PR tree-optimization/82929
[official-gcc.git] / gcc / config / arc / arc.md
blobc766306075c307048f92468ef55a81c7a47990cc
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 (define_delay (eq_attr "type" "loop_end")
558   [(eq_attr "in_delay_slot" "true")
559    (eq_attr "in_delay_slot" "true")
560    (nil)])
562 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
563 ;; non-taken case, so the only meaningful way to have an annull-true
564 ;; filled delay slot is to conditionalize the delay slot insn.
565 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
566                    (eq_attr "type" "branch,uncond_branch,jump")
567                    (match_test "!optimize_size"))
568   [(eq_attr "in_delay_slot" "true")
569    (eq_attr "cond_delay_insn" "yes")
570    (eq_attr "cond_delay_insn" "yes")])
572 ;; For ARC700, anything goes for annulled-true insns, since there is no
573 ;; penalty for the unexposed delay slot when the branch is not taken,
574 ;; however, we must avoid things that have a delay slot themselvese to
575 ;; avoid confusing gcc.
576 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
577                    (eq_attr "type" "branch,uncond_branch,jump")
578                    (match_test "!optimize_size"))
579   [(eq_attr "in_delay_slot" "true")
580    (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
581    (eq_attr "cond_delay_insn" "yes")])
583 ;; -mlongcall -fpic sfuncs use r12 to load the function address
584 (define_delay (eq_attr "type" "sfunc")
585   [(eq_attr "in_sfunc_delay_slot" "true")
586    (eq_attr "in_sfunc_delay_slot" "true")
587    (nil)])
588 ;; ??? need to use a working strategy for canuse_limm:
589 ;; - either canuse_limm is not eligible for delay slots, and has no
590 ;;   delay slots, or arc_reorg has to treat them as nocond, or it has to
591 ;;   somehow modify them to become inelegible for delay slots if a decision
592 ;;   is made that makes conditional execution required.
594 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
595   (const
596    (cond [(symbol_ref "arc_tune == TUNE_ARC600")
597           (const_string "arc600")
598           (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
599           (const_string "arc700_4_2_std")
600           (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
601           (const_string "arc700_4_2_xmac")]
602          (const_string "none"))))
604 (define_attr "tune_arc700" "false,true"
605   (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
606                 (const_string "true")
607                 (const_string "false")))
609 ;; Move instructions.
610 (define_expand "movqi"
611   [(set (match_operand:QI 0 "move_dest_operand" "")
612         (match_operand:QI 1 "general_operand" ""))]
613   ""
614   "if (prepare_move_operands (operands, QImode)) DONE;")
616 ; In order to allow the ccfsm machinery to do its work, the leading compact
617 ; alternatives say 'canuse' - there is another alternative that will match
618 ; when the condition codes are used.
619 ; Rcq won't match if the condition is actually used; to avoid a spurious match
620 ; via q, q is inactivated as constraint there.
621 ; Likewise, the length of an alternative that might be shifted to conditional
622 ; execution must reflect this, lest out-of-range branches are created.
623 ; The iscompact attribute allows the epilogue expander to know for which
624 ; insns it should lengthen the return insn.
625 (define_insn "*movqi_insn"
626   [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h,w*l,w*l,???w,h,w*l,Rcq,  S,!*x,  r,r, Ucm,m,???m,  m,Usc")
627         (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,i"))]
628   "register_operand (operands[0], QImode)
629    || register_operand (operands[1], QImode)"
630   "@
631    mov%? %0,%1%&
632    mov%? %0,%1%&
633    mov%? %0,%1%&
634    mov%? %0,%1%&
635    mov%? %0,%1%&
636    mov%? %0,%1
637    mov%? %0,%1
638    mov%? %0,%1
639    mov%? %0,%1
640    mov%? %0,%S1
641    ldb%? %0,%1%&
642    stb%? %1,%0%&
643    ldb%? %0,%1%&
644    xldb%U1 %0,%1
645    ldb%U1%V1 %0,%1
646    xstb%U0 %1,%0
647    stb%U0%V0 %1,%0
648    stb%U0%V0 %1,%0
649    stb%U0%V0 %1,%0
650    stb%U0%V0 %1,%0"
651   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
652    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
653    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
654    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
656 (define_expand "movhi"
657   [(set (match_operand:HI 0 "move_dest_operand" "")
658         (match_operand:HI 1 "general_operand" ""))]
659   ""
660   "if (prepare_move_operands (operands, HImode)) DONE;")
662 (define_insn "*movhi_insn"
663   [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h,w*l,w*l,???w,Rcq#q,h,w*l,Rcq,  S,  r,r, Ucm,m,???m,  m,VUsc")
664         (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"))]
665   "register_operand (operands[0], HImode)
666    || register_operand (operands[1], HImode)
667    || (CONSTANT_P (operands[1])
668        /* Don't use a LIMM that we could load with a single insn - we loose
669           delay-slot filling opportunities.  */
670        && !satisfies_constraint_I (operands[1])
671        && satisfies_constraint_Usc (operands[0]))"
672   "@
673    mov%? %0,%1%&
674    mov%? %0,%1%&
675    mov%? %0,%1%&
676    mov%? %0,%1%&
677    mov%? %0,%1%&
678    mov%? %0,%1
679    mov%? %0,%1
680    mov%? %0,%1
681    mov%? %0,%S1%&
682    mov%? %0,%S1
683    mov%? %0,%S1
684    ld%_%? %0,%1%&
685    st%_%? %1,%0%&
686    xld%_%U1 %0,%1
687    ld%_%U1%V1 %0,%1
688    xst%_%U0 %1,%0
689    st%_%U0%V0 %1,%0
690    st%_%U0%V0 %1,%0
691    st%_%U0%V0 %S1,%0
692    st%_%U0%V0 %S1,%0"
693   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
694    (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")
695    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
696    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
698 (define_expand "movsi"
699   [(set (match_operand:SI 0 "move_dest_operand" "")
700         (match_operand:SI 1 "general_operand" ""))]
701   ""
702   "if (prepare_move_operands (operands, SImode)) DONE;")
704 ; In order to allow the ccfsm machinery to do its work, the leading compact
705 ; alternatives say 'canuse' - there is another alternative that will match
706 ; when the condition codes are used.
707 ; Rcq won't match if the condition is actually used; to avoid a spurious match
708 ; via q, q is inactivated as constraint there.
709 ; Likewise, the length of an alternative that might be shifted to conditional
710 ; execution must reflect this, lest out-of-range branches are created.
711 ; the iscompact attribute allows the epilogue expander to know for which
712 ; insns it should lengthen the return insn.
713 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
714 (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
715   [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h,w*l,w*l,  w,  w,  w,  w,  ???w, ?w,  w,Rcq#q,  h, w*l,Rcq,  S,   Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,  m,VUsc")
716         (match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1, cL,  I,Crr,Clo,Chi,Cbi,?Rac*l,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac,Cm3, C32"))]
717   "register_operand (operands[0], SImode)
718    || register_operand (operands[1], SImode)
719    || (CONSTANT_P (operands[1])
720        /* Don't use a LIMM that we could load with a single insn - we loose
721           delay-slot filling opportunities.  */
722        && !satisfies_constraint_I (operands[1])
723        && satisfies_constraint_Usc (operands[0]))"
724   "@
725    mov%? %0,%1%&        ;0
726    mov%? %0,%1%&        ;1
727    mov%? %0,%1%&        ;2
728    mov%? %0,%1%&        ;3
729    mov%? %0,%1%&        ;4
730    mov%? %0,%1          ;5
731    mov%? %0,%1          ;6
732    ror %0,((%1*2+1) & 0x3f) ;7
733    movl.cl %0,%1        ;8
734    movh.cl %0,%L1>>16   ;9
735    * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
736    mov%? %0,%1          ;11
737    add %0,%S1           ;12
738    add %0,pcl,%1@pcl    ;13
739    mov%? %0,%1          ;14
740    mov%? %0,%1          ;15
741    mov%? %0,%1          ;16
742    ld%?%U1 %0,%1        ;17
743    st%? %1,%0%&         ;18
744    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
745    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
746    ld%? %0,%1%&         ;21
747    xld%U1 %0,%1         ;22
748    ld%? %0,%1%&         ;23
749    ld%? %0,%1%&         ;24
750    ld%U1%V1 %0,%1       ;25
751    xst%U0 %1,%0         ;26
752    st%? %1,%0%&         ;27
753    st%U0%V0 %1,%0       ;28
754    st%U0%V0 %1,%0       ;29
755    st%U0%V0 %1,%0       ;30
756    st%U0%V0 %1,%0       ;31"
757    ;                         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
758   [(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")
759    (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")
760    ; Use default length for iscompact to allow for COND_EXEC.  But set length
761    ; of Crr to 4.
762    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8")
763    (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")
764    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
766 ;; Sometimes generated by the epilogue code.  We don't want to
767 ;; recognize these addresses in general, because the limm is costly,
768 ;; and we can't use them for stores.  */
769 (define_insn "*movsi_pre_mod"
770   [(set (match_operand:SI 0 "register_operand" "=w")
771         (mem:SI (pre_modify
772                   (reg:SI SP_REG)
773                   (plus:SI (reg:SI SP_REG)
774                            (match_operand 1 "immediate_operand" "Cal")))))]
775   "reload_completed"
776   "ld.a %0,[sp,%1]"
777   [(set_attr "type" "load")
778    (set_attr "length" "8")])
780 ;; Store a value to directly to memory.  The location might also be cached.
781 ;; Since the cached copy can cause a write-back at unpredictable times,
782 ;; we first write cached, then we write uncached.
783 (define_insn "store_direct"
784   [(set (match_operand:SI 0 "move_dest_operand" "=m")
785       (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
786        UNSPEC_ARC_DIRECT))]
787   ""
788   "st%U0 %1,%0\;st%U0.di %1,%0"
789   [(set_attr "type" "store")])
791 (define_insn_and_split "*movsi_set_cc_insn"
792   [(set (match_operand:CC_ZN 2 "cc_set_register" "")
793         (match_operator:CC_ZN 3 "zn_compare_operator"
794           [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
795    (set (match_operand:SI 0 "register_operand" "=w,w,w")
796         (match_dup 1))]
797   ""
798   "mov%?.f %0,%S1"
799   ; splitting to 'tst' allows short insns and combination into brcc.
800   "reload_completed && operands_match_p (operands[0], operands[1])"
801   [(set (match_dup 2) (match_dup 3))]
802   ""
803   [(set_attr "type" "compare")
804    (set_attr "predicable" "no,yes,yes")
805    (set_attr "cond" "set_zn")
806    (set_attr "length" "4,4,8")])
808 (define_insn "unary_comparison"
809   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
810         (match_operator:CC_ZN 3 "zn_compare_operator"
811           [(match_operator:SI 2 "unary_operator"
812              [(match_operand:SI 1 "register_operand" "c")])
813            (const_int 0)]))]
814   ""
815   "%O2.f 0,%1"
816   [(set_attr "type" "compare")
817    (set_attr "cond" "set_zn")])
820 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
821 (define_insn "*unary_comparison_result_used"
822   [(set (match_operand 2 "cc_register" "")
823         (match_operator 4 "zn_compare_operator"
824           [(match_operator:SI 3 "unary_operator"
825              [(match_operand:SI 1 "register_operand" "c")])
826                (const_int 0)]))
827    (set (match_operand:SI 0 "register_operand" "=w")
828         (match_dup 3))]
829   ""
830   "%O3.f %0,%1"
831   [(set_attr "type" "compare")
832    (set_attr "cond" "set_zn")
833    (set_attr "length" "4")])
835 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
836 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
837 ; even if we don't need the clobber.
838 (define_insn_and_split "*tst_movb"
839   [(set
840      (match_operand 0 "cc_register" "")
841      (match_operator 4 "zn_compare_operator"
842        [(and:SI
843           (match_operand:SI 1 "register_operand"  "%Rcq,Rcq, c,  c,  c,  c,Rrq,  3,  c")
844           (match_operand:SI 2 "nonmemory_operand"  "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
845         (const_int 0)]))
846    (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
847   "TARGET_NPS_BITOPS"
848   "movb.f.cl %3,%1,%p2,%p2,%s2"
849   "TARGET_NPS_BITOPS && reload_completed
850    && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
851   [(set (match_dup 0) (match_dup 4))])
853 (define_insn "*tst"
854   [(set
855      (match_operand 0 "cc_register" "")
856      (match_operator 3 "zn_compare_operator"
857        [(and:SI
858           (match_operand:SI 1 "register_operand"
859            "%Rcq,Rcq, c, c, c,  c,  c,  c")
860           (match_operand:SI 2 "nonmemory_operand"
861            " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
862         (const_int 0)]))]
863   "reload_completed
864    || !satisfies_constraint_Cbf (operands[2])
865    || satisfies_constraint_C0p (operands[2])
866    || satisfies_constraint_I (operands[2])
867    || satisfies_constraint_C1p (operands[2])
868    || satisfies_constraint_Chs (operands[2])"
869   "*
870     switch (which_alternative)
871     {
872     case 0: case 2: case 3: case 7:
873       return \"tst%? %1,%2\";
874     case 1:
875       return \"btst%? %1,%z2\";
876     case 4:
877       return \"bmsk%?.f 0,%1,%Z2%&\";
878     case 5:
879       return \"bclr%?.f 0,%1,%M2%&\";
880     case 6:
881       return \"asr.f 0,%1,%p2\";
882     default:
883       gcc_unreachable ();
884     }
885   "
886   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
887    (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
888    (set_attr "length" "*,*,4,4,4,4,4,8")
889    (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
890    (set_attr "cond" "set_zn")])
892 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
893 ; combine will do that and not try the AND.
895 ; It would take 66 constraint combinations to describe the zero_extract
896 ; constants that are covered by the 12-bit signed constant for tst
897 ; (excluding the ones that are better done by mov or btst).
898 ; so we rather use an extra pattern for tst;
899 ; since this is about constants, reload shouldn't care.
900 (define_insn "*tst_bitfield_tst"
901   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
902         (match_operator 4 "zn_compare_operator"
903           [(zero_extract:SI
904              (match_operand:SI 1 "register_operand"  "c")
905              (match_operand:SI 2 "const_int_operand" "n")
906              (match_operand:SI 3 "const_int_operand" "n"))
907            (const_int 0)]))]
908   "INTVAL (operands[2]) > 1
909    && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
910        || (INTVAL (operands[3]) <= 11
911            && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
912   "tst %1,((1<<%2)-1)<<%3"
913   [(set_attr "type" "compare")
914    (set_attr "cond" "set_zn")
915    (set_attr "length" "4")])
917 ; Likewise for asr.f.
918 (define_insn "*tst_bitfield_asr"
919   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
920         (match_operator 4 "zn_compare_operator"
921           [(zero_extract:SI
922              (match_operand:SI 1 "register_operand"  "c")
923              (match_operand:SI 2 "const_int_operand" "n")
924              (match_operand:SI 3 "const_int_operand" "n"))
925            (const_int 0)]))]
926   "INTVAL (operands[2]) > 1
927    && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
928   "asr.f 0,%1,%3"
929   [(set_attr "type" "shift")
930    (set_attr "cond" "set_zn")
931    (set_attr "length" "4")])
933 (define_insn "*tst_bitfield"
934   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
935         (match_operator 5 "zn_compare_operator"
936           [(zero_extract:SI
937              (match_operand:SI 1 "register_operand" "%Rcqq,c,  c,Rrq,c")
938              (match_operand:SI 2 "const_int_operand"    "N,N,  n,Cbn,n")
939              (match_operand:SI 3 "const_int_operand"    "n,n,C_0,Cbn,n"))
940            (const_int 0)]))
941    (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
942   ""
943   "@
944    btst%? %1,%3
945    btst %1,%3
946    bmsk.f 0,%1,%2-1
947    movb.f.cl %4,%1,%3,%3,%2
948    and.f 0,%1,((1<<%2)-1)<<%3"
949   [(set_attr "iscompact" "maybe,false,false,false,false")
950    (set_attr "type" "compare,compare,compare,shift,compare")
951    (set_attr "cond" "set_zn")
952    (set_attr "length" "*,4,4,4,8")])
954 (define_insn "*commutative_binary_comparison"
955   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
956         (match_operator:CC_ZN 5 "zn_compare_operator"
957           [(match_operator:SI 4 "commutative_operator"
958              [(match_operand:SI 1 "register_operand" "%c,c")
959               (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
960            (const_int 0)]))
961    (clobber (match_scratch:SI 3 "=X,X"))]
962   ""
963   "%O4.f 0,%1,%2"
964   [(set_attr "type" "compare")
965    (set_attr "cond" "set_zn")
966    (set_attr "length" "4,8")])
968 ; for flag setting 'add' instructions like if (a+b) { ...}
969 ; the combiner needs this pattern
970 (define_insn "*addsi_compare"
971   [(set (reg:CC_ZN CC_REG)
972         (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
973                        (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
974   ""
975   "add.f 0,%0,%1"
976   [(set_attr "cond" "set")
977    (set_attr "type" "compare")
978    (set_attr "length" "4")])
980 ; for flag setting 'add' instructions like if (a+b < a) { ...}
981 ; the combiner needs this pattern
982 (define_insn "addsi_compare_2"
983   [(set (reg:CC_C CC_REG)
984         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
985                                (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
986                       (match_dup 0)))]
987   ""
988   "add.f 0,%0,%1"
989   [(set_attr "cond" "set")
990    (set_attr "type" "compare")
991    (set_attr "length" "4,8")])
993 (define_insn "*addsi_compare_3"
994   [(set (reg:CC_C CC_REG)
995         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
996                                (match_operand:SI 1 "register_operand" "c"))
997                       (match_dup 1)))]
998   ""
999   "add.f 0,%0,%1"
1000   [(set_attr "cond" "set")
1001    (set_attr "type" "compare")
1002    (set_attr "length" "4")])
1004 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
1005 (define_insn "*commutative_binary_comparison_result_used"
1006   [(set (match_operand 3 "cc_register" "")
1007         (match_operator 5 "zn_compare_operator"
1008           ; We can accept any commutative operator except mult because
1009           ; our 'w' class below could try to use LP_COUNT.
1010           [(match_operator:SI 4 "commutative_operator_sans_mult"
1011              [(match_operand:SI 1 "register_operand" "c,0,c")
1012               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1013            (const_int 0)]))
1014    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1015         (match_dup 4))]
1016   ""
1017   "%O4.f %0,%1,%2 ; non-mult commutative"
1018   [(set_attr "type" "compare,compare,compare")
1019    (set_attr "cond" "set_zn,set_zn,set_zn")
1020    (set_attr "length" "4,4,8")])
1022 ; a MULT-specific version of this pattern to avoid touching the
1023 ; LP_COUNT register
1024 (define_insn "*commutative_binary_mult_comparison_result_used"
1025   [(set (match_operand 3 "cc_register" "")
1026         (match_operator 5 "zn_compare_operator"
1027           [(match_operator:SI 4 "mult_operator"
1028              [(match_operand:SI 1 "register_operand" "c,0,c")
1029               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1030            (const_int 0)]))
1031         ; Make sure to use the W class to not touch LP_COUNT.
1032    (set (match_operand:SI 0 "register_operand" "=W,W,W")
1033         (match_dup 4))]
1034   "!TARGET_ARC600_FAMILY"
1035   "%O4.f %0,%1,%2 ; mult commutative"
1036   [(set_attr "type" "compare,compare,compare")
1037    (set_attr "cond" "set_zn,set_zn,set_zn")
1038    (set_attr "length" "4,4,8")])
1040 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
1041 (define_insn "*noncommutative_binary_comparison_result_used"
1042   [(set (match_operand 3 "cc_register" "")
1043         (match_operator 5 "zn_compare_operator"
1044           [(match_operator:SI 4 "noncommutative_operator"
1045              [(match_operand:SI 1 "register_operand" "c,0,c")
1046               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1047                (const_int 0)]))
1048    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1049         (match_dup 4 ))]
1050   "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1051   "%O4.f %0,%1,%2"
1052   [(set_attr "type" "compare,compare,compare")
1053    (set_attr "cond" "set_zn,set_zn,set_zn")
1054    (set_attr "length" "4,4,8")])
1056 (define_insn "*noncommutative_binary_comparison"
1057   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1058         (match_operator:CC_ZN 5 "zn_compare_operator"
1059           [(match_operator:SI 4 "noncommutative_operator"
1060              [(match_operand:SI 1 "register_operand" "c,c")
1061               (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
1062            (const_int 0)]))
1063    (clobber (match_scratch:SI 3 "=X,X"))]
1064   "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1065   "%O4.f 0,%1,%2"
1066   [(set_attr "type" "compare")
1067    (set_attr "cond" "set_zn")
1068    (set_attr "length" "4,8")])
1070 (define_expand "bic_f_zn"
1071   [(parallel
1072      [(set (reg:CC_ZN CC_REG)
1073            (compare:CC_ZN
1074              (and:SI (match_operand:SI 1 "register_operand" "")
1075                      (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1076            (const_int 0)))
1077       (set (match_operand:SI 0 "register_operand" "")
1078            (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1079   "")
1081 (define_insn "*bic_f"
1082   [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
1083         (match_operator 4 "zn_compare_operator"
1084           [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1085                    (not:SI
1086                      (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1087            (const_int 0)]))
1088    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1089         (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1090   ""
1091   "bic.f %0,%1,%2"
1092   [(set_attr "type" "compare,compare,compare")
1093    (set_attr "cond" "set_zn,set_zn,set_zn")
1094    (set_attr "length" "4,4,8")])
1096 (define_expand "movdi"
1097   [(set (match_operand:DI 0 "move_dest_operand" "")
1098         (match_operand:DI 1 "general_operand" ""))]
1099   ""
1100   "
1101   if (prepare_move_operands (operands, DImode))
1102     DONE;
1103   ")
1105 (define_insn_and_split "*movdi_insn"
1106   [(set (match_operand:DI 0 "move_dest_operand"      "=w, w,r,m")
1107         (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
1108   "register_operand (operands[0], DImode)
1109    || register_operand (operands[1], DImode)"
1110   "*
1112   switch (which_alternative)
1113     {
1114     default:
1115       return \"#\";
1117     case 2:
1118     if (TARGET_LL64
1119         && ((even_register_operand (operands[0], DImode)
1120              && memory_operand (operands[1], DImode))
1121             || (memory_operand (operands[0], DImode)
1122                 && even_register_operand (operands[1], DImode))))
1123       return \"ldd%U1%V1 %0,%1%&\";
1124     return \"#\";
1126     case 3:
1127     if (TARGET_LL64
1128         && ((even_register_operand (operands[0], DImode)
1129              && memory_operand (operands[1], DImode))
1130             || (memory_operand (operands[0], DImode)
1131                 && even_register_operand (operands[1], DImode))))
1132      return \"std%U0%V0 %1,%0\";
1133     return \"#\";
1134     }
1136   "reload_completed"
1137   [(const_int 0)]
1138   {
1139    arc_split_move (operands);
1140    DONE;
1141   }
1142   [(set_attr "type" "move,move,load,store")
1143    ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1144    (set_attr "length" "8,16,*,*")])
1147 ;; Floating point move insns.
1149 (define_expand "movsf"
1150   [(set (match_operand:SF 0 "move_dest_operand" "")
1151         (match_operand:SF 1 "general_operand" ""))]
1152   ""
1153   "if (prepare_move_operands (operands, SFmode)) DONE;")
1155 (define_insn "*movsf_insn"
1156   [(set (match_operand:SF 0 "move_dest_operand"    "=h,w,w,r,m")
1157         (match_operand:SF 1 "move_src_operand"   "hCm1,c,E,m,c"))]
1158   "register_operand (operands[0], SFmode)
1159    || register_operand (operands[1], SFmode)"
1160   "@
1161    mov%? %0,%1
1162    mov%? %0,%1
1163    mov%? %0,%1 ; %A1
1164    ld%U1%V1 %0,%1
1165    st%U0%V0 %1,%0"
1166   [(set_attr "type" "move,move,move,load,store")
1167    (set_attr "predicable" "no,yes,yes,no,no")
1168    (set_attr "iscompact" "true,false,false,false,false")])
1170 (define_expand "movdf"
1171   [(set (match_operand:DF 0 "move_dest_operand" "")
1172         (match_operand:DF 1 "general_operand" ""))]
1173   ""
1174   "if (prepare_move_operands (operands, DFmode)) DONE;")
1176 (define_insn_and_split "*movdf_insn"
1177   [(set (match_operand:DF 0 "move_dest_operand"      "=D,r,c,c,r,m")
1178         (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1179   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1180   "*
1182  switch (which_alternative)
1183    {
1184     default:
1185       return \"#\";
1186     case 4:
1187     if (TARGET_LL64
1188         && ((even_register_operand (operands[0], DFmode)
1189              && memory_operand (operands[1], DFmode))
1190             || (memory_operand (operands[0], DFmode)
1191                 && even_register_operand (operands[1], DFmode))))
1192       return \"ldd%U1%V1 %0,%1%&\";
1193     return \"#\";
1195     case 5:
1196     if (TARGET_LL64
1197         && ((even_register_operand (operands[0], DFmode)
1198              && memory_operand (operands[1], DFmode))
1199             || (memory_operand (operands[0], DFmode)
1200                 && even_register_operand (operands[1], DFmode))))
1201      return \"std%U0%V0 %1,%0\";
1202     return \"#\";
1203    }
1205   "reload_completed"
1206   [(const_int 0)]
1207   {
1208    arc_split_move (operands);
1209    DONE;
1210   }
1211   [(set_attr "type" "move,move,move,move,load,store")
1212    (set_attr "predicable" "no,no,yes,yes,no,no")
1213    ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1214    (set_attr "length" "4,16,8,16,16,16")])
1216 (define_insn_and_split "*movdf_insn_nolrsr"
1217   [(set (match_operand:DF 0 "register_operand"       "=r")
1218         (match_operand:DF 1 "arc_double_register_operand" "D"))
1219    (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1220    ]
1221   "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1222   "#"
1223   "&& 1"
1224   [
1225     ; mov r0, 0
1226     (set (match_dup 0) (match_dup 3))
1228     ; daddh?? r1, r0, r0
1229     (parallel [
1230         (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1231         (use (const_int 1))
1232         (use (const_int 1))
1233         (use (match_dup 0)) ; used to block can_combine_p
1234         (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1235     ])
1237     ; We have to do this twice, once to read the value into R0 and
1238     ; second time to put back the contents which the first DEXCLx
1239     ; will have overwritten
1240     ; dexcl2 r0, r1, r0
1241     (parallel [
1242                (set (match_dup 4) ; aka r0result
1243                                   ; aka DF, r1, r0
1244                     (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1245                                         VUNSPEC_ARC_DEXCL))
1246                (clobber (match_dup 1))
1247                ])
1248     ; Generate the second, which makes sure operand5 and operand4 values
1249     ; are put back in the Dx register properly.
1250     (set (match_dup 1) (unspec_volatile:DF
1251                         [(match_dup 5) (match_dup 4)]
1252                         VUNSPEC_ARC_DEXCL_NORES))
1254     ; Note: we cannot use a (clobber (match_scratch)) here because
1255     ; the combine pass will end up replacing uses of it with 0
1256   ]
1257   "operands[3] = CONST0_RTX (DFmode);
1258    operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1259    operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1260   [(set_attr "type" "move")])
1262 ;; Load/Store with update instructions.
1264 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1265 ;; hardware can also do cases where the increment is not the size of the
1266 ;; object.
1268 ;; In all these cases, we use operands 0 and 1 for the register being
1269 ;; incremented because those are the operands that local-alloc will
1270 ;; tie and these are the pair most likely to be tieable (and the ones
1271 ;; that will benefit the most).
1273 ;; We use match_operator here because we need to know whether the memory
1274 ;; object is volatile or not.
1277 ;; Note: loadqi_update has no 16-bit variant
1278 (define_insn "*loadqi_update"
1279   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1280         (match_operator:QI 4 "any_mem_operand"
1281          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1282                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1283    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1284         (plus:SI (match_dup 1) (match_dup 2)))]
1285   ""
1286   "ldb.a%V4 %3,[%0,%S2]"
1287   [(set_attr "type" "load,load")
1288    (set_attr "length" "4,8")])
1290 (define_insn "*load_zeroextendqisi_update"
1291   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1292         (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1293                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1294                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1295    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1296         (plus:SI (match_dup 1) (match_dup 2)))]
1297   ""
1298   "ldb.a%V4 %3,[%0,%S2]"
1299   [(set_attr "type" "load,load")
1300    (set_attr "length" "4,8")])
1302 (define_insn "*load_signextendqisi_update"
1303   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1304         (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1305                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1306                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1307    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1308         (plus:SI (match_dup 1) (match_dup 2)))]
1309   ""
1310   "ldb.x.a%V4 %3,[%0,%S2]"
1311   [(set_attr "type" "load,load")
1312    (set_attr "length" "4,8")])
1314 (define_insn "*storeqi_update"
1315   [(set (match_operator:QI 4 "any_mem_operand"
1316          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1317                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1318         (match_operand:QI 3 "register_operand" "c"))
1319    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1320         (plus:SI (match_dup 1) (match_dup 2)))]
1321   ""
1322   "stb.a%V4 %3,[%0,%2]"
1323   [(set_attr "type" "store")
1324    (set_attr "length" "4")])
1326 ;; ??? pattern may have to be re-written
1327 ;; Note: no 16-bit variant for this pattern
1328 (define_insn "*loadhi_update"
1329   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1330         (match_operator:HI 4 "any_mem_operand"
1331          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1332                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1333    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1334         (plus:SI (match_dup 1) (match_dup 2)))]
1335   ""
1336   "ld%_.a%V4 %3,[%0,%S2]"
1337   [(set_attr "type" "load,load")
1338    (set_attr "length" "4,8")])
1340 (define_insn "*load_zeroextendhisi_update"
1341   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1342         (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1343                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1344                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1345    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1346         (plus:SI (match_dup 1) (match_dup 2)))]
1347   ""
1348   "ld%_.a%V4 %3,[%0,%S2]"
1349   [(set_attr "type" "load,load")
1350    (set_attr "length" "4,8")])
1352 ;; Note: no 16-bit variant for this instruction
1353 (define_insn "*load_signextendhisi_update"
1354   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1355         (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1356                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1357                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1358    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1359         (plus:SI (match_dup 1) (match_dup 2)))]
1360   ""
1361   "ld%_.x.a%V4 %3,[%0,%S2]"
1362   [(set_attr "type" "load,load")
1363    (set_attr "length" "4,8")])
1365 (define_insn "*storehi_update"
1366   [(set (match_operator:HI 4 "any_mem_operand"
1367          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1368                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1369         (match_operand:HI 3 "register_operand" "c"))
1370    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1371         (plus:SI (match_dup 1) (match_dup 2)))]
1372   ""
1373   "st%_.a%V4 %3,[%0,%2]"
1374   [(set_attr "type" "store")
1375    (set_attr "length" "4")])
1377 ;; No 16-bit variant for this instruction pattern
1378 (define_insn "*loadsi_update"
1379   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1380         (match_operator:SI 4 "any_mem_operand"
1381          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1382                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1383    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1384         (plus:SI (match_dup 1) (match_dup 2)))]
1385   ""
1386   "ld.a%V4 %3,[%0,%S2]"
1387   [(set_attr "type" "load,load")
1388    (set_attr "length" "4,8")])
1390 (define_insn "*storesi_update"
1391   [(set (match_operator:SI 4 "any_mem_operand"
1392          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1393                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1394         (match_operand:SI 3 "register_operand" "c"))
1395    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1396         (plus:SI (match_dup 1) (match_dup 2)))]
1397   ""
1398   "st.a%V4 %3,[%0,%2]"
1399   [(set_attr "type" "store")
1400    (set_attr "length" "4")])
1402 (define_insn "*loadsf_update"
1403   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1404         (match_operator:SF 4 "any_mem_operand"
1405          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1406                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1407    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1408         (plus:SI (match_dup 1) (match_dup 2)))]
1409   ""
1410   "ld.a%V4 %3,[%0,%S2]"
1411   [(set_attr "type" "load,load")
1412    (set_attr "length" "4,8")])
1414 (define_insn "*storesf_update"
1415   [(set (match_operator:SF 4 "any_mem_operand"
1416          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1417                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1418         (match_operand:SF 3 "register_operand" "c"))
1419    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1420         (plus:SI (match_dup 1) (match_dup 2)))]
1421   ""
1422   "st.a%V4 %3,[%0,%2]"
1423   [(set_attr "type" "store")
1424    (set_attr "length" "4")])
1426 ;; Conditional move instructions.
1428 (define_expand "movsicc"
1429   [(set (match_operand:SI 0 "dest_reg_operand" "")
1430         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1431                          (match_operand:SI 2 "nonmemory_operand" "")
1432                          (match_operand:SI 3 "register_operand" "")))]
1433   ""
1434   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1437 (define_expand "movdicc"
1438   [(set (match_operand:DI 0 "dest_reg_operand" "")
1439         (if_then_else:DI(match_operand 1 "comparison_operator" "")
1440                         (match_operand:DI 2 "nonmemory_operand" "")
1441                         (match_operand:DI 3 "register_operand" "")))]
1442   ""
1443   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1446 (define_expand "movsfcc"
1447   [(set (match_operand:SF 0 "dest_reg_operand" "")
1448         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1449                       (match_operand:SF 2 "nonmemory_operand" "")
1450                       (match_operand:SF 3 "register_operand" "")))]
1451   ""
1452   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1454 (define_expand "movdfcc"
1455   [(set (match_operand:DF 0 "dest_reg_operand" "")
1456         (if_then_else:DF (match_operand 1 "comparison_operator" "")
1457                       (match_operand:DF 2 "nonmemory_operand" "")
1458                       (match_operand:DF 3 "register_operand" "")))]
1459   ""
1460   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1462 (define_insn "*movsicc_insn"
1463   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1464         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1465                        [(match_operand 4 "cc_register" "") (const_int 0)])
1466                       (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1467                       (match_operand:SI 2 "register_operand" "0,0")))]
1468   ""
1470   if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1471       && satisfies_constraint_Rcq (operands[0]))
1472     return "sub%?.ne %0,%0,%0";
1473   /* ??? might be good for speed on ARC600 too, *if* properly scheduled.  */
1474   if ((optimize_size && (!TARGET_ARC600_FAMILY))
1475       && rtx_equal_p (operands[1], constm1_rtx)
1476       && GET_CODE (operands[3]) == LTU)
1477     return "sbc.cs %0,%0,%0";
1478   return "mov.%d3 %0,%S1";
1480   [(set_attr "type" "cmove,cmove")
1481    (set_attr "length" "4,8")])
1483 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1484 ;; if the single bit is the sign bit, then GCC likes to convert this
1485 ;; into a sign extend and a compare less than, or greater to zero.
1486 ;; This is usually fine, except for the NXP400 where we have access to
1487 ;; a bit test instruction, along with a special short load instruction
1488 ;; (from CMEM), that doesn't support sign-extension on load.
1490 ;; This peephole optimisation attempts to restore the use of bit-test
1491 ;; in those cases where it is useful to do so.
1492 (define_peephole2
1493   [(set (match_operand:SI 0 "register_operand" "")
1494                 (sign_extend:SI
1495                 (match_operand:QI 1 "any_mem_operand" "")))
1496    (set (reg:CC_ZN CC_REG)
1497         (compare:CC_ZN (match_dup 0)
1498                        (const_int 0)))
1499    (set (pc)
1500         (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1501                        [(reg:CC_ZN CC_REG) (const_int 0)])
1502                       (match_operand 3 "" "")
1503                       (match_operand 4 "" "")))]
1504   "TARGET_NPS_CMEM
1505    && cmem_address (XEXP (operands[1], 0), SImode)
1506    && peep2_reg_dead_p (2, operands[0])
1507    && peep2_regno_dead_p (3, CC_REG)"
1508   [(set (match_dup 0)
1509         (zero_extend:SI
1510         (match_dup 1)))
1511    (set (reg:CC_ZN CC_REG)
1512         (compare:CC_ZN (zero_extract:SI
1513                          (match_dup 0)
1514                          (const_int 1)
1515                          (const_int 7))
1516                        (const_int 0)))
1517    (set (pc)
1518         (if_then_else (match_dup 2)
1519                       (match_dup 3)
1520                       (match_dup 4)))]
1521   "if (GET_CODE (operands[2]) == GE)
1522      operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1523    else
1524      operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1526 ; Try to generate more short moves, and/or less limms, by substituting a
1527 ; conditional move with a conditional sub.
1528 (define_peephole2
1529   [(set (match_operand:SI 0 "compact_register_operand")
1530         (match_operand:SI 1 "const_int_operand"))
1531    (set (match_dup 0)
1532         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1533                            [(match_operand 4 "cc_register" "") (const_int 0)])
1534                             (match_operand:SI 2 "const_int_operand" "")
1535                       (match_dup 0)))]
1536   "!satisfies_constraint_P (operands[1])
1537    && satisfies_constraint_P (operands[2])
1538    && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1539   [(set (match_dup 0) (match_dup 2))
1540    (cond_exec
1541      (match_dup 3)
1542      (set (match_dup 0)
1543           (plus:SI (match_dup 0) (match_dup 1))))]
1544   "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1545                                                     GET_MODE (operands[4])),
1546                                  VOIDmode, operands[4], const0_rtx);
1547    operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1549 (define_insn "*movdicc_insn"
1550   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1551         (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1552                         [(match_operand 4 "cc_register" "") (const_int 0)])
1553                       (match_operand:DI 1 "nonmemory_operand" "c,i")
1554                       (match_operand:DI 2 "register_operand" "0,0")))]
1555    ""
1556    "*
1558    switch (which_alternative)
1559      {
1560      default:
1561      case 0 :
1562        /* We normally copy the low-numbered register first.  However, if
1563          the first register operand 0 is the same as the second register of
1564          operand 1, we must copy in the opposite order.  */
1565        if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1566         return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1567        else
1568         return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1569      case 1 :
1570         return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1573      }
1575   [(set_attr "type" "cmove,cmove")
1576    (set_attr "length" "8,16")])
1579 (define_insn "*movsfcc_insn"
1580   [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1581         (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1582                        [(match_operand 4 "cc_register" "") (const_int 0)])
1583                       (match_operand:SF 1 "nonmemory_operand" "c,E")
1584                       (match_operand:SF 2 "register_operand" "0,0")))]
1585   ""
1586   "@
1587    mov.%d3 %0,%1
1588    mov.%d3 %0,%1 ; %A1"
1589   [(set_attr "type" "cmove,cmove")])
1591 (define_insn "*movdfcc_insn"
1592   [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1593         (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1594                  [(match_operand 4 "cc_register" "") (const_int 0)])
1595                       (match_operand:DF 2 "nonmemory_operand" "c,E")
1596                       (match_operand:DF 3 "register_operand" "0,0")))]
1597   ""
1598   "*
1600   switch (which_alternative)
1601     {
1602     default:
1603     case 0 :
1604       /* We normally copy the low-numbered register first.  However, if
1605          the first register operand 0 is the same as the second register of
1606          operand 1, we must copy in the opposite order.  */
1607       if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1608         return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1609       else
1610         return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1611     case 1 :
1612               return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1614     }
1616   [(set_attr "type" "cmove,cmove")
1617    (set_attr "length" "8,16")])
1620 (define_insn "*zero_extendqihi2_i"
1621   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
1622         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
1623   ""
1624   "@
1625    extb%? %0,%1%&
1626    extb%? %0,%1%&
1627    bmsk%? %0,%1,7
1628    extb %0,%1
1629    xldb%U1 %0,%1
1630    ldb%U1 %0,%1"
1631   [(set_attr "type" "unary,unary,unary,unary,load,load")
1632    (set_attr "iscompact" "maybe,true,false,false,false,false")
1633    (set_attr "predicable" "no,no,yes,no,no,no")])
1635 (define_expand "zero_extendqihi2"
1636   [(set (match_operand:HI 0 "dest_reg_operand" "")
1637         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1638   ""
1639   "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1642 (define_insn "*zero_extendqisi2_ac"
1643   [(set (match_operand:SI 0 "dest_reg_operand"    "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
1644         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
1645   ""
1646   "@
1647    extb%? %0,%1%&
1648    extb%? %0,%1%&
1649    bmsk%? %0,%1,7
1650    extb %0,%1
1651    ldb%? %0,%1%&
1652    ldb%? %0,%1%&
1653    xldb%U1 %0,%1
1654    ldb%U1 %0,%1"
1655   [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1656    (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1657    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1659 (define_expand "zero_extendqisi2"
1660   [(set (match_operand:SI 0 "dest_reg_operand" "")
1661         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1662   ""
1663   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1666 (define_insn "*zero_extendhisi2_i"
1667   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
1668         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))]
1669   ""
1670   "@
1671    ext%_%? %0,%1%&
1672    ext%_%? %0,%1%&
1673    bmsk%? %0,%1,15
1674    ext%_ %0,%1
1675    ld%_%? %0,%1
1676    ld%_%? %0,%1
1677    * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
1678    ld%_%U1%V1 %0,%1"
1679   [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1680    (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1681    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1684 (define_expand "zero_extendhisi2"
1685   [(set (match_operand:SI 0 "dest_reg_operand" "")
1686         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1687   ""
1688   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1691 ;; Sign extension instructions.
1693 (define_insn "*extendqihi2_i"
1694   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
1695         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
1696   ""
1697   "@
1698    sexb%? %0,%1%&
1699    sexb %0,%1
1700    ldb.x%U1 %0,%1
1701    ldb.x%U1 %0,%1"
1702   [(set_attr "type" "unary,unary,load,load")
1703    (set_attr "iscompact" "true,false,false,false")
1704    (set_attr "length" "*,*,*,8")])
1707 (define_expand "extendqihi2"
1708   [(set (match_operand:HI 0 "dest_reg_operand" "")
1709         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1710   ""
1711   "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1714 (define_insn "*extendqisi2_ac"
1715   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
1716         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
1717   ""
1718   "@
1719    sexb%? %0,%1%&
1720    sexb %0,%1
1721    ldb.x%U1 %0,%1
1722    ldb.x%U1 %0,%1"
1723   [(set_attr "type" "unary,unary,load,load")
1724    (set_attr "iscompact" "true,false,false,false")
1725    (set_attr "length" "*,*,*,8")])
1727 (define_expand "extendqisi2"
1728   [(set (match_operand:SI 0 "dest_reg_operand" "")
1729         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1730   ""
1731   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1734 (define_insn "*extendhisi2_i"
1735   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r")
1736         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
1737   ""
1738   "@
1739    sex%_%? %0,%1%&
1740    sex%_ %0,%1
1741    ldh%?.x %0,%1%&
1742    ld%_.x%U1%V1 %0,%1
1743    ld%_.x%U1%V1 %0,%1"
1744   [(set_attr "type" "unary,unary,load,load,load")
1745    (set_attr "iscompact" "true,false,true,false,false")
1746    (set_attr "length" "*,*,*,4,8")])
1748 (define_expand "extendhisi2"
1749   [(set (match_operand:SI 0 "dest_reg_operand" "")
1750         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1751   ""
1752   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1755 ;; Unary arithmetic insns
1757 ;; We allow constant operands to enable late constant propagation, but it is
1758 ;; not worth while to have more than one dedicated alternative to output them -
1759 ;; if we are really worried about getting these the maximum benefit of all
1760 ;; the available alternatives, we should add an extra pass to fold such
1761 ;; operations to movsi.
1763 ;; Absolute instructions
1765 (define_insn "*abssi2_mixed"
1766   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1767         (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1768   "TARGET_MIXED_CODE"
1769   "abs%? %0,%1%&"
1770   [(set_attr "type" "two_cycle_core")
1771    (set_attr "iscompact" "true")])
1773 (define_insn "abssi2"
1774   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1775         (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1776   ""
1777   "abs%? %0,%1%&"
1778   [(set_attr "type" "two_cycle_core")
1779    (set_attr "length" "*,4,8")
1780    (set_attr "iscompact" "true,false,false")])
1782 ;; Maximum and minimum insns
1784 (define_insn "smaxsi3"
1785    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1786          (smax:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1787                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1788   ""
1789   "max%? %0,%1,%2"
1790   [(set_attr "type" "two_cycle_core")
1791    (set_attr "length" "4,4,8")
1792    (set_attr "predicable" "yes,no,no")]
1795 (define_insn "sminsi3"
1796    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1797          (smin:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1798                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1799   ""
1800   "min%? %0,%1,%2"
1801   [(set_attr "type" "two_cycle_core")
1802    (set_attr "length" "4,4,8")
1803    (set_attr "predicable" "yes,no,no")]
1806 ;; Arithmetic instructions.
1808 ; We say an insn can be conditionalized if this doesn't introduce a long
1809 ; immediate.  We set the type such that we still have good scheduling if the
1810 ; insn is conditionalized.
1811 ; ??? It would make sense to allow introduction of long immediates, but
1812 ;     we'd need to communicate to the ccfsm machinery the extra cost.
1813 ; The alternatives in the constraints still serve three purposes:
1814 ; - estimate insn size assuming conditional execution
1815 ; - guide reload to re-order the second and third operand to get a better fit.
1816 ; - give tentative insn type to guide scheduling
1817 ;   N.B. "%" for commutativity doesn't help when there is another matching
1818 ;   (but longer) alternative.
1819 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1820 ;  register class 'W' instead of 'w'.
1821 (define_insn_and_split "*addsi3_mixed"
1822   ;;                                                      0       1    2    3   4   5   6     7    8   9   a    b     c   d e   f  10  11  12
1823   [(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")
1824         (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")
1825                  (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")))]
1826   ""
1828   arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1829   return "";
1831   "&& reload_completed && get_attr_length (insn) == 8
1832    && satisfies_constraint_I (operands[2])
1833    && GET_CODE (PATTERN (insn)) != COND_EXEC"
1834   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1835   "split_addsi (operands);"
1836   [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
1837    (set (attr "iscompact")
1838         (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1839                (const_string "false")
1840                (match_operand 2 "long_immediate_operand" "")
1841                (const_string "maybe_limm")]
1842               (const_string "maybe")))
1843    (set_attr "length"     "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
1844    (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
1845    (set_attr "cond"       "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1848 ;; ARCv2 MPYW and MPYUW
1849 (define_expand "mulhisi3"
1850   [(set (match_operand:SI 0 "register_operand"                           "")
1851         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"  ""))
1852                  (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1853   "TARGET_MPYW"
1854   "{
1855     if (CONSTANT_P (operands[2]))
1856     {
1857       emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1858       DONE;
1859     }
1860    }"
1863 (define_insn "mulhisi3_imm"
1864   [(set (match_operand:SI 0 "register_operand"                         "=r,r,r,  r,  r")
1865         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0,  0,  r"))
1866                  (match_operand:HI 2 "short_const_int_operand"          "L,L,I,C16,C16")))]
1867   "TARGET_MPYW"
1868   "mpyw%? %0,%1,%2"
1869   [(set_attr "length" "4,4,4,8,8")
1870    (set_attr "iscompact" "false")
1871    (set_attr "type" "mul16_em")
1872    (set_attr "predicable" "yes,no,no,yes,no")
1873    (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1874    ])
1876 (define_insn "mulhisi3_reg"
1877   [(set (match_operand:SI 0 "register_operand"                          "=Rcqq,r,r")
1878         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"  "   0,0,r"))
1879                  (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1880   "TARGET_MPYW"
1881   "mpyw%? %0,%1,%2"
1882   [(set_attr "length" "*,4,4")
1883    (set_attr "iscompact" "maybe,false,false")
1884    (set_attr "type" "mul16_em")
1885    (set_attr "predicable" "yes,yes,no")
1886    (set_attr "cond" "canuse,canuse,nocond")
1887    ])
1889 (define_expand "umulhisi3"
1890   [(set (match_operand:SI 0 "register_operand"                           "")
1891         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand"  ""))
1892                  (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
1893   "TARGET_MPYW"
1894   "{
1895     if (CONSTANT_P (operands[2]))
1896     {
1897       emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1898       DONE;
1899     }
1900   }"
1903 (define_insn "umulhisi3_imm"
1904   [(set (match_operand:SI 0 "register_operand"                          "=r, r,  r,  r,  r")
1905         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r,  0,  0,  r"))
1906                  (match_operand:HI 2 "short_unsigned_const_operand"     " L, L,J12,J16,J16")))]
1907   "TARGET_MPYW"
1908   "mpyuw%? %0,%1,%2"
1909   [(set_attr "length" "4,4,4,8,8")
1910    (set_attr "iscompact" "false")
1911    (set_attr "type" "mul16_em")
1912    (set_attr "predicable" "yes,no,no,yes,no")
1913    (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1914    ])
1916 (define_insn "umulhisi3_reg"
1917   [(set (match_operand:SI 0 "register_operand"                          "=Rcqq, r, r")
1918         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "   %0, 0, r"))
1919                  (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1920   "TARGET_MPYW"
1921   "mpyuw%? %0,%1,%2"
1922   [(set_attr "length" "*,4,4")
1923    (set_attr "iscompact" "maybe,false,false")
1924    (set_attr "type" "mul16_em")
1925    (set_attr "predicable" "yes,yes,no")
1926    (set_attr "cond" "canuse,canuse,nocond")
1927    ])
1929 ;; ARC700/ARC600/V2 multiply
1930 ;; SI <- SI * SI
1932 (define_expand "mulsi3"
1933  [(set (match_operand:SI 0 "nonimmediate_operand"            "")
1934         (mult:SI (match_operand:SI 1 "register_operand"  "")
1935                  (match_operand:SI 2 "nonmemory_operand" "")))]
1936   ""
1938   if (TARGET_MPY)
1939     {
1940       if (!register_operand (operands[0], SImode))
1941         {
1942           rtx result = gen_reg_rtx (SImode);
1944           emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1945           emit_move_insn (operands[0], result);
1946           DONE;
1947         }
1948     }
1949   else if (TARGET_MUL64_SET)
1950     {
1951      rtx tmp = gen_reg_rtx (SImode);
1952      emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
1953      emit_move_insn (operands[0], tmp);
1954      DONE;
1955     }
1956   else if (TARGET_MULMAC_32BY16_SET)
1957     {
1958      rtx tmp = gen_reg_rtx (SImode);
1959      emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
1960      emit_move_insn (operands[0], tmp);
1961      DONE;
1962     }
1963   else
1964     {
1965       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1966       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1967       emit_insn (gen_mulsi3_600_lib ());
1968       emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1969       DONE;
1970     }
1973 (define_insn_and_split "mulsi32x16"
1974  [(set (match_operand:SI 0 "register_operand"            "=w")
1975         (mult:SI (match_operand:SI 1 "register_operand"  "%c")
1976                  (match_operand:SI 2 "nonmemory_operand" "ci")))
1977   (clobber (reg:DI MUL32x16_REG))]
1978  "TARGET_MULMAC_32BY16_SET"
1979  "#"
1980  "TARGET_MULMAC_32BY16_SET && reload_completed"
1981  [(const_int 0)]
1983   if (immediate_operand (operands[2], SImode)
1984     && INTVAL (operands[2]) >= 0
1985     && INTVAL (operands[2]) <= 65535)
1986      {
1987       emit_insn (gen_umul_600 (operands[1], operands[2],
1988                                        gen_acc2 (), gen_acc1 ()));
1989       emit_move_insn (operands[0], gen_acc2 ());
1990       DONE;
1991      }
1992    emit_insn (gen_umul_600 (operands[1], operands[2],
1993                                    gen_acc2 (), gen_acc1 ()));
1994    emit_insn (gen_mac_600 (operands[1], operands[2],
1995                                    gen_acc2 (), gen_acc1 ()));
1996    emit_move_insn (operands[0], gen_acc2 ());
1997    DONE;
1998   }
1999  [(set_attr "type" "multi")
2000   (set_attr "length" "8")])
2002 ; mululw conditional execution without a LIMM clobbers an input register;
2003 ; we'd need a different pattern to describe this.
2004 ; To make the conditional execution valid for the LIMM alternative, we
2005 ; have to emit the LIMM before the register operand.
2006 (define_insn "umul_600"
2007   [(set (match_operand:SI 2 "acc2_operand" "")
2008         (mult:SI (match_operand:SI 0 "register_operand"  "c,c,c")
2009                  (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2010                                                          "c,L,Cal")
2011                                   (const_int 16)
2012                                   (const_int 0))))
2013    (clobber (match_operand:SI 3 "acc1_operand" ""))]
2014   "TARGET_MULMAC_32BY16_SET"
2015   "mululw 0, %0, %1"
2016   [(set_attr "length" "4,4,8")
2017    (set_attr "type" "mulmac_600")
2018    (set_attr "predicable" "no")
2019    (set_attr "cond" "nocond")])
2021 (define_insn "mac_600"
2022   [(set (match_operand:SI 2 "acc2_operand" "")
2023         (plus:SI
2024           (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2025                    (ashift:SI
2026                      (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2027                                       (const_int 16)
2028                                       (const_int 16))
2029                      (const_int 16)))
2030           (match_dup 2)))
2031    (clobber (match_operand:SI 3 "acc1_operand" ""))]
2032   "TARGET_MULMAC_32BY16_SET"
2033   "machlw%? 0, %0, %1"
2034   [(set_attr "length" "4,4,8")
2035    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2036    (set_attr "predicable" "no, no, yes")
2037    (set_attr "cond" "nocond, canuse_limm, canuse")])
2039 (define_insn_and_split "mulsi64"
2040  [(set (match_operand:SI 0 "register_operand"            "=w")
2041         (mult:SI (match_operand:SI 1 "register_operand"  "%c")
2042                  (match_operand:SI 2 "nonmemory_operand" "ci")))
2043   (clobber (reg:DI MUL64_OUT_REG))]
2044  "TARGET_MUL64_SET"
2045  "#"
2046  "TARGET_MUL64_SET && reload_completed"
2047   [(const_int 0)]
2049   emit_insn (gen_mulsi_600 (operands[1], operands[2],
2050                         gen_mlo (), gen_mhi ()));
2051   emit_move_insn (operands[0], gen_mlo ());
2052   DONE;
2054   [(set_attr "type" "multi")
2055    (set_attr "length" "8")])
2057 (define_insn "mulsi_600"
2058   [(set (match_operand:SI 2 "mlo_operand" "")
2059         (mult:SI (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c")
2060                  (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
2061    (clobber (match_operand:SI 3 "mhi_operand" ""))]
2062   "TARGET_MUL64_SET"
2063 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
2064 ; using a machine code pattern that only allows "L" constraint constants.
2065 ;  "mul64%? \t0, %0, %1%&"
2067   if (satisfies_constraint_I (operands[1])
2068       && !satisfies_constraint_L (operands[1]))
2069     {
2070       /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS  */
2071       int n = true_regnum (operands[0]);
2072       int i = INTVAL (operands[1]);
2073       asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
2074       asm_fprintf (asm_out_file, "\t.short %d`",
2075                    ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
2076       return "; mul64%? \t0, %0, %1%&";
2077     }
2078   return "mul64%? \t0, %0, %1%&";
2080   [(set_attr "length" "*,4,4,8")
2081    (set_attr "iscompact" "maybe,false,false,false")
2082    (set_attr "type" "multi,multi,multi,multi")
2083    (set_attr "predicable" "yes,yes,no,yes")
2084    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2086 ; If we compile without an mul option enabled, but link with libraries
2087 ; for a mul option, we'll see clobbers of multiplier output registers.
2088 ; There is also an implementation using norm that clobbers the loop registers.
2089 (define_insn "mulsi3_600_lib"
2090   [(set (reg:SI R0_REG)
2091         (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
2092    (clobber (reg:SI RETURN_ADDR_REGNUM))
2093    (clobber (reg:SI R1_REG))
2094    (clobber (reg:SI R2_REG))
2095    (clobber (reg:SI R3_REG))
2096    (clobber (reg:DI MUL64_OUT_REG))
2097    (clobber (reg:SI LP_COUNT))
2098    (clobber (reg:SI LP_START))
2099    (clobber (reg:SI LP_END))
2100    (clobber (reg:CC CC_REG))]
2101   "!TARGET_ANY_MPY
2102    && SFUNC_CHECK_PREDICABLE"
2103   "*return arc_output_libcall (\"__mulsi3\");"
2104   [(set_attr "is_sfunc" "yes")
2105    (set_attr "predicable" "yes")])
2107 (define_insn_and_split "mulsidi_600"
2108   [(set (match_operand:DI 0 "register_operand"                               "=c, c,c,  c")
2109         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "%Rcq#q, c,c,  c"))
2110                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand"  "Rcq#q,cL,L,C32"))))
2111    (clobber (reg:DI MUL64_OUT_REG))]
2112   "TARGET_MUL64_SET"
2113   "#"
2114   "TARGET_MUL64_SET"
2115   [(const_int 0)]
2116   "emit_insn (gen_mul64 (operands[1], operands[2]));
2117    emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2118    DONE;"
2119   [(set_attr "type" "multi")
2120    (set_attr "length" "8")])
2122 (define_insn "mul64"
2123   [(set (reg:DI MUL64_OUT_REG)
2124         (mult:DI
2125          (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c,  c"))
2126          (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))]
2127   "TARGET_MUL64_SET"
2128   "mul64%? \t0, %0, %1%&"
2129   [(set_attr "length" "*,4,4,8")
2130    (set_attr "iscompact" "maybe,false,false,false")
2131    (set_attr "type" "multi,multi,multi,multi")
2132    (set_attr "predicable" "yes,yes,no,yes")
2133    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2135 (define_insn_and_split "umulsidi_600"
2136   [(set (match_operand:DI 0 "register_operand"                            "=c,c, c")
2137         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"   "%c,c, c"))
2138                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand"  "cL,L,C32"))))
2139    (clobber (reg:DI MUL64_OUT_REG))]
2140   "TARGET_MUL64_SET"
2141   "#"
2142   "TARGET_MUL64_SET"
2143   [(const_int 0)]
2144   "emit_insn (gen_mulu64 (operands[1], operands[2]));
2145    emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2146    DONE;"
2147   [(set_attr "type" "umulti")
2148    (set_attr "length" "8")])
2150 (define_insn "mulu64"
2151   [(set (reg:DI MUL64_OUT_REG)
2152         (mult:DI
2153          (zero_extend:DI (match_operand:SI 0 "register_operand"  "%c,c,c"))
2154          (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2155   "TARGET_MUL64_SET"
2156   "mulu64%? \t0, %0, %1%&"
2157   [(set_attr "length" "4,4,8")
2158    (set_attr "iscompact" "false")
2159    (set_attr "type" "umulti")
2160    (set_attr "predicable" "yes,no,yes")
2161    (set_attr "cond" "canuse,canuse_limm,canuse")])
2163 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2164 ; may not be used as destination constraint.
2166 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2167 ; but mpyu is faster for the standard multiplier.
2168 ; Note: we must make sure LP_COUNT is not one of the destination
2169 ; registers, since it cannot be the destination of a multi-cycle insn
2170 ; like MPY or MPYU.
2171 (define_insn "mulsi3_700"
2172  [(set (match_operand:SI 0 "mpy_dest_reg_operand"        "=Rcr,r,r,Rcr,r")
2173         (mult:SI (match_operand:SI 1 "register_operand"  "%0,c,0,0,c")
2174                  (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2175  "TARGET_ARC700_MPY"
2176   "mpyu%? %0,%1,%2"
2177   [(set_attr "length" "4,4,4,8,8")
2178    (set_attr "type" "umulti")
2179    (set_attr "predicable" "yes,no,no,yes,no")
2180    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2182 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2183 ; short variant. LP_COUNT constraints are still valid.
2184 (define_insn "mulsi3_v2"
2185  [(set (match_operand:SI 0 "mpy_dest_reg_operand"        "=Rcqq,Rcr, r,r,Rcr,  r")
2186         (mult:SI (match_operand:SI 1 "register_operand"     "%0,  0, c,0,  0,  c")
2187                  (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
2188  "TARGET_MULTI"
2189  "mpy%? %0,%1,%2"
2190  [(set_attr "length" "*,4,4,4,8,8")
2191   (set_attr "iscompact" "maybe,false,false,false,false,false")
2192   (set_attr "type" "umulti")
2193   (set_attr "predicable" "no,yes,no,no,yes,no")
2194   (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2196 (define_expand "mulsidi3"
2197   [(set (match_operand:DI 0 "register_operand" "")
2198         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2199                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2200   "TARGET_ANY_MPY"
2201   {
2202   if (TARGET_PLUS_MACD)
2203     {
2204      if (CONST_INT_P (operands[2]))
2205        {
2206         emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2207        }
2208      else
2209        {
2210         emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2211        }
2212      DONE;
2213     }
2214   if (TARGET_MPY)
2215     {
2216       operands[2] = force_reg (SImode, operands[2]);
2217       if (!register_operand (operands[0], DImode))
2218         {
2219           rtx result = gen_reg_rtx (DImode);
2221           operands[2] = force_reg (SImode, operands[2]);
2222           emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2223           emit_move_insn (operands[0], result);
2224           DONE;
2225         }
2226     }
2227   else if (TARGET_MUL64_SET)
2228     {
2229       emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2230       DONE;
2231     }
2232   else if (TARGET_MULMAC_32BY16_SET)
2233     {
2234       operands[2] = force_reg (SImode, operands[2]);
2235       emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2236       DONE;
2237     }
2238   operands[2] = force_reg (SImode, operands[2]);
2239   })
2241 (define_insn_and_split "mulsidi64"
2242   [(set (match_operand:DI 0 "register_operand" "=w")
2243         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2244                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2245    (clobber (reg:DI MUL32x16_REG))]
2246   "TARGET_MULMAC_32BY16_SET"
2247   "#"
2248   "TARGET_MULMAC_32BY16_SET && reload_completed"
2249   [(const_int 0)]
2250   {
2251    rtx result_hi = gen_highpart (SImode, operands[0]);
2252    rtx result_low = gen_lowpart (SImode, operands[0]);
2254    emit_insn (gen_mul64_600 (operands[1], operands[2]));
2255    emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2256    emit_move_insn (result_low, gen_acc2 ());
2257    DONE;
2258   }
2259   [(set_attr "type" "multi")
2260    (set_attr "length" "8")])
2263 (define_insn "mul64_600"
2264   [(set (reg:DI MUL32x16_REG)
2265         (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2266                                   "c,c,c"))
2267                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2268                                   "c,L,Cal")
2269                                   (const_int 16)
2270                                   (const_int 0))))
2271   ]
2272   "TARGET_MULMAC_32BY16_SET"
2273   "mullw%? 0, %0, %1"
2274   [(set_attr "length" "4,4,8")
2275    (set_attr "type" "mulmac_600")
2276    (set_attr "predicable" "no,no,yes")
2277    (set_attr "cond" "nocond, canuse_limm, canuse")])
2280 ;; ??? check if this is canonical rtl
2281 (define_insn "mac64_600"
2282   [(set (reg:DI MUL32x16_REG)
2283         (plus:DI
2284           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2285                    (ashift:DI
2286                      (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2287                                       (const_int 16) (const_int 16))
2288                      (const_int 16)))
2289           (reg:DI MUL32x16_REG)))
2290    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2291         (zero_extract:SI
2292           (plus:DI
2293             (mult:DI (sign_extend:DI (match_dup 1))
2294                      (ashift:DI
2295                        (sign_extract:DI (match_dup 2)
2296                                         (const_int 16) (const_int 16))
2297                           (const_int 16)))
2298             (reg:DI MUL32x16_REG))
2299           (const_int 32) (const_int 32)))]
2300   "TARGET_MULMAC_32BY16_SET"
2301   "machlw%? %0, %1, %2"
2302   [(set_attr "length" "4,4,8")
2303    (set_attr "type" "mulmac_600")
2304    (set_attr "predicable" "no,no,yes")
2305    (set_attr "cond" "nocond, canuse_limm, canuse")])
2308 ;; DI <- DI(signed SI) * DI(signed SI)
2309 (define_insn_and_split "mulsidi3_700"
2310   [(set (match_operand:DI 0 "register_operand" "=&r")
2311         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2312                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2313   "TARGET_MPY && !TARGET_PLUS_MACD"
2314   "#"
2315   "&& reload_completed"
2316   [(const_int 0)]
2318   int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2319   int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2320   rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2321   rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2322   emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2323   emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2324   DONE;
2326   [(set_attr "type" "multi")
2327    (set_attr "length" "8")])
2329 (define_insn "mulsi3_highpart"
2330   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
2331         (truncate:SI
2332          (lshiftrt:DI
2333           (mult:DI
2334            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
2335            (sign_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
2336           (const_int 32))))]
2337   "TARGET_MPY"
2338   "mpy%+%? %0,%1,%2"
2339   [(set_attr "length" "4,4,8,8")
2340    (set_attr "type" "multi")
2341    (set_attr "predicable" "yes,no,yes,no")
2342    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2344 ; Note that mpyhu has the same latency as mpy / mpyh,
2345 ; thus we use the type multi.
2346 (define_insn "*umulsi3_highpart_i"
2347   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
2348         (truncate:SI
2349          (lshiftrt:DI
2350           (mult:DI
2351            (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
2352            (zero_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
2353           (const_int 32))))]
2354   "TARGET_MPY"
2355   "mpy%+u%? %0,%1,%2"
2356   [(set_attr "length" "4,4,8,8")
2357    (set_attr "type" "multi")
2358    (set_attr "predicable" "yes,no,yes,no")
2359    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2361 ; Implementations include additional labels for umulsidi3, so we got all
2362 ; the same clobbers - plus one for the result low part.  */
2363 (define_insn "umulsi3_highpart_600_lib_le"
2364   [(set (reg:SI R1_REG)
2365         (truncate:SI
2366          (lshiftrt:DI
2367           (mult:DI (zero_extend:DI (reg:SI R0_REG))
2368                    (zero_extend:DI (reg:SI R1_REG)))
2369           (const_int 32))))
2370    (clobber (reg:SI RETURN_ADDR_REGNUM))
2371    (clobber (reg:SI R0_REG))
2372    (clobber (reg:DI R2_REG))
2373    (clobber (reg:SI R12_REG))
2374    (clobber (reg:DI MUL64_OUT_REG))
2375    (clobber (reg:CC CC_REG))]
2376   "!TARGET_BIG_ENDIAN
2377    && !TARGET_ANY_MPY
2378    && SFUNC_CHECK_PREDICABLE"
2379   "*return arc_output_libcall (\"__umulsi3_highpart\");"
2380   [(set_attr "is_sfunc" "yes")
2381    (set_attr "predicable" "yes")])
2383 (define_insn "umulsi3_highpart_600_lib_be"
2384   [(set (reg:SI R0_REG)
2385         (truncate:SI
2386          (lshiftrt:DI
2387           (mult:DI (zero_extend:DI (reg:SI R0_REG))
2388                    (zero_extend:DI (reg:SI R1_REG)))
2389           (const_int 32))))
2390    (clobber (reg:SI RETURN_ADDR_REGNUM))
2391    (clobber (reg:SI R1_REG))
2392    (clobber (reg:DI R2_REG))
2393    (clobber (reg:SI R12_REG))
2394    (clobber (reg:DI MUL64_OUT_REG))
2395    (clobber (reg:CC CC_REG))]
2396   "TARGET_BIG_ENDIAN
2397    && !TARGET_ANY_MPY
2398    && SFUNC_CHECK_PREDICABLE"
2399   "*return arc_output_libcall (\"__umulsi3_highpart\");"
2400   [(set_attr "is_sfunc" "yes")
2401    (set_attr "predicable" "yes")])
2403 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2404 ;; need a separate pattern for immediates
2405 ;; ??? This is fine for combine, but not for reload.
2406 (define_insn "umulsi3_highpart_int"
2407   [(set (match_operand:SI 0 "register_operand"            "=Rcr, r, r,Rcr,  r")
2408         (truncate:SI
2409          (lshiftrt:DI
2410           (mult:DI
2411            (zero_extend:DI (match_operand:SI 1 "register_operand"  " 0, c, 0,  0,  c"))
2412            (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2413           (const_int 32))))]
2414   "TARGET_MPY"
2415   "mpy%+u%? %0,%1,%2"
2416   [(set_attr "length" "4,4,4,8,8")
2417    (set_attr "type" "multi")
2418    (set_attr "predicable" "yes,no,no,yes,no")
2419    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2421 (define_expand "umulsi3_highpart"
2422   [(set (match_operand:SI 0 "general_operand"  "")
2423         (truncate:SI
2424          (lshiftrt:DI
2425           (mult:DI
2426            (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2427            (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2428           (const_int 32))))]
2429   "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2430   "
2432   rtx target = operands[0];
2434   if (!TARGET_MPY)
2435     {
2436       emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2437       emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2438       if (TARGET_BIG_ENDIAN)
2439         emit_insn (gen_umulsi3_highpart_600_lib_be ());
2440       else
2441         emit_insn (gen_umulsi3_highpart_600_lib_le ());
2442       emit_move_insn (target, gen_rtx_REG (SImode, 0));
2443       DONE;
2444     }
2446   if (!register_operand (target, SImode))
2447     target = gen_reg_rtx (SImode);
2449   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2450     operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2451                                                   operands[2], SImode);
2452   else if (!immediate_operand (operands[2], SImode))
2453     operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2454   emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2455   if (target != operands[0])
2456     emit_move_insn (operands[0], target);
2457   DONE;
2460 (define_expand "umulsidi3"
2461   [(set (match_operand:DI 0 "register_operand" "")
2462         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2463                  (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2464   ""
2466   if (TARGET_PLUS_MACD)
2467     {
2468      if (CONST_INT_P (operands[2]))
2469        {
2470         emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2471        }
2472      else
2473        {
2474         emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2475        }
2476      DONE;
2477     }
2478   if (TARGET_MPY)
2479     {
2480       operands[2] = force_reg (SImode, operands[2]);
2481       if (!register_operand (operands[0], DImode))
2482         {
2483           rtx result = gen_reg_rtx (DImode);
2485           emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2486           emit_move_insn (operands[0], result);
2487           DONE;
2488         }
2489     }
2490   else if (TARGET_MUL64_SET)
2491     {
2492      operands[2] = force_reg (SImode, operands[2]);
2493      emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2494       DONE;
2495     }
2496   else if (TARGET_MULMAC_32BY16_SET)
2497     {
2498      operands[2] = force_reg (SImode, operands[2]);
2499      emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2500       DONE;
2501     }
2502   else
2503     {
2504       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2505       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2506       emit_insn (gen_umulsidi3_600_lib ());
2507       emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2508       DONE;
2509     }
2512 (define_insn_and_split "umulsidi64"
2513   [(set (match_operand:DI 0 "register_operand" "=w")
2514         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2515                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2516    (clobber (reg:DI MUL32x16_REG))]
2517   "TARGET_MULMAC_32BY16_SET"
2518   "#"
2519   "TARGET_MULMAC_32BY16_SET && reload_completed"
2520   [(const_int 0)]
2521   {
2522    rtx result_hi;
2523    rtx result_low;
2525    result_hi = gen_highpart (SImode, operands[0]);
2526    result_low = gen_lowpart (SImode, operands[0]);
2528    emit_insn (gen_umul64_600 (operands[1], operands[2]));
2529    emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2530    emit_move_insn (result_low, gen_acc2 ());
2531    DONE;
2532    }
2533   [(set_attr "type" "multi")
2534    (set_attr "length" "8")])
2536 (define_insn "umul64_600"
2537   [(set (reg:DI MUL32x16_REG)
2538         (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2539                                   "c,c,c"))
2540                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2541                                   "c,L,Cal")
2542                                   (const_int 16)
2543                                   (const_int 0))))
2544   ]
2545   "TARGET_MULMAC_32BY16_SET"
2546   "mululw 0, %0, %1"
2547   [(set_attr "length" "4,4,8")
2548    (set_attr "type" "mulmac_600")
2549    (set_attr "predicable" "no")
2550    (set_attr "cond" "nocond")])
2553 (define_insn "umac64_600"
2554   [(set (reg:DI MUL32x16_REG)
2555         (plus:DI
2556           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2557                    (ashift:DI
2558                      (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2559                                       (const_int 16) (const_int 16))
2560                      (const_int 16)))
2561           (reg:DI MUL32x16_REG)))
2562    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2563         (zero_extract:SI
2564           (plus:DI
2565             (mult:DI (zero_extend:DI (match_dup 1))
2566                      (ashift:DI
2567                        (zero_extract:DI (match_dup 2)
2568                                         (const_int 16) (const_int 16))
2569                           (const_int 16)))
2570             (reg:DI MUL32x16_REG))
2571           (const_int 32) (const_int 32)))]
2572   "TARGET_MULMAC_32BY16_SET"
2573   "machulw%? %0, %1, %2"
2574   [(set_attr "length" "4,4,8")
2575    (set_attr "type" "mulmac_600")
2576    (set_attr "predicable" "no,no,yes")
2577    (set_attr "cond" "nocond, canuse_limm, canuse")])
2579 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2580 (define_insn_and_split "umulsidi3_700"
2581   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2582         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2583                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2584   "TARGET_MPY && !TARGET_PLUS_MACD"
2585   "#"
2586   "reload_completed"
2587   [(const_int 0)]
2589   int hi = !TARGET_BIG_ENDIAN;
2590   int lo = !hi;
2591   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2592   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2593   emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2594   emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2595   DONE;
2597   [(set_attr "type" "umulti")
2598   (set_attr "length" "8")])
2600 (define_insn "umulsidi3_600_lib"
2601   [(set (reg:DI R0_REG)
2602         (mult:DI (zero_extend:DI (reg:SI R0_REG))
2603                  (zero_extend:DI (reg:SI R1_REG))))
2604    (clobber (reg:SI RETURN_ADDR_REGNUM))
2605    (clobber (reg:DI R2_REG))
2606    (clobber (reg:SI R12_REG))
2607    (clobber (reg:DI MUL64_OUT_REG))
2608    (clobber (reg:CC CC_REG))]
2609    "!TARGET_ANY_MPY
2610    && SFUNC_CHECK_PREDICABLE"
2611   "*return arc_output_libcall (\"__umulsidi3\");"
2612   [(set_attr "is_sfunc" "yes")
2613    (set_attr "predicable" "yes")])
2615 (define_peephole2
2616   [(parallel
2617      [(set (reg:DI R0_REG)
2618            (mult:DI (zero_extend:DI (reg:SI R0_REG))
2619                     (zero_extend:DI (reg:SI R1_REG))))
2620       (clobber (reg:SI RETURN_ADDR_REGNUM))
2621       (clobber (reg:DI R2_REG))
2622       (clobber (reg:SI R12_REG))
2623       (clobber (reg:DI MUL64_OUT_REG))
2624       (clobber (reg:CC CC_REG))])]
2625   "!TARGET_ANY_MPY
2626    && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2627   [(pc)]
2629   if (TARGET_BIG_ENDIAN)
2630     emit_insn (gen_umulsi3_highpart_600_lib_be ());
2631   else
2632     emit_insn (gen_umulsi3_highpart_600_lib_le ());
2633   DONE;
2636 (define_expand "addsi3"
2637   [(set (match_operand:SI 0 "dest_reg_operand" "")
2638         (plus:SI (match_operand:SI 1 "register_operand" "")
2639                  (match_operand:SI 2 "nonmemory_operand" "")))]
2640   ""
2641   "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2642      {
2643        operands[2]=force_reg(SImode, operands[2]);
2644      }
2645   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2646    {
2647       operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2648    }
2650   ")
2652 (define_expand "adddi3"
2653   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2654                    (plus:DI (match_operand:DI 1 "register_operand" "")
2655                             (match_operand:DI 2 "nonmemory_operand" "")))
2656               (clobber (reg:CC CC_REG))])]
2657   ""
2660 ; This assumes that there can be no strictly partial overlap between
2661 ; operands[1] and operands[2].
2662 (define_insn_and_split "*adddi3_i"
2663   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2664         (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2665                  (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2666    (clobber (reg:CC CC_REG))]
2667   ""
2668   "#"
2669   "reload_completed"
2670   [(const_int 0)]
2672   int hi = !TARGET_BIG_ENDIAN;
2673   int lo = !hi;
2674   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2675   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2676   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2677   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2678   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2679   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2682   if (l2 == const0_rtx)
2683     {
2684       if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2685         emit_move_insn (l0, l1);
2686       emit_insn (gen_addsi3 (h0, h1, h2));
2687       if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2688         emit_move_insn (l0, l1);
2689       DONE;
2690     }
2691   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2692       && INTVAL (operands[2]) >= -0x7fffffff)
2693     {
2694       emit_insn (gen_subdi3_i (operands[0], operands[1],
2695                  GEN_INT (-INTVAL (operands[2]))));
2696       DONE;
2697     }
2698   if (rtx_equal_p (l0, h1))
2699     {
2700       if (h2 != const0_rtx)
2701         emit_insn (gen_addsi3 (h0, h1, h2));
2702       else if (!rtx_equal_p (h0, h1))
2703         emit_move_insn (h0, h1);
2704       emit_insn (gen_add_f (l0, l1, l2));
2705       emit_insn
2706         (gen_rtx_COND_EXEC
2707           (VOIDmode,
2708            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2709            gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2710       DONE;
2711     }
2712   emit_insn (gen_add_f (l0, l1, l2));
2713   emit_insn (gen_adc (h0, h1, h2));
2714   DONE;
2716   [(set_attr "cond" "clob")
2717    (set_attr "type" "binary")
2718    (set_attr "length" "16,16,20")])
2720 (define_insn "add_f"
2721   [(set (reg:CC_C CC_REG)
2722         (compare:CC_C
2723           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2724                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2725           (match_dup 1)))
2726    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2727         (plus:SI (match_dup 1) (match_dup 2)))]
2728   ""
2729   "add.f %0,%1,%2"
2730   [(set_attr "cond" "set")
2731    (set_attr "type" "compare")
2732    (set_attr "length" "4,4,8")])
2734 (define_insn "*add_f_2"
2735   [(set (reg:CC_C CC_REG)
2736         (compare:CC_C
2737           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2738                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2739           (match_dup 2)))
2740    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2741         (plus:SI (match_dup 1) (match_dup 2)))]
2742   ""
2743   "add.f %0,%1,%2"
2744   [(set_attr "cond" "set")
2745    (set_attr "type" "compare")
2746    (set_attr "length" "4,4,8")])
2748 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2749 ; needlessly prioritizing the matching constraint.
2750 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2751 ; execution is used where possible.
2752 (define_insn_and_split "adc"
2753   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2754         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2755                           (match_operand:SI 1 "nonmemory_operand"
2756                                                          "%c,0,c,0,cCal"))
2757                  (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2758   "register_operand (operands[1], SImode)
2759    || register_operand (operands[2], SImode)"
2760   "@
2761         adc %0,%1,%2
2762         add.cs %0,%1,1
2763         adc %0,%1,%2
2764         adc %0,%1,%2
2765         adc %0,%1,%2"
2766   ; if we have a bad schedule after sched2, split.
2767   "reload_completed
2768    && !optimize_size && (!TARGET_ARC600_FAMILY)
2769    && arc_scheduling_not_expected ()
2770    && arc_sets_cc_p (prev_nonnote_insn (insn))
2771    /* If next comes a return or other insn that needs a delay slot,
2772       expect the adc to get into the delay slot.  */
2773    && next_nonnote_insn (insn)
2774    && !arc_need_delay (next_nonnote_insn (insn))
2775    /* Restore operands before emitting.  */
2776    && (extract_insn_cached (insn), 1)"
2777   [(set (match_dup 0) (match_dup 3))
2778    (cond_exec
2779      (ltu (reg:CC_C CC_REG) (const_int 0))
2780      (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2781   "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2782   [(set_attr "cond" "use")
2783    (set_attr "type" "cc_arith")
2784    (set_attr "length" "4,4,4,4,8")])
2786 ; combiner-splitter cmp / scc -> cmp / adc
2787 (define_split
2788   [(set (match_operand:SI 0 "dest_reg_operand" "")
2789         (gtu:SI (match_operand:SI 1 "register_operand" "")
2790                 (match_operand:SI 2 "register_operand" "")))
2791    (clobber (reg CC_REG))]
2792   ""
2793   [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2794    (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2796 ; combine won't work when an intermediate result is used later...
2797 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2798 (define_peephole2
2799   [(set (match_operand:SI 0 "dest_reg_operand" "")
2800         (plus:SI (match_operand:SI 1 "register_operand" "")
2801                  (match_operand:SI 2 "nonmemory_operand" "")))
2802    (set (reg:CC_C CC_REG)
2803         (compare:CC_C (match_dup 0)
2804                       (match_operand:SI 3 "nonmemory_operand" "")))]
2805   "rtx_equal_p (operands[1], operands[3])
2806    || rtx_equal_p (operands[2], operands[3])"
2807   [(parallel
2808      [(set (reg:CC_C CC_REG)
2809            (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2810       (set (match_dup 0)
2811            (plus:SI (match_dup 1) (match_dup 2)))])])
2813 ; ??? need to delve into combine to find out why this is not useful.
2814 ; We'd like to be able to grok various C idioms for carry bit usage.
2815 ;(define_insn "*adc_0"
2816 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2817 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2818 ;                (match_operand:SI 1 "register_operand" "c")))]
2819 ;  ""
2820 ;  "adc %0,%1,0"
2821 ;  [(set_attr "cond" "use")
2822 ;   (set_attr "type" "cc_arith")
2823 ;   (set_attr "length" "4")])
2825 ;(define_split
2826 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2827 ;       (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2828 ;                        (match_operand:SI 2 "register_operand" "c"))
2829 ;                (match_operand:SI 3 "register_operand" "c")))
2830 ;   (clobber (reg CC_REG))]
2831 ;  ""
2832 ;  [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2833 ;   (set (match_dup 0)
2834 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2835 ;                (match_dup 3)))])
2837 (define_expand "subsi3"
2838   [(set (match_operand:SI 0 "dest_reg_operand" "")
2839         (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2840                  (match_operand:SI 2 "nonmemory_operand" "")))]
2841   ""
2842   "
2844   int c = 1;
2846   if (!register_operand (operands[2], SImode))
2847     {
2848       operands[1] = force_reg (SImode, operands[1]);
2849       c = 2;
2850     }
2851   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2852     operands[c] = force_reg (SImode, operands[c]);
2853   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2854       operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2857 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2858 ; combine should make such an insn go away.
2859 (define_insn_and_split "subsi3_insn"
2860   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcqq,Rcqq,Rcw,Rcw,w,w,w,  w,  w,  w")
2861         (minus:SI (match_operand:SI 1 "nonmemory_operand"    "0,Rcqq,  0, cL,c,L,I,Cal,Cal,  c")
2862                   (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq,  c,  0,c,c,0,  0,  c,Cal")))]
2863   "register_operand (operands[1], SImode)
2864    || register_operand (operands[2], SImode)"
2865   "@
2866     sub%? %0,%1,%2%&
2867     sub%? %0,%1,%2%&
2868     sub%? %0,%1,%2
2869     rsub%? %0,%2,%1
2870     sub %0,%1,%2
2871     rsub %0,%2,%1
2872     rsub %0,%2,%1
2873     rsub%? %0,%2,%1
2874     rsub %0,%2,%1
2875     sub %0,%1,%2"
2876   "reload_completed && get_attr_length (insn) == 8
2877    && satisfies_constraint_I (operands[1])
2878    && GET_CODE (PATTERN (insn)) != COND_EXEC"
2879   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2880   "split_subsi (operands);"
2881   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2882   (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2883   (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2884   (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2885   (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2886   ])
2888 (define_expand "subdi3"
2889   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2890                    (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2891                              (match_operand:DI 2 "nonmemory_operand" "")))
2892               (clobber (reg:CC CC_REG))])]
2893   ""
2895   if (!register_operand (operands[2], DImode))
2896     operands[1] = force_reg (DImode, operands[1]);
2899 (define_insn_and_split "subdi3_i"
2900   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2901         (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2902                   (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2903    (clobber (reg:CC CC_REG))]
2904   "register_operand (operands[1], DImode)
2905    || register_operand (operands[2], DImode)"
2906   "#"
2907   "reload_completed"
2908   [(const_int 0)]
2910   int hi = !TARGET_BIG_ENDIAN;
2911   int lo = !hi;
2912   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2913   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2914   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2915   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2916   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2917   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2919   if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2920     {
2921       h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2922       if (!rtx_equal_p (h0, h1))
2923         emit_insn (gen_rtx_SET (h0, h1));
2924       emit_insn (gen_sub_f (l0, l1, l2));
2925       emit_insn
2926         (gen_rtx_COND_EXEC
2927           (VOIDmode,
2928            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2929            gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2930       DONE;
2931     }
2932   emit_insn (gen_sub_f (l0, l1, l2));
2933   emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2934   DONE;
2936   [(set_attr "cond" "clob")
2937    (set_attr "length" "16,16,16,20,20")])
2939 (define_insn "*sbc_0"
2940   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2941         (minus:SI (match_operand:SI 1 "register_operand" "c")
2942                   (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2943                           (const_int 0))))]
2944   ""
2945   "sbc %0,%1,0"
2946   [(set_attr "cond" "use")
2947    (set_attr "type" "cc_arith")
2948    (set_attr "length" "4")])
2950 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2951 ; needlessly prioritizing the matching constraint.
2952 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2953 ; is used where possible.
2954 (define_insn_and_split "sbc"
2955   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2956         (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2957                                                 "c,0,c,0,cCal")
2958                             (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2959                                     (const_int 0)))
2960                   (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2961   "register_operand (operands[1], SImode)
2962    || register_operand (operands[2], SImode)"
2963   "@
2964         sbc %0,%1,%2
2965         sub.cs %0,%1,1
2966         sbc %0,%1,%2
2967         sbc %0,%1,%2
2968         sbc %0,%1,%2"
2969   ; if we have a bad schedule after sched2, split.
2970   "reload_completed
2971    && !optimize_size && (!TARGET_ARC600_FAMILY)
2972    && arc_scheduling_not_expected ()
2973    && arc_sets_cc_p (prev_nonnote_insn (insn))
2974    /* If next comes a return or other insn that needs a delay slot,
2975       expect the adc to get into the delay slot.  */
2976    && next_nonnote_insn (insn)
2977    && !arc_need_delay (next_nonnote_insn (insn))
2978    /* Restore operands before emitting.  */
2979    && (extract_insn_cached (insn), 1)"
2980   [(set (match_dup 0) (match_dup 4))
2981    (cond_exec
2982      (ltu (reg:CC_C CC_REG) (const_int 0))
2983      (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2984   "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2985   [(set_attr "cond" "use")
2986    (set_attr "type" "cc_arith")
2987    (set_attr "length" "4,4,4,4,8")])
2989 (define_insn "sub_f"
2990   [(set (reg:CC CC_REG)
2991         (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2992                     (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2993    (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2994         (minus:SI (match_dup 1) (match_dup 2)))]
2995   "register_operand (operands[1], SImode)
2996    || register_operand (operands[2], SImode)"
2997   "@
2998         sub.f %0,%1,%2
2999         rsub.f %0,%2,%1
3000         sub.f %0,%1,%2
3001         rsub.f %0,%2,%1
3002         sub.f %0,%1,%2
3003         sub.f %0,%1,%2"
3004   [(set_attr "type" "compare")
3005    (set_attr "length" "4,4,4,4,8,8")])
3007 ; combine won't work when an intermediate result is used later...
3008 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3009 (define_peephole2
3010   [(set (reg:CC CC_REG)
3011         (compare:CC (match_operand:SI 1 "register_operand" "")
3012                     (match_operand:SI 2 "nonmemory_operand" "")))
3013    (set (match_operand:SI 0 "dest_reg_operand" "")
3014         (minus:SI (match_dup 1) (match_dup 2)))]
3015   ""
3016   [(parallel
3017      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3018       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3020 (define_peephole2
3021   [(set (reg:CC CC_REG)
3022         (compare:CC (match_operand:SI 1 "register_operand" "")
3023                     (match_operand:SI 2 "nonmemory_operand" "")))
3024    (set (match_operand 3 "" "") (match_operand 4 "" ""))
3025    (set (match_operand:SI 0 "dest_reg_operand" "")
3026         (minus:SI (match_dup 1) (match_dup 2)))]
3027   "!reg_overlap_mentioned_p (operands[3], operands[1])
3028    && !reg_overlap_mentioned_p (operands[3], operands[2])
3029    && !reg_overlap_mentioned_p (operands[0], operands[4])
3030    && !reg_overlap_mentioned_p (operands[0], operands[3])"
3031   [(parallel
3032      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3033       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3034    (set (match_dup 3) (match_dup 4))])
3036 (define_insn "*add_n"
3037   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3038         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3039                             (match_operand:SI 2 "_1_2_3_operand" ""))
3040                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3041   ""
3042   "add%c2%? %0,%3,%1%&"
3043   [(set_attr "type" "shift")
3044    (set_attr "length" "*,4,4,8,4,8")
3045    (set_attr "predicable" "yes,yes,no,no,no,no")
3046    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3047    (set_attr "iscompact" "maybe,false,false,false,false,false")])
3049 (define_insn "*add_n"
3050   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3051         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3052                           (match_operand:SI 2 "_2_4_8_operand" ""))
3053                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3054   ""
3055   "add%z2%? %0,%3,%1%&"
3056   [(set_attr "type" "shift")
3057    (set_attr "length" "*,4,4,8,4,8")
3058    (set_attr "predicable" "yes,yes,no,no,no,no")
3059    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3060    (set_attr "iscompact" "maybe,false,false,false,false,false")])
3062 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3063 ;; what synth_mult likes.
3064 (define_insn "*sub_n"
3065   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3066         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3067                   (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
3068                              (match_operand:SI 3 "_1_2_3_operand" ""))))]
3069   ""
3070   "sub%c3%? %0,%1,%2"
3071   [(set_attr "type" "shift")
3072    (set_attr "length" "4,4,8")
3073    (set_attr "predicable" "yes,no,no")
3074    (set_attr "cond" "canuse,nocond,nocond")
3075    (set_attr "iscompact" "false")])
3077 (define_insn "*sub_n"
3078   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3079         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3080                   (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
3081                            (match_operand:SI 3 "_2_4_8_operand" ""))))]
3082   ""
3083   "sub%z3%? %0,%1,%2"
3084   [(set_attr "type" "shift")
3085    (set_attr "length" "4,4,8")
3086    (set_attr "predicable" "yes,no,no")
3087    (set_attr "cond" "canuse,nocond,nocond")
3088    (set_attr "iscompact" "false")])
3090 ; ??? check if combine matches this.
3091 (define_insn "*bset"
3092   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3093         (ior:SI (ashift:SI (const_int 1)
3094                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3095                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3096   ""
3097   "bset%? %0,%2,%1"
3098   [(set_attr "length" "4,4,8")
3099    (set_attr "predicable" "yes,no,no")
3100    (set_attr "cond" "canuse,nocond,nocond")]
3103 ; ??? check if combine matches this.
3104 (define_insn "*bxor"
3105   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3106         (xor:SI (ashift:SI (const_int 1)
3107                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3108                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3109   ""
3110   "bxor%? %0,%2,%1"
3111   [(set_attr "length" "4,4,8")
3112    (set_attr "predicable" "yes,no,no")
3113    (set_attr "cond" "canuse,nocond,nocond")]
3116 ; ??? check if combine matches this.
3117 (define_insn "*bclr"
3118   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3119         (and:SI (not:SI (ashift:SI (const_int 1)
3120                                    (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
3121                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3122   ""
3123   "bclr%? %0,%2,%1"
3124   [(set_attr "length" "4,4,8")
3125    (set_attr "predicable" "yes,no,no")
3126    (set_attr "cond" "canuse,nocond,nocond")]
3129 ; ??? FIXME: find combine patterns for bmsk.
3131 ;;Following are the define_insns added for the purpose of peephole2's
3133 ; see also iorsi3 for use with constant bit number.
3134 (define_insn "*bset_insn"
3135   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3136         (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3137                 (ashift:SI (const_int 1)
3138                            (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3139   ""
3140   "@
3141      bset%? %0,%1,%2 ;;peep2, constr 1
3142      bset %0,%1,%2 ;;peep2, constr 2
3143      bset %0,%S1,%2 ;;peep2, constr 3"
3144   [(set_attr "length" "4,4,8")
3145    (set_attr "predicable" "yes,no,no")
3146    (set_attr "cond" "canuse,nocond,nocond")]
3149 ; see also xorsi3 for use with constant bit number.
3150 (define_insn "*bxor_insn"
3151   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3152         (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3153                 (ashift:SI (const_int 1)
3154                         (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3155   ""
3156   "@
3157      bxor%? %0,%1,%2
3158      bxor %0,%1,%2
3159      bxor %0,%S1,%2"
3160   [(set_attr "length" "4,4,8")
3161    (set_attr "predicable" "yes,no,no")
3162    (set_attr "cond" "canuse,nocond,nocond")]
3165 ; see also andsi3 for use with constant bit number.
3166 (define_insn "*bclr_insn"
3167   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3168         (and:SI (not:SI (ashift:SI (const_int 1)
3169                                    (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
3170                 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
3171   ""
3172   "@
3173      bclr%? %0,%1,%2
3174      bclr %0,%1,%2
3175      bclr %0,%S1,%2"
3176   [(set_attr "length" "4,4,8")
3177    (set_attr "predicable" "yes,no,no")
3178    (set_attr "cond" "canuse,nocond,nocond")]
3181 ; see also andsi3 for use with constant bit number.
3182 (define_insn "*bmsk_insn"
3183   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3184         (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3185                 (plus:SI (ashift:SI (const_int 1)
3186                                     (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3187                                              (const_int 1)))
3188                          (const_int -1))))]
3189   ""
3190   "@
3191      bmsk%? %0,%S1,%2
3192      bmsk %0,%1,%2
3193      bmsk %0,%S1,%2"
3194   [(set_attr "length" "4,4,8")
3195    (set_attr "predicable" "yes,no,no")
3196    (set_attr "cond" "canuse,nocond,nocond")]
3199 ;;Instructions added for peephole2s end
3201 ;; Boolean instructions.
3203 (define_expand "andsi3"
3204   [(set (match_operand:SI 0 "dest_reg_operand" "")
3205         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3206                 (match_operand:SI 2 "nonmemory_operand" "")))]
3207   ""
3208   "if (!satisfies_constraint_Cux (operands[2]))
3209      operands[1] = force_reg (SImode, operands[1]);
3210    else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
3211      operands[1] = arc_rewrite_small_data (operands[1]);")
3213 (define_insn "andsi3_i"
3214   [(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")
3215         (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")
3216                 (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")))]
3217   "(register_operand (operands[1], SImode)
3218     && nonmemory_operand (operands[2], SImode))
3219    || (memory_operand (operands[1], SImode)
3220        && satisfies_constraint_Cux (operands[2]))"
3222   switch (which_alternative)
3223     {
3224     case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3225       return "and%? %0,%1,%2%&";
3226     case 1: case 6:
3227       return "and%? %0,%2,%1%&";
3228     case 2:
3229       return "bmsk%? %0,%1,%Z2%&";
3230     case 7: case 12:
3231      if (satisfies_constraint_C2p (operands[2]))
3232        {
3233         operands[2] = GEN_INT ((~INTVAL (operands[2])));
3234         return "bmskn%? %0,%1,%Z2%&";
3235        }
3236      else
3237        {
3238         return "bmsk%? %0,%1,%Z2%&";
3239        }
3240     case 3: case 8: case 13:
3241       return "bclr%? %0,%1,%M2%&";
3242     case 4:
3243       return (INTVAL (operands[2]) == 0xff
3244               ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3245     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3246     case 15:
3247       return "movb.cl %0,%1,%p2,%p2,%s2";
3249     case 19:
3250       const char *tmpl;
3252       if (satisfies_constraint_Ucm (operands[1]))
3253         tmpl = (INTVAL (operands[2]) == 0xff
3254                 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3255       else
3256         tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3258       if (TARGET_BIG_ENDIAN)
3259         {
3260           rtx xop[2];
3262           xop[0] = operands[0];
3263           xop[1] = adjust_address (operands[1], QImode,
3264                                    INTVAL (operands[2]) == 0xff ? 3 : 2);
3265           output_asm_insn (tmpl, xop);
3266           return "";
3267         }
3268       return tmpl;
3269     default:
3270       gcc_unreachable ();
3271     }
3273   [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3274    (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3275    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3276    (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3277    (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")])
3279 ; combiner splitter, pattern found in ldtoa.c .
3280 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3281 (define_split
3282   [(set (reg:CC_Z CC_REG)
3283         (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3284                               (match_operand 1 "const_int_operand" ""))
3285                       (match_operand 2 "const_int_operand" "")))
3286    (clobber (match_operand:SI 3 "register_operand" ""))]
3287   "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3288   [(set (match_dup 3)
3289         (plus:SI (match_dup 0) (match_dup 4)))
3290    (set (reg:CC_Z CC_REG)
3291         (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3292                       (const_int 0)))]
3293   "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3295 ;;bic define_insn that allows limm to be the first operand
3296 (define_insn "*bicsi3_insn"
3297    [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3298         (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3299                 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3300   ""
3301   "@
3302    bic%? %0, %2, %1%& ;;constraint 0
3303    bic%? %0,%2,%1  ;;constraint 1
3304    bic %0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
3305    bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3306    bic %0,%2,%1    ;;constraint 4
3307    bic %0,%2,%S1   ;;constraint 5, FIXME: will it ever get generated ???
3308    bic %0,%S2,%1   ;;constraint 6"
3309   [(set_attr "length" "*,4,4,8,4,8,8")
3310   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3311   (set_attr "predicable" "no,yes,no,yes,no,no,no")
3312   (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3314 (define_insn "iorsi3"
3315   [(set (match_operand:SI 0 "dest_reg_operand"        "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w,  w,w,Rcw,  w")
3316         (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq,   0,  0,  c,  0, 0, c,  c,0,  0,  c")
3317                 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL,  0,C0p, I,cL,C0p,I,Cal,Cal")))]
3318   ""
3319   "*
3320   switch (which_alternative)
3321     {
3322     case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3323       return \"or%? %0,%1,%2%&\";
3324     case 1: case 4:
3325       return \"or%? %0,%2,%1%&\";
3326     case 2: case 5: case 8:
3327       return \"bset%? %0,%1,%z2%&\";
3328     default:
3329       gcc_unreachable ();
3330     }"
3331   [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3332    (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3333    (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3334    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3336 (define_insn "xorsi3"
3337   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w,  w,w,  w,  w")
3338         (xor:SI (match_operand:SI 1 "register_operand"  "%0,   Rcq,  0,  c,  0,  0, c,  c,0,  0,  c")
3339                 (match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, cL,  0,C0p,  I,cL,C0p,I,Cal,Cal")))]
3340   ""
3341   "*
3342   switch (which_alternative)
3343     {
3344     case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3345       return \"xor%? %0,%1,%2%&\";
3346     case 1: case 3:
3347       return \"xor%? %0,%2,%1%&\";
3348     case 4: case 7:
3349       return \"bxor%? %0,%1,%z2\";
3350     default:
3351       gcc_unreachable ();
3352     }
3353   "
3354   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3355    (set_attr "type" "binary")
3356    (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3357    (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3358    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3360 (define_insn "negsi2"
3361   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3362         (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3363   ""
3364   "neg%? %0,%1%&"
3365   [(set_attr "type" "unary")
3366    (set_attr "iscompact" "maybe,true,false,false")
3367    (set_attr "predicable" "no,no,yes,no")])
3369 (define_insn "one_cmplsi2"
3370   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3371         (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3372   ""
3373   "not%? %0,%1%&"
3374   [(set_attr "type" "unary,unary")
3375    (set_attr "iscompact" "true,false")])
3377 (define_insn_and_split "one_cmpldi2"
3378   [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3379         (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3380   ""
3381   "#"
3382   "&& reload_completed"
3383   [(set (match_dup 2) (not:SI (match_dup 3)))
3384    (set (match_dup 4) (not:SI (match_dup 5)))]
3386   int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3388   operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3389   operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3390   operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3391   operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3393   [(set_attr "type" "unary,unary")
3394    (set_attr "cond" "nocond,nocond")
3395    (set_attr "length" "4,8")])
3397 ;; Shift instructions.
3399 (define_expand "ashlsi3"
3400   [(set (match_operand:SI 0 "dest_reg_operand" "")
3401         (ashift:SI (match_operand:SI 1 "register_operand" "")
3402                    (match_operand:SI 2 "nonmemory_operand" "")))]
3403   ""
3404   "
3406   if (!TARGET_BARREL_SHIFTER)
3407     {
3408       emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3409       DONE;
3410     }
3413 (define_expand "ashrsi3"
3414   [(set (match_operand:SI 0 "dest_reg_operand" "")
3415         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3416                      (match_operand:SI 2 "nonmemory_operand" "")))]
3417   ""
3418   "
3420   if (!TARGET_BARREL_SHIFTER)
3421     {
3422       emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3423       DONE;
3424     }
3427 (define_expand "lshrsi3"
3428   [(set (match_operand:SI 0 "dest_reg_operand" "")
3429         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3430                      (match_operand:SI 2 "nonmemory_operand" "")))]
3431   ""
3432   "
3434   if (!TARGET_BARREL_SHIFTER)
3435     {
3436       emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3437       DONE;
3438     }
3441 (define_insn "shift_si3"
3442   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3443         (match_operator:SI 3 "shift4_operator"
3444                            [(match_operand:SI 1 "register_operand" "0")
3445                             (match_operand:SI 2 "const_int_operand" "n")]))
3446    (clobber (match_scratch:SI 4 "=&r"))
3447    (clobber (reg:CC CC_REG))
3448   ]
3449   "!TARGET_BARREL_SHIFTER"
3450   "* return output_shift (operands);"
3451   [(set_attr "type" "shift")
3452    (set_attr "length" "16")])
3454 (define_insn "shift_si3_loop"
3455   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3456         (match_operator:SI 3 "shift_operator"
3457                            [(match_operand:SI 1 "register_operand" "0,0")
3458                             (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3459    (clobber (match_scratch:SI 4 "=X,X"))
3460    (clobber (reg:SI LP_COUNT))
3461    (clobber (reg:SI LP_START))
3462    (clobber (reg:SI LP_END))
3463    (clobber (reg:CC CC_REG))
3464   ]
3465   "!TARGET_BARREL_SHIFTER"
3466   "* return output_shift (operands);"
3467   [(set_attr "type" "shift")
3468    (set_attr "length" "16,20")])
3470 ; asl, asr, lsr patterns:
3471 ; There is no point in including an 'I' alternative since only the lowest 5
3472 ; bits are used for the shift.  OTOH Cal can be useful if the shift amount
3473 ; is defined in an external symbol, as we don't have special relocations
3474 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3475 ; provide one alternatice for this, without condexec support.
3476 (define_insn "*ashlsi3_insn"
3477   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3478         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3479                    (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3480   "TARGET_BARREL_SHIFTER
3481    && (register_operand (operands[1], SImode)
3482        || register_operand (operands[2], SImode))"
3483   "asl%? %0,%1,%2%&"
3484   [(set_attr "type" "shift")
3485    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3486    (set_attr "predicable" "no,no,no,yes,no,no")
3487    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3489 (define_insn "*ashrsi3_insn"
3490   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3491         (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3492                      (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3493   "TARGET_BARREL_SHIFTER
3494    && (register_operand (operands[1], SImode)
3495        || register_operand (operands[2], SImode))"
3496   "asr%? %0,%1,%2%&"
3497   [(set_attr "type" "shift")
3498    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3499    (set_attr "predicable" "no,no,no,yes,no,no")
3500    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3502 (define_insn "*lshrsi3_insn"
3503   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3504         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3505                      (match_operand:SI 2 "nonmemory_operand"  "N,  N,RcqqM, cL,cL,cCal")))]
3506   "TARGET_BARREL_SHIFTER
3507    && (register_operand (operands[1], SImode)
3508        || register_operand (operands[2], SImode))"
3509   "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3510             ?  \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3511   [(set_attr "type" "shift")
3512    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3513    (set_attr "predicable" "no,no,no,yes,no,no")
3514    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3516 (define_insn "rotrsi3"
3517   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
3518         (rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCal")
3519                      (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3520   "TARGET_BARREL_SHIFTER"
3521   "ror%? %0,%1,%2"
3522   [(set_attr "type" "shift,shift,shift")
3523    (set_attr "predicable" "yes,no,no")
3524    (set_attr "length" "4,4,8")])
3526 ;; Compare / branch instructions.
3528 (define_expand "cbranchsi4"
3529   [(set (reg:CC CC_REG)
3530         (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3531                     (match_operand:SI 2 "nonmemory_operand" "")))
3532    (set (pc)
3533         (if_then_else
3534               (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3535                                                                (const_int 0)])
3536               (label_ref (match_operand 3 "" ""))
3537               (pc)))]
3538   ""
3540   gcc_assert (XEXP (operands[0], 0) == operands[1]);
3541   gcc_assert (XEXP (operands[0], 1) == operands[2]);
3542   operands[0] = gen_compare_reg (operands[0], VOIDmode);
3543   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3544   DONE;
3547 ;; ??? Could add a peephole to generate compare with swapped operands and
3548 ;; modifed cc user if second, but not first operand is a compact register.
3549 (define_insn "cmpsi_cc_insn_mixed"
3550   [(set (reg:CC CC_REG)
3551         (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq,  h, c, c,qRcq,c")
3552                     (match_operand:SI 1 "nonmemory_operand"   "cO,  hO,Cm1,cI,cL, Cal,Cal")))]
3553   ""
3554   "cmp%? %0,%B1%&"
3555   [(set_attr "type" "compare")
3556    (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3557    (set_attr "predicable" "no,no,no,no,yes,no,yes")
3558    (set_attr "cond" "set")
3559    (set_attr "length" "*,*,*,4,4,*,8")
3560    (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3562 (define_insn "*cmpsi_cc_zn_insn"
3563   [(set (reg:CC_ZN CC_REG)
3564         (compare:CC_ZN (match_operand:SI 0 "register_operand"  "qRcq,c")
3565                        (const_int 0)))]
3566   ""
3567   "tst%? %0,%0%&"
3568   [(set_attr "type" "compare,compare")
3569    (set_attr "iscompact" "true,false")
3570    (set_attr "predicable" "no,yes")
3571    (set_attr "cond" "set_zn")
3572    (set_attr "length" "*,4")])
3574 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3575 (define_insn "*btst"
3576   [(set (reg:CC_ZN CC_REG)
3577         (compare:CC_ZN
3578           (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3579                            (const_int 1)
3580                            (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3581           (const_int 0)))]
3582   ""
3583   "btst%? %0,%1"
3584   [(set_attr "iscompact" "true,false")
3585    (set_attr "predicable" "no,yes")
3586    (set_attr "cond" "set")
3587    (set_attr "type" "compare")
3588    (set_attr "length" "*,4")])
3590 ; combine suffers from 'simplifications' that replace a one-bit zero
3591 ; extract with a shift if it can prove that the upper bits are zero.
3592 ; arc_reorg sees the code after sched2, which can have caused our
3593 ; inputs to be clobbered even if they were not clobbered before.
3594 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3595 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3596 ; bbit (i.e. bad scheduling) and missed conditional execution,
3597 ; so make this an option.
3598 (define_peephole2
3599   [(set (reg:CC_ZN CC_REG)
3600         (compare:CC_ZN
3601           (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3602                            (const_int 1)
3603                            (match_operand:SI 1 "nonmemory_operand" ""))
3604           (const_int 0)))
3605    (set (pc)
3606         (if_then_else (match_operator 3 "equality_comparison_operator"
3607                                       [(reg:CC_ZN CC_REG) (const_int 0)])
3608                       (label_ref (match_operand 2 "" ""))
3609                       (pc)))]
3610   "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3611   [(parallel [(set (pc)
3612                    (if_then_else
3613                      (match_op_dup 3
3614                        [(zero_extract:SI (match_dup 0)
3615                                          (const_int 1) (match_dup 1))
3616                         (const_int 0)])
3617                      (label_ref (match_dup 2))
3618                      (pc)))
3619               (clobber (reg:CC_ZN CC_REG))])])
3621 (define_insn "*cmpsi_cc_z_insn"
3622   [(set (reg:CC_Z CC_REG)
3623         (compare:CC_Z (match_operand:SI 0 "register_operand"  "qRcq,c")
3624                       (match_operand:SI 1 "p2_immediate_operand"  "O,n")))]
3625   ""
3626   "@
3627         cmp%? %0,%1%&
3628         bxor.f 0,%0,%z1"
3629   [(set_attr "type" "compare,compare")
3630    (set_attr "iscompact" "true,false")
3631    (set_attr "cond" "set,set_zn")
3632    (set_attr "length" "*,4")])
3634 (define_insn "*cmpsi_cc_c_insn"
3635   [(set (reg:CC_C CC_REG)
3636         (compare:CC_C (match_operand:SI 0 "register_operand"  "Rcqq,Rcqq,  h, c,Rcqq,  c")
3637                       (match_operand:SI 1 "nonmemory_operand"   "cO,  hO,Cm1,cI, Cal,Cal")))]
3638   ""
3639   "cmp%? %0,%S1%&"
3640   [(set_attr "type" "compare")
3641    (set_attr "iscompact" "true,true,true,false,true_limm,false")
3642    (set_attr "cond" "set")
3643    (set_attr "length" "*,*,*,4,*,8")
3644    (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3646 ;; Next come the scc insns.
3648 (define_expand "cstoresi4"
3649   [(set (match_operand:SI 0 "dest_reg_operand" "")
3650         (match_operator:SI 1 "ordered_comparison_operator"
3651                            [(match_operand:SI 2 "nonmemory_operand" "")
3652                             (match_operand:SI 3 "nonmemory_operand" "")]))]
3653   ""
3655   if (!TARGET_CODE_DENSITY)
3656   {
3657    gcc_assert (XEXP (operands[1], 0) == operands[2]);
3658    gcc_assert (XEXP (operands[1], 1) == operands[3]);
3659    operands[1] = gen_compare_reg (operands[1], SImode);
3660    emit_insn (gen_scc_insn (operands[0], operands[1]));
3661    DONE;
3662   }
3663   if (!register_operand (operands[2], SImode))
3664     operands[2] = force_reg (SImode, operands[2]);
3668 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3669                            (DF "TARGET_OPTFPE")])
3671 (define_expand "cstore<mode>4"
3672   [(set (reg:CC CC_REG)
3673         (compare:CC (match_operand:SDF 2 "register_operand" "")
3674                     (match_operand:SDF 3 "register_operand" "")))
3675    (set (match_operand:SI 0 "dest_reg_operand" "")
3676         (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3677                                                     (const_int 0)]))]
3679   "TARGET_FP_SP_BASE || TARGET_OPTFPE"
3681   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3682   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3683   operands[1] = gen_compare_reg (operands[1], SImode);
3684   emit_insn (gen_scc_insn (operands[0], operands[1]));
3685   DONE;
3688 ; We need a separate expander for this lest we loose the mode of CC_REG
3689 ; when match_operator substitutes the literal operand into the comparison.
3690 (define_expand "scc_insn"
3691   [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3693 (define_insn_and_split "*scc_insn"
3694   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3695         (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3696   ""
3697   "#"
3698   "reload_completed"
3699   [(set (match_dup 0) (const_int 1))
3700    (cond_exec
3701      (match_dup 1)
3702      (set (match_dup 0) (const_int 0)))]
3704   operands[1]
3705     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3706                                          GET_MODE (XEXP (operands[1], 0))),
3707                       VOIDmode,
3708                       XEXP (operands[1], 0), XEXP (operands[1], 1));
3710   [(set_attr "type" "unary")])
3712 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3713 ;; that is one lower if the carry flag is set.
3715 ;; ??? Look up negscc insn.  See pa.md for example.
3716 (define_insn "*neg_scc_insn"
3717   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3718         (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3719                  [(reg CC_REG) (const_int 0)])))]
3720   ""
3721   "mov %0,-1\;sub.%D1 %0,%0,%0"
3722   [(set_attr "type" "unary")
3723    (set_attr "length" "8")])
3725 (define_insn "*not_scc_insn"
3726   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3727         (not:SI (match_operator:SI 1 "proper_comparison_operator"
3728                  [(reg CC_REG) (const_int 0)])))]
3729   ""
3730   "mov %0,1\;sub.%d1 %0,%0,%0"
3731   [(set_attr "type" "unary")
3732    (set_attr "length" "8")])
3734 ; cond_exec patterns
3735 (define_insn "*movsi_ne"
3736   [(cond_exec
3737      (ne (match_operand:CC_Z 2 "cc_use_register"    "Rcc,  Rcc,  Rcc,Rcc,Rcc") (const_int 0))
3738      (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q,  w,w")
3739           (match_operand:SI 1 "nonmemory_operand"   "C_0,    h, ?Cal, Lc,?Cal")))]
3740   ""
3741   "@
3742         * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3743         * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3744         * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3745         mov.ne %0,%1
3746         mov.ne %0,%S1"
3747   [(set_attr "type" "cmove")
3748    (set_attr "iscompact" "true,true,true_limm,false,false")
3749    (set_attr "length" "2,2,6,4,8")
3750    (set_attr "cpu_facility" "*,av2,av2,*,*")])
3752 (define_insn "*movsi_cond_exec"
3753   [(cond_exec
3754      (match_operator 3 "proper_comparison_operator"
3755        [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3756      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3757           (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3758   ""
3759   "mov.%d3 %0,%S1"
3760   [(set_attr "type" "cmove")
3761    (set_attr "length" "4,8")])
3763 (define_insn "*commutative_cond_exec"
3764   [(cond_exec
3765      (match_operator 5 "proper_comparison_operator"
3766        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3767      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3768           (match_operator:SI 3 "commutative_operator"
3769             [(match_operand:SI 1 "register_operand" "%0,0")
3770              (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3771   ""
3773   arc_output_commutative_cond_exec (operands, true);
3774   return "";
3776   [(set_attr "cond" "use")
3777    (set_attr "type" "cmove")
3778    (set_attr_alternative "length"
3779      [(const_int 4)
3780       (cond
3781         [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3782              (const_int 4))
3783          (const_int 4)]
3784         (const_int 8))])])
3786 (define_insn "*sub_cond_exec"
3787   [(cond_exec
3788      (match_operator 4 "proper_comparison_operator"
3789        [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3790      (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3791           (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3792                     (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3793   ""
3794   "@
3795         sub.%d4 %0,%1,%2
3796         rsub.%d4 %0,%2,%1
3797         rsub.%d4 %0,%2,%1"
3798   [(set_attr "cond" "use")
3799    (set_attr "type" "cmove")
3800    (set_attr "length" "4,4,8")])
3802 (define_insn "*noncommutative_cond_exec"
3803   [(cond_exec
3804      (match_operator 5 "proper_comparison_operator"
3805        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3806      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3807           (match_operator:SI 3 "noncommutative_operator"
3808             [(match_operand:SI 1 "register_operand" "0,0")
3809              (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3810   ""
3811   "%O3.%d5 %0,%1,%2"
3812   [(set_attr "cond" "use")
3813    (set_attr "type" "cmove")
3814    (set_attr "length" "4,8")])
3816 ;; These control RTL generation for conditional jump insns
3817 ;; Match both normal and inverted jump.
3819 ; We need a separate expander for this lest we loose the mode of CC_REG
3820 ; when match_operator substitutes the literal operand into the comparison.
3821 (define_expand "branch_insn"
3822   [(set (pc)
3823         (if_then_else (match_operand 1 "" "")
3824                       (label_ref (match_operand 0 "" ""))
3825                       (pc)))])
3827 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3828 ; are three reasons why we need to consider branches to be length 6:
3829 ; - annull-false delay slot insns are implemented using conditional execution,
3830 ;   thus preventing short insn formation where used.
3831 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3832 ;   using conditional execution, preventing short insn formation where used.
3833 ; - for ARC700: likely or somewhat likely taken branches are made long and
3834 ;   unaligned if possible to avoid branch penalty.
3835 (define_insn "*branch_insn"
3836   [(set (pc)
3837         (if_then_else (match_operator 1 "proper_comparison_operator"
3838                                       [(reg CC_REG) (const_int 0)])
3839                       (label_ref (match_operand 0 "" ""))
3840                       (pc)))]
3841   ""
3842   "*
3844   if (arc_ccfsm_branch_deleted_p ())
3845     {
3846       arc_ccfsm_record_branch_deleted ();
3847       return \"; branch deleted, next insns conditionalized\";
3848     }
3849   else
3850     {
3851       arc_ccfsm_record_condition (operands[1], false, insn, 0);
3852       if (get_attr_length (insn) == 2)
3853          return \"b%d1%? %^%l0%&\";
3854       else
3855          return \"b%d1%# %^%l0\";
3856     }
3858   [(set_attr "type" "branch")
3859    (set
3860      (attr "length")
3861      (cond [
3862        (eq_attr "delay_slot_filled" "yes")
3863        (const_int 4)
3865        (ne
3866          (if_then_else
3867            (match_operand 1 "equality_comparison_operator" "")
3868            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3869                 (gt (minus (match_dup 0) (pc))
3870                     (minus (const_int 506)
3871                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3872            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3873                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3874                 (gt (minus (match_dup 0) (pc))
3875                     (minus (const_int 58)
3876                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3877          (const_int 0))
3878        (const_int 4)]
3879       (const_int 2)))
3881    (set (attr "iscompact")
3882         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3883               (const_string "false")))])
3885 (define_insn "*rev_branch_insn"
3886   [(set (pc)
3887         (if_then_else (match_operator 1 "proper_comparison_operator"
3888                                       [(reg CC_REG) (const_int 0)])
3889                       (pc)
3890                       (label_ref (match_operand 0 "" ""))))]
3891   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3892   "*
3894   if (arc_ccfsm_branch_deleted_p ())
3895     {
3896       arc_ccfsm_record_branch_deleted ();
3897       return \"; branch deleted, next insns conditionalized\";
3898     }
3899   else
3900     {
3901       arc_ccfsm_record_condition (operands[1], true, insn, 0);
3902       if (get_attr_length (insn) == 2)
3903          return \"b%D1%? %^%l0\";
3904       else
3905          return \"b%D1%# %^%l0\";
3906     }
3908   [(set_attr "type" "branch")
3909    (set
3910      (attr "length")
3911      (cond [
3912        (eq_attr "delay_slot_filled" "yes")
3913        (const_int 4)
3915        (ne
3916          (if_then_else
3917            (match_operand 1 "equality_comparison_operator" "")
3918            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3919                 (gt (minus (match_dup 0) (pc))
3920                     (minus (const_int 506)
3921                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3922            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3923                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3924                 (gt (minus (match_dup 0) (pc))
3925                     (minus (const_int 58)
3926                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3927          (const_int 0))
3928        (const_int 4)]
3929       (const_int 2)))
3931    (set (attr "iscompact")
3932         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3933               (const_string "false")))])
3935 ;; Unconditional and other jump instructions.
3937 (define_expand "jump"
3938   [(set (pc) (label_ref (match_operand 0 "" "")))]
3939   ""
3940   "")
3942 (define_insn "jump_i"
3943   [(set (pc) (label_ref (match_operand 0 "" "")))]
3944   "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3945   "b%!%* %^%l0%&"
3946   [(set_attr "type" "uncond_branch")
3947    (set (attr "iscompact")
3948         (if_then_else (match_test "get_attr_length (insn) == 2")
3949                       (const_string "true") (const_string "false")))
3950    (set_attr "cond" "canuse")
3951    (set (attr "length")
3952         (cond [
3953           ; In arc_reorg we just guesstimate; might be more or less than 4.
3954           (match_test "arc_branch_size_unknown_p ()")
3955           (const_int 4)
3957           (eq_attr "delay_slot_filled" "yes")
3958           (const_int 4)
3960           (match_test "CROSSING_JUMP_P (insn)")
3961           (const_int 4)
3963           (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3964                (gt (minus (match_dup 0) (pc))
3965                    (minus (const_int 506)
3966                           (symbol_ref "get_attr_delay_slot_length (insn)"))))
3967           (const_int 4)]
3968          (const_int 2)))])
3970 (define_insn "indirect_jump"
3971   [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3972   ""
3973   "@
3974    j%!%* %0%&
3975    j%!%* %0%&
3976    j%!%* %0%&
3977    j%!%* [%0]%&
3978    j%!%* [%0]%&"
3979   [(set_attr "type" "jump")
3980    (set_attr "iscompact" "false,false,false,maybe,false")
3981    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3983 ;; Implement a switch statement.
3985 (define_expand "casesi"
3986   [(set (match_dup 5)
3987         (minus:SI (match_operand:SI 0 "register_operand" "")
3988                   (match_operand:SI 1 "nonmemory_operand" "")))
3989    (set (reg:CC CC_REG)
3990         (compare:CC (match_dup 5)
3991                     (match_operand:SI 2 "nonmemory_operand" "")))
3992    (set (pc)
3993         (if_then_else (gtu (reg:CC CC_REG)
3994                            (const_int 0))
3995                       (label_ref (match_operand 4 "" ""))
3996                       (pc)))
3997    (set (match_dup 6)
3998         (unspec:SI [(match_operand 3 "" "")
3999                     (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
4000    (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
4001   ""
4002   "
4004   rtx x;
4006   operands[5] = gen_reg_rtx (SImode);
4007   operands[6] = gen_reg_rtx (SImode);
4008   operands[7] = operands[3];
4009   emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4010   emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4011   x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4012   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4013                             gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4014   emit_jump_insn (gen_rtx_SET (pc_rtx, x));
4015   if (TARGET_COMPACT_CASESI)
4016     {
4017       emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4018     }
4019   else
4020     {
4021       operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4022       if (flag_pic || !cse_not_expected)
4023         operands[3] = force_reg (Pmode, operands[3]);
4024       emit_insn (gen_casesi_load (operands[6],
4025                                   operands[3], operands[5], operands[7]));
4026       if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4027         emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4028       emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4029     }
4030   DONE;
4033 (define_insn "casesi_load"
4034   [(set (match_operand:SI 0 "register_operand"             "=Rcq,r,r")
4035         (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4036                     (match_operand:SI 2 "register_operand"  "Rcq,c,c")
4037                     (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
4038   ""
4039   "*
4041   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4043   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4044     {
4045       gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4046       gcc_assert (GET_MODE (diff_vec) == SImode);
4047       gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4048     }
4050   switch (GET_MODE (diff_vec))
4051     {
4052     case E_SImode:
4053       return \"ld.as %0,[%1,%2]%&\";
4054     case E_HImode:
4055       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4056         return \"ld%_.as %0,[%1,%2]\";
4057       return \"ld%_.x.as %0,[%1,%2]\";
4058     case E_QImode:
4059       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4060         return \"ldb%? %0,[%1,%2]%&\";
4061       return \"ldb.x %0,[%1,%2]\";
4062     default:
4063       gcc_unreachable ();
4064     }
4066   [(set_attr "type" "load")
4067    (set_attr_alternative "iscompact"
4068      [(cond
4069         [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4070                                                (as_a<rtx_insn *> (operands[3]))))")
4071              (symbol_ref "QImode"))
4072          (const_string "false")
4073          (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4074                                                        (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4075          (const_string "false")]
4076         (const_string "true"))
4077       (const_string "false")
4078       (const_string "false")])
4079    (set_attr_alternative "length"
4080      [(cond
4081         [(eq_attr "iscompact" "false") (const_int 4)
4082         ; We have to mention (match_dup 3) to convince genattrtab.c that this
4083         ; is a varying length insn.
4084          (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4085          (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4086         (const_int 2))
4087       (const_int 4)
4088       (const_int 8)])])
4090 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4091 ; even for CASE_VECTOR_PC_RELATIVE.
4092 (define_insn "casesi_jump"
4093   [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4094    (use (label_ref (match_operand 1 "" "")))]
4095   ""
4096   "j%!%* [%0]%&"
4097   [(set_attr "type" "jump")
4098    (set_attr "iscompact" "false,maybe,false")
4099    (set_attr "cond" "canuse")])
4101 (define_insn "casesi_compact_jump"
4102   [(set (pc)
4103         (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4104                    UNSPEC_ARC_CASESI))
4105    (use (label_ref (match_operand 1 "" "")))
4106    (clobber (match_scratch:SI 2 "=q,0"))]
4107   "TARGET_COMPACT_CASESI"
4108   "*
4110   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4111   int unalign = arc_get_unalign ();
4112   rtx xop[3];
4113   const char *s;
4115   xop[0] = operands[0];
4116   xop[2] = operands[2];
4117   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4119   switch (GET_MODE (diff_vec))
4120     {
4121     case E_SImode:
4122       /* Max length can be 12 in this case, but this is OK because
4123          2 of these are for alignment, and are anticipated in the length
4124          of the ADDR_DIFF_VEC.  */
4125       if (unalign && !satisfies_constraint_Rcq (xop[0]))
4126         s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
4127       else if (unalign)
4128         s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4129       else
4130         s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4131       arc_clear_unalign ();
4132       break;
4133     case E_HImode:
4134       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4135         {
4136           if (satisfies_constraint_Rcq (xop[0]))
4137             {
4138               s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
4139               xop[1] = GEN_INT ((10 - unalign) / 2U);
4140             }
4141           else
4142             {
4143               s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
4144               xop[1] = GEN_INT (10 + unalign);
4145             }
4146         }
4147       else
4148         {
4149           if (satisfies_constraint_Rcq (xop[0]))
4150             {
4151               s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
4152               xop[1] = GEN_INT ((10 - unalign) / 2U);
4153             }
4154           else
4155             {
4156               s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
4157               xop[1] = GEN_INT (10 + unalign);
4158             }
4159         }
4160       arc_toggle_unalign ();
4161       break;
4162     case E_QImode:
4163       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4164         {
4165           if ((rtx_equal_p (xop[2], xop[0])
4166                || find_reg_note (insn, REG_DEAD, xop[0]))
4167               && satisfies_constraint_Rcq (xop[0]))
4168             {
4169               s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4170               xop[1] = GEN_INT (8 + unalign);
4171             }
4172           else
4173             {
4174               s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4175               xop[1] = GEN_INT (10 + unalign);
4176               arc_toggle_unalign ();
4177             }
4178         }
4179       else if ((rtx_equal_p (xop[0], xop[2])
4180                 || find_reg_note (insn, REG_DEAD, xop[0]))
4181                && satisfies_constraint_Rcq (xop[0]))
4182         {
4183           s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4184           xop[1] = GEN_INT (10 - unalign);
4185           arc_toggle_unalign ();
4186         }
4187       else
4188         {
4189           /* ??? Length is 12.  */
4190           s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4191           xop[1] = GEN_INT (8 + unalign);
4192         }
4193       break;
4194     default:
4195       gcc_unreachable ();
4196     }
4197   output_asm_insn (s, xop);
4198   return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4200   [(set_attr "length" "10")
4201    (set_attr "type" "jump")
4202    (set_attr "iscompact" "true")
4203    (set_attr "cond" "nocond")])
4205 (define_expand "call"
4206   ;; operands[1] is stack_size_rtx
4207   ;; operands[2] is next_arg_register
4208   [(parallel [(call (match_operand:SI 0 "call_operand" "")
4209                     (match_operand 1 "" ""))
4210              (clobber (reg:SI 31))])]
4211   ""
4212   "{
4213     rtx callee;
4215     gcc_assert (MEM_P (operands[0]));
4216     callee  = XEXP (operands[0], 0);
4217     /* This is to decide if we should generate indirect calls by loading the
4218        32 bit address of the callee into a register before performing the
4219        branch and link - this exposes cse opportunities.
4220        Also, in weird cases like compile/20010107-1.c, we may get a PLUS.  */
4221     if (GET_CODE (callee) != REG
4222         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4223       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4224   }
4228 ; Rcq, which is used in alternative 0, checks for conditional execution.
4229 ; At instruction output time, if it doesn't match and we end up with
4230 ; alternative 1 ("q"), that means that we can't use the short form.
4231 (define_insn "*call_i"
4232   [(call (mem:SI (match_operand:SI 0
4233                   "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4234          (match_operand 1 "" ""))
4235    (clobber (reg:SI 31))]
4236   ""
4237   "@
4238    jl%!%* [%0]%&
4239    jl%!%* [%0]%&
4240    jl%!%* [%0]
4241    bl%!%* %P0
4242    bl%!%* %P0
4243    jl%!%* %S0
4244    jl%* %S0
4245    jl%! %S0"
4246   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4247    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4248    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4249    (set_attr "length" "*,*,4,4,4,4,4,8")])
4251 (define_expand "call_value"
4252   ;; operand 2 is stack_size_rtx
4253   ;; operand 3 is next_arg_register
4254   [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4255                    (call (match_operand:SI 1 "call_operand" "")
4256                          (match_operand 2 "" "")))
4257              (clobber (reg:SI 31))])]
4258   ""
4259   "
4260   {
4261     rtx callee;
4263     gcc_assert (MEM_P (operands[1]));
4264     callee = XEXP (operands[1], 0);
4265      /* See the comment in define_expand \"call\".  */
4266     if (GET_CODE (callee) != REG
4267         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4268       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4269   }")
4272 ; Rcq, which is used in alternative 0, checks for conditional execution.
4273 ; At instruction output time, if it doesn't match and we end up with
4274 ; alternative 1 ("q"), that means that we can't use the short form.
4275 (define_insn "*call_value_i"
4276   [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,w,w,  w")
4277         (call (mem:SI (match_operand:SI 1
4278                        "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4279               (match_operand 2 "" "")))
4280    (clobber (reg:SI 31))]
4281   ""
4282   "@
4283    jl%!%* [%1]%&
4284    jl%!%* [%1]%&
4285    jl%!%* [%1]
4286    bl%!%* %P1;1
4287    bl%!%* %P1;1
4288    jl%!%* %S1
4289    jl%* %S1
4290    jl%! %S1"
4291   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4292    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4293    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4294    (set_attr "length" "*,*,4,4,4,4,4,8")])
4296 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4297 ; use it for lack of inter-procedural branch shortening.
4298 ; Link-time relaxation would help...
4300 (define_insn "nop"
4301   [(const_int 0)]
4302   ""
4303   "nop%?"
4304   [(set_attr "type" "misc")
4305    (set_attr "iscompact" "true")
4306    (set_attr "cond" "canuse")
4307    (set_attr "length" "2")])
4309 (define_insn "nopv"
4310   [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4311   ""
4312   "nop%?"
4313   [(set_attr "type" "misc")
4314    (set_attr "iscompact" "true")
4315    (set_attr "length" "2")])
4317 ;; Special pattern to flush the icache.
4318 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
4320 (define_insn "flush_icache"
4321   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4322   ""
4323   "* return \"\";"
4324   [(set_attr "type" "misc")])
4326 ;; Split up troublesome insns for better scheduling.
4328 ;; Peepholes go at the end.
4329 ;;asl followed by add can be replaced by an add{1,2,3}
4330 ;; Three define_peepholes have been added for this optimization
4331 ;; ??? This used to target non-canonical rtl.  Now we use add_n, which
4332 ;; can be generated by combine.  Check if these peepholes still provide
4333 ;; any benefit.
4335 ;; -------------------------------------------------------------
4336 ;; Pattern 1 : r0 = r1 << {i}
4337 ;;             r3 = r4/INT + r0     ;;and commutative
4338 ;;                 ||
4339 ;;                 \/
4340 ;;             add{i} r3,r4/INT,r1
4341 ;; -------------------------------------------------------------
4342 ;; ??? This should be covered by combine, alas, at times combine gets
4343 ;; too clever for it's own good: when the shifted input is known to be
4344 ;; either 0 or 1, the operation will be made into an if-then-else, and
4345 ;; thus fail to match the add_n pattern.  Example: _mktm_r, line 85 in
4346 ;; newlib/libc/time/mktm_r.c .
4348 (define_peephole2
4349   [(set (match_operand:SI 0 "dest_reg_operand" "")
4350         (ashift:SI (match_operand:SI 1 "register_operand" "")
4351                    (match_operand:SI 2 "const_int_operand" "")))
4352   (set (match_operand:SI 3 "dest_reg_operand" "")
4353        (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4354                 (match_operand:SI 5 "nonmemory_operand" "")))]
4355   "(INTVAL (operands[2]) == 1
4356     || INTVAL (operands[2]) == 2
4357     || INTVAL (operands[2]) == 3)
4358    && (true_regnum (operands[4]) == true_regnum (operands[0])
4359        || true_regnum (operands[5]) == true_regnum (operands[0]))
4360    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4361  ;; the preparation statements take care to put proper operand in operands[4]
4362  ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4363   [(set (match_dup 3)
4364         (plus:SI (mult:SI (match_dup 1)
4365                           (match_dup 2))
4366                  (match_dup 4)))]
4367   "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4368       operands[4] = operands[5];
4369    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4372 ;; -------------------------------------------------------------
4373 ;; Pattern 1 : r0 = r1 << {i}
4374 ;;             r3 = r4 - r0
4375 ;;                 ||
4376 ;;                 \/
4377 ;;             sub{i} r3,r4,r1
4378 ;; -------------------------------------------------------------
4379 ;; ??? This should be covered by combine, alas, at times combine gets
4380 ;; too clever for it's own good: when the shifted input is known to be
4381 ;; either 0 or 1, the operation will be made into an if-then-else, and
4382 ;; thus fail to match the sub_n pattern.  Example: __ieee754_yn, line 239 in
4383 ;; newlib/libm/math/e_jn.c .
4385 (define_peephole2
4386   [(set (match_operand:SI 0 "dest_reg_operand" "")
4387         (ashift:SI (match_operand:SI 1 "register_operand" "")
4388                    (match_operand:SI 2 "const_int_operand" "")))
4389    (set (match_operand:SI 3 "dest_reg_operand" "")
4390         (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4391                   (match_dup 0)))]
4392   "(INTVAL (operands[2]) == 1
4393     || INTVAL (operands[2]) == 2
4394     || INTVAL (operands[2]) == 3)
4395    && (peep2_reg_dead_p (2, operands[0])
4396        || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4397   [(set (match_dup 3)
4398         (minus:SI (match_dup 4)
4399                   (mult:SI (match_dup 1)
4400                            (match_dup 2))))]
4401   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4406 ; When using the high single bit, the result of a multiply is either
4407 ; the original number or zero.  But MPY costs 4 cycles, which we
4408 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4409 (define_peephole2
4410   [(set (match_operand:SI 0 "dest_reg_operand" "")
4411         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4412                      (const_int 31)))
4413    (set (match_operand:SI 4 "register_operand" "")
4414         (mult:SI (match_operand:SI 2 "register_operand")
4415                  (match_operand:SI 3 "nonmemory_operand" "")))]
4416   "TARGET_ARC700_MPY
4417    && (rtx_equal_p (operands[0], operands[2])
4418        || rtx_equal_p (operands[0], operands[3]))
4419    && peep2_regno_dead_p (0, CC_REG)
4420    && (rtx_equal_p (operands[0], operands[4])
4421        || (peep2_reg_dead_p (2, operands[0])
4422           && peep2_reg_dead_p (1, operands[4])))"
4423   [(parallel [(set (reg:CC_Z CC_REG)
4424                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4425                                  (const_int 0)))
4426               (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4427    (cond_exec
4428      (ne (reg:CC_Z CC_REG) (const_int 0))
4429      (set (match_dup 4) (match_dup 5)))]
4431   if (!rtx_equal_p (operands[0], operands[2]))
4432     operands[5] = operands[2];
4433   else if (!rtx_equal_p (operands[0], operands[3]))
4434     operands[5] = operands[3];
4435   else
4436     operands[5] = operands[4]; /* Actually a no-op... presumably rare.  */
4439 (define_peephole2
4440   [(set (match_operand:SI 0 "dest_reg_operand" "")
4441         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4442                      (const_int 31)))
4443    (set (match_operand:SI 4 "register_operand" "")
4444         (mult:SI (match_operand:SI 2 "register_operand")
4445                  (match_operand:SI 3 "nonmemory_operand" "")))]
4446   "TARGET_ARC700_MPY
4447    && (rtx_equal_p (operands[0], operands[2])
4448        || rtx_equal_p (operands[0], operands[3]))
4449    && peep2_regno_dead_p (2, CC_REG)"
4450   [(parallel [(set (reg:CC_Z CC_REG)
4451                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4452                                  (const_int 0)))
4453               (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4454    (set (match_dup 4) (match_dup 5))
4455    (cond_exec
4456      (eq (reg:CC_Z CC_REG) (const_int 0))
4457      (set (match_dup 4) (const_int 0)))]
4458  "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4460 ;; Instructions generated through builtins
4462 (define_insn "clrsbsi2"
4463   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4464         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4465   "TARGET_NORM"
4466   "@
4467    norm \t%0, %1
4468    norm \t%0, %S1"
4469   [(set_attr "length" "4,8")
4470    (set_attr "type" "two_cycle_core,two_cycle_core")])
4472 (define_insn "norm_f"
4473   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4474         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4475    (set (reg:CC_ZN CC_REG)
4476         (compare:CC_ZN (match_dup 1) (const_int 0)))]
4477   "TARGET_NORM"
4478   "@
4479    norm.f\t%0, %1
4480    norm.f\t%0, %S1"
4481   [(set_attr "length" "4,8")
4482    (set_attr "type" "two_cycle_core,two_cycle_core")])
4484 (define_insn_and_split "clrsbhi2"
4485   [(set (match_operand:HI  0 "dest_reg_operand" "=w,w")
4486         (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4487   "TARGET_NORM"
4488   "#"
4489   "reload_completed"
4490   [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4491   "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4493 (define_insn "normw"
4494   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4495         (zero_extend:SI
4496           (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4497   "TARGET_NORM"
4498   "@
4499    norm%_ \t%0, %1
4500    norm%_ \t%0, %S1"
4501   [(set_attr "length" "4,8")
4502    (set_attr "type" "two_cycle_core,two_cycle_core")])
4504 (define_expand "clzsi2"
4505   [(parallel
4506     [(set (match_operand:SI 0 "register_operand" "")
4507           (clz:SI (match_operand:SI 1 "register_operand" "")))
4508      (clobber (match_dup 2))])]
4509   "TARGET_NORM"
4510   "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);")
4512 (define_insn_and_split "*arc_clzsi2"
4513   [(set (match_operand:SI 0 "register_operand" "=r")
4514         (clz:SI (match_operand:SI 1 "register_operand" "r")))
4515    (clobber (reg:CC_ZN CC_REG))]
4516   "TARGET_NORM"
4517   "#"
4518   "reload_completed"
4519   [(const_int 0)]
4521   emit_insn (gen_norm_f (operands[0], operands[1]));
4522   emit_insn
4523     (gen_rtx_COND_EXEC
4524       (VOIDmode,
4525        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4526        gen_rtx_SET (operands[0], const0_rtx)));
4527   emit_insn
4528     (gen_rtx_COND_EXEC
4529       (VOIDmode,
4530        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4531        gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4532   DONE;
4534 [(set_attr "type" "unary")
4535  (set_attr "length" "12")])
4537 (define_expand "ctzsi2"
4538   [(match_operand:SI 0 "register_operand" "")
4539    (match_operand:SI 1 "register_operand" "")]
4540   "TARGET_NORM"
4541   "
4542   emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4543   DONE;
4546 (define_insn_and_split "arc_ctzsi2"
4547   [(set (match_operand:SI 0 "register_operand" "=r")
4548         (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4549    (clobber (reg:CC_ZN CC_REG))
4550    (clobber (match_scratch:SI 2 "=&r"))]
4551   "TARGET_NORM"
4552   "#"
4553   "reload_completed"
4554   [(const_int 0)]
4556   rtx temp = operands[0];
4558   if (reg_overlap_mentioned_p (temp, operands[1])
4559       || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4560           && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4561                                  REGNO (temp))))
4562     temp = operands[2];
4563   emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4564   emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4565   emit_insn (gen_clrsbsi2 (operands[0], temp));
4566   emit_insn
4567     (gen_rtx_COND_EXEC
4568       (VOIDmode,
4569        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4570        gen_rtx_SET (operands[0], GEN_INT (32))));
4571   emit_insn
4572     (gen_rtx_COND_EXEC
4573       (VOIDmode,
4574        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4575        gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4576                                                 operands[0]))));
4577   DONE;
4579 [(set_attr "type" "unary")
4580  (set_attr "length" "20")])
4582 (define_insn "swap"
4583   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
4584         (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4585                             UNSPEC_ARC_SWAP))]
4586   "TARGET_SWAP"
4587   "@
4588    swap \t%0, %1
4589    swap \t%0, %S1
4590    swap \t%0, %1"
4591   [(set_attr "length" "4,8,4")
4592    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4594 (define_insn "divaw"
4595   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4596                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4597                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4598                                            UNSPEC_ARC_DIVAW))]
4599   "TARGET_ARC700 || TARGET_EA_SET"
4600   "@
4601    divaw \t%0, %1, %2
4602    divaw \t%0, %S1, %2
4603    divaw \t%0, %1, %S2"
4604   [(set_attr "length" "4,8,8")
4605    (set_attr "type" "divaw,divaw,divaw")])
4607 (define_insn "flag"
4608   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4609                    VUNSPEC_ARC_FLAG)]
4610   ""
4611   "@
4612     flag%? %0
4613     flag %0
4614     flag%? %S0"
4615   [(set_attr "length" "4,4,8")
4616    (set_attr "type" "misc,misc,misc")
4617    (set_attr "predicable" "yes,no,yes")
4618    (set_attr "cond" "clob,clob,clob")])
4620 (define_insn "brk"
4621   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4622                    VUNSPEC_ARC_BRK)]
4623   ""
4624   "brk"
4625   [(set_attr "length" "4")
4626   (set_attr "type" "misc")])
4628 (define_insn "rtie"
4629   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4630                    VUNSPEC_ARC_RTIE)]
4631   ""
4632   "rtie"
4633   [(set_attr "length" "4")
4634   (set_attr "type" "misc")
4635   (set_attr "cond" "clob")])
4637 (define_insn "sync"
4638   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4639                    VUNSPEC_ARC_SYNC)]
4640   ""
4641   "sync"
4642   [(set_attr "length" "4")
4643   (set_attr "type" "misc")])
4645 (define_insn "swi"
4646   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4647                    VUNSPEC_ARC_SWI)]
4648   ""
4649   "*
4651     if(TARGET_ARC700)
4652         return \"trap0\";
4653     else
4654         return \"swi\";
4656   [(set_attr "length" "4")
4657   (set_attr "type" "misc")])
4660 (define_insn "sleep"
4661   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4662                    VUNSPEC_ARC_SLEEP)]
4663   "check_if_valid_sleep_operand(operands,0)"
4664   "sleep %0"
4665   [(set_attr "length" "4")
4666   (set_attr "type" "misc")])
4668 (define_insn "core_read"
4669   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4670         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4671                             VUNSPEC_ARC_CORE_READ))]
4672   ""
4673   "*
4674     if (check_if_valid_regno_const (operands, 1))
4675       return \"mov \t%0, r%1\";
4676     return \"mov \t%0, r%1\";
4677   "
4678   [(set_attr "length" "4")
4679    (set_attr "type" "unary")])
4681 (define_insn "core_write"
4682   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4683                      (match_operand:SI 1 "general_operand" "Hn,!r")]
4684                    VUNSPEC_ARC_CORE_WRITE)]
4685   ""
4686   "*
4687     if (check_if_valid_regno_const (operands, 1))
4688       return \"mov \tr%1, %0\";
4689     return \"mov \tr%1, %0\";
4690   "
4691   [(set_attr "length" "4")
4692    (set_attr "type" "unary")])
4694 (define_insn "lr"
4695   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
4696         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4697                             VUNSPEC_ARC_LR))]
4698   ""
4699   "lr\t%0, [%1]"
4700   [(set_attr "length" "4,8,4,8")
4701    (set_attr "type" "lr,lr,lr,lr")])
4703 (define_insn "sr"
4704   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4705                      (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4706                    VUNSPEC_ARC_SR)]
4707   ""
4708   "sr\t%S0, [%1]"
4709   [(set_attr "length" "8,4,8,4")
4710    (set_attr "type" "sr,sr,sr,sr")])
4712 (define_insn "trap_s"
4713   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4714                    VUNSPEC_ARC_TRAP_S)]
4715   "!TARGET_ARC600_FAMILY"
4717   if (which_alternative == 0)
4718     {
4719       arc_toggle_unalign ();
4720       return \"trap_s %0\";
4721     }
4723   /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4724      because *.md files do not get scanned by exgettext.  */
4725   fatal_error (input_location,
4726                \"operand to trap_s should be an unsigned 6-bit value\");
4728   [(set_attr "length" "2")
4729   (set_attr "type" "misc")])
4731 (define_insn "unimp_s"
4732   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4733                    VUNSPEC_ARC_UNIMP_S)]
4734   "!TARGET_ARC600_FAMILY"
4735   "unimp_s"
4736   [(set_attr "length" "4")
4737   (set_attr "type" "misc")])
4739 ;; End of instructions generated through builtins
4741 ; Since the demise of REG_N_SETS as reliable data readily available to the
4742 ; target, it is no longer possible to find out
4743 ; in the prologue / epilogue expanders how many times blink is set.
4744 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4745 ; any explicit use of blink will cause it to be saved; hence we cannot
4746 ; represent the blink use in return / sibcall instructions themselves, and
4747 ; instead have to show it in EPILOGUE_USES and must explicitly
4748 ; forbid instructions that change blink in the return / sibcall delay slot.
4749 (define_expand "sibcall"
4750   [(parallel [(call (match_operand 0 "memory_operand" "")
4751                     (match_operand 1 "general_operand" ""))
4752               (simple_return)
4753               (use (match_operand 2 "" ""))])]
4754   ""
4755   "
4756   {
4757     rtx callee = XEXP (operands[0], 0);
4759     if (operands[2] == NULL_RTX)
4760       operands[2] = const0_rtx;
4761     if (GET_CODE (callee) != REG
4762         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4763       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4764   }"
4767 (define_expand "sibcall_value"
4768   [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4769                    (call (match_operand 1 "memory_operand" "")
4770                          (match_operand 2 "general_operand" "")))
4771               (simple_return)
4772               (use (match_operand 3 "" ""))])]
4773   ""
4774   "
4775   {
4776     rtx callee = XEXP (operands[1], 0);
4778     if (operands[3] == NULL_RTX)
4779       operands[3] = const0_rtx;
4780     if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4781       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4782   }"
4785 (define_insn "*sibcall_insn"
4786  [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4787                  "Cbp,Cbr,Rs5,Rsc,Cal"))
4788         (match_operand 1 "" ""))
4789   (simple_return)
4790   (use (match_operand 2 "" ""))]
4791   ""
4792   "@
4793    b%!%* %P0
4794    b%!%* %P0
4795    j%!%* [%0]%&
4796    j%!%* [%0]
4797    j%! %P0"
4798   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4799    (set_attr "predicable" "yes,no,no,yes,yes")
4800    (set_attr "iscompact" "false,false,maybe,false,false")
4801    (set_attr "is_SIBCALL" "yes")]
4804 (define_insn "*sibcall_value_insn"
4805  [(set (match_operand 0 "dest_reg_operand" "")
4806        (call (mem:SI (match_operand:SI 1 "call_address_operand"
4807               "Cbp,Cbr,Rs5,Rsc,Cal"))
4808              (match_operand 2 "" "")))
4809   (simple_return)
4810   (use (match_operand 3 "" ""))]
4811   ""
4812   "@
4813    b%!%* %P1
4814    b%!%* %P1
4815    j%!%* [%1]%&
4816    j%!%* [%1]
4817    j%! %P1"
4818   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4819    (set_attr "predicable" "yes,no,no,yes,yes")
4820    (set_attr "iscompact" "false,false,maybe,false,false")
4821    (set_attr "is_SIBCALL" "yes")]
4824 (define_expand "prologue"
4825   [(pc)]
4826   ""
4828   arc_expand_prologue ();
4829   DONE;
4832 (define_expand "epilogue"
4833   [(pc)]
4834   ""
4836   arc_expand_epilogue (0);
4837   DONE;
4840 (define_expand "sibcall_epilogue"
4841   [(pc)]
4842   ""
4844   arc_expand_epilogue (1);
4845   DONE;
4848 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4849 ; in the prologue / epilogue expanders how many times blink is set.
4850 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4851 ; any explicit use of blink will cause it to be saved; hence we cannot
4852 ; represent the blink use in return / sibcall instructions themselves, and
4853 ; instead have to show it in EPILOGUE_USES and must explicitly
4854 ; forbid instructions that change blink in the return / sibcall delay slot.
4855 (define_insn "simple_return"
4856   [(simple_return)]
4857   "reload_completed"
4859   rtx reg
4860     = gen_rtx_REG (Pmode,
4861                    arc_return_address_register (arc_compute_function_type
4862                                                 (cfun)));
4864   if (TARGET_V2
4865       && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
4866   {
4867     return \"rtie\";
4868   }
4869   if (TARGET_PAD_RETURN)
4870     arc_pad_return ();
4871   output_asm_insn (\"j%!%* [%0]%&\", &reg);
4872   return \"\";
4874   [(set (attr "type")
4875         (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))")
4876                     (match_test "TARGET_V2"))
4877                (const_string "brcc_no_delay_slot")]
4878               (const_string "return")))
4879    ; predicable won't help here since the canonical rtl looks different
4880    ; for branches.
4881    (set (attr "cond")
4882         (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4883                         (symbol_ref "ARC_FUNCTION_ILINK1"))
4884                     (match_test "TARGET_V2"))
4885                (const_string "nocond")]
4886               (const_string "canuse")))
4887   (set (attr "iscompact")
4888         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4889                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4890                (const_string "maybe")]
4891               (const_string "false")))
4892    (set (attr "length")
4893         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4894                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4895                (const_int 4)]
4896               (const_int 2)))])
4898 (define_insn "p_return_i"
4899   [(set (pc)
4900         (if_then_else (match_operator 0 "proper_comparison_operator"
4901                                       [(reg CC_REG) (const_int 0)])
4902                       (simple_return) (pc)))]
4903   "reload_completed
4904    && !(TARGET_V2
4905      && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
4907   rtx xop[2];
4908   xop[0] = operands[0];
4909   xop[1]
4910     = gen_rtx_REG (Pmode,
4911                    arc_return_address_register (arc_compute_function_type
4912                                                 (cfun)));
4914   if (TARGET_PAD_RETURN)
4915     arc_pad_return ();
4916   output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4917   /* record the condition in case there is a delay insn.  */
4918   arc_ccfsm_record_condition (xop[0], false, insn, 0);
4919   return \"\";
4921   [(set_attr "type" "return")
4922    (set_attr "cond" "use")
4923    (set (attr "iscompact")
4924         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4925                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4926                (const_string "maybe")]
4927               (const_string "false")))
4928    (set (attr "length")
4929         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4930                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4931                (const_int 4)
4932                (not (match_operand 0 "equality_comparison_operator" ""))
4933                (const_int 4)
4934                (eq_attr "delay_slot_filled" "yes")
4935                (const_int 4)]
4936               (const_int 2)))])
4938 (define_insn_and_split "eh_return"
4939   [(eh_return)
4940    (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4941    (clobber (match_scratch:SI 1  "=X,r"))
4942    (clobber (match_scratch:SI 2 "=&r,r"))]
4943   ""
4944   "#"
4945   "reload_completed"
4946   [(set (match_dup 2) (match_dup 0))]
4948   int offs = arc_return_slot_offset ();
4950   if (offs < 0)
4951     operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4952   else
4953     {
4954       if (!register_operand (operands[0], Pmode)
4955           && !satisfies_constraint_C32 (operands[0]))
4956         {
4957           emit_move_insn (operands[1], operands[0]);
4958           operands[0] = operands[1];
4959         }
4960       rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4961       if (!strict_memory_address_p (Pmode, addr))
4962         {
4963           emit_move_insn (operands[2], addr);
4964           addr = operands[2];
4965         }
4966       operands[2] = gen_frame_mem (Pmode, addr);
4967     }
4969   [(set_attr "length" "12")])
4971 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4972 ;; non-constant predicate.
4973 (define_expand "return"
4974   [(return)]
4975   "optimize < 0")
4977  ;; Comment in final.c (insn_current_reference_address) says
4978  ;; forward branch addresses are calculated from the next insn after branch
4979  ;; and for backward branches, it is calculated from the branch insn start.
4980  ;; The shortening logic here is tuned to accomodate this behavior
4981 ;; ??? This should be grokked by the ccfsm machinery.
4982 (define_insn "cbranchsi4_scratch"
4983   [(set (pc)
4984         (if_then_else (match_operator 0 "proper_comparison_operator"
4985                         [(match_operand:SI 1 "register_operand" "c,c, c")
4986                          (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4987                       (label_ref (match_operand 3 "" ""))
4988                       (pc)))
4989    (clobber (match_operand 4 "cc_register" ""))]
4990    "(reload_completed
4991      || (TARGET_EARLY_CBRANCHSI
4992          && brcc_nolimm_operator (operands[0], VOIDmode)))
4993     && !CROSSING_JUMP_P (insn)"
4994    "*
4995      switch (get_attr_length (insn))
4996      {
4997        case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4998        case 4: return \"br%d0%* %1, %B2, %^%l3\";
4999        case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
5000                  return \"br%d0%* %1, %B2, %^%l3\";
5001        /* FALLTHRU */
5002        case 6: case 10:
5003        case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\";
5004        default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
5005      }
5006    "
5007   [(set_attr "cond" "clob, clob, clob")
5008    (set (attr "type")
5009         (if_then_else
5010           (match_test "valid_brcc_with_delay_p (operands)")
5011           (const_string "brcc")
5012           (const_string "brcc_no_delay_slot")))
5013    ; For forward branches, we need to account not only for the distance to
5014    ; the target, but also the difference between pcl and pc, the instruction
5015    ; length, and any delay insn, if present.
5016    (set
5017      (attr "length")
5018      (cond ; the outer cond does a test independent of branch shortening.
5019        [(match_operand 0 "brcc_nolimm_operator" "")
5020         (cond
5021           [(and (match_operand:CC_Z 4 "cc_register")
5022                 (eq_attr "delay_slot_filled" "no")
5023                 (ge (minus (match_dup 3) (pc)) (const_int -128))
5024                 (le (minus (match_dup 3) (pc))
5025                     (minus (const_int 122)
5026                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5027            (const_int 2)
5028            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5029                 (le (minus (match_dup 3) (pc))
5030                     (minus (const_int 244)
5031                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5032            (const_int 4)
5033            (and (match_operand:SI 1 "compact_register_operand" "")
5034                 (match_operand:SI 2 "compact_hreg_operand" ""))
5035            (const_int 6)]
5036           (const_int 8))]
5037          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5038                      (le (minus (match_dup 3) (pc)) (const_int 244)))
5039                 (const_int 8)
5040                 (and (match_operand:SI 1 "compact_register_operand" "")
5041                      (match_operand:SI 2 "compact_hreg_operand" ""))
5042                 (const_int 10)]
5043                (const_int 12))))
5044    (set (attr "iscompact")
5045         (if_then_else (match_test "get_attr_length (insn) & 2")
5046                       (const_string "true") (const_string "false")))])
5048 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5049 (define_insn "*bbit"
5050   [(set (pc)
5051         (if_then_else
5052           (match_operator 3 "equality_comparison_operator"
5053             [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5054                               (const_int 1)
5055                               (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5056              (const_int 0)])
5057           (label_ref (match_operand 0 "" ""))
5058           (pc)))
5059    (clobber (reg:CC_ZN CC_REG))]
5060   "!CROSSING_JUMP_P (insn)"
5062   switch (get_attr_length (insn))
5063     {
5064       case 4: return (GET_CODE (operands[3]) == EQ
5065                       ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5066       case 6:
5067       case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5068       default: gcc_unreachable ();
5069     }
5071   [(set_attr "type" "brcc")
5072    (set_attr "cond" "clob")
5073    (set (attr "length")
5074         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5075                     (le (minus (match_dup 0) (pc))
5076                     (minus (const_int 248)
5077                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5078                (const_int 4)
5079                (eq (symbol_ref "which_alternative") (const_int 0))
5080                (const_int 6)]
5081               (const_int 8)))
5082    (set (attr "iscompact")
5083         (if_then_else (match_test "get_attr_length (insn) == 6")
5084                       (const_string "true") (const_string "false")))])
5086 ; ??? When testing a bit from a DImode register, combine creates a
5087 ; zero_extract in DImode.  This goes via an AND with a DImode constant,
5088 ; so can only be observed on 64 bit hosts.
5089 (define_insn_and_split "*bbit_di"
5090   [(set (pc)
5091         (if_then_else
5092           (match_operator 3 "equality_comparison_operator"
5093             [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
5094                               (const_int 1)
5095                               (match_operand 2 "immediate_operand" "L,L"))
5096              (const_int 0)])
5097           (label_ref (match_operand 0 "" ""))
5098           (pc)))
5099    (clobber (reg:CC_ZN CC_REG))]
5100   "!CROSSING_JUMP_P (insn)"
5101   "#"
5102   ""
5103   [(parallel
5104      [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
5105       (clobber (reg:CC_ZN CC_REG))])]
5107   rtx xtr;
5109   xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
5110   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
5111                                 xtr, const0_rtx);
5114 ;; -------------------------------------------------------------------
5115 ;; Hardware loop
5116 ;; -------------------------------------------------------------------
5118 ; operand 0 is the loop count pseudo register
5119 ; operand 1 is the label to jump to at the top of the loop
5120 (define_expand "doloop_end"
5121   [(parallel [(set (pc)
5122                    (if_then_else
5123                     (ne (match_operand 0 "" "")
5124                         (const_int 1))
5125                     (label_ref (match_operand 1 "" ""))
5126                     (pc)))
5127               (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
5128               (unspec [(const_int 0)] UNSPEC_ARC_LP)
5129               (clobber (match_dup 2))])]
5130   ""
5132  if (GET_MODE (operands[0]) != SImode)
5133    FAIL;
5134  operands[2] = gen_rtx_SCRATCH (SImode);
5137 (define_insn "arc_lp"
5138   [(unspec:SI [(match_operand:SI 0 "register_operand" "l")]
5139               UNSPEC_ARC_LP)
5140    (use (label_ref (match_operand 1 "" "")))
5141    (use (label_ref (match_operand 2 "" "")))]
5142   ""
5143   "lp\\t@%l2\\t; %0:@%l1->@%l2"
5144   [(set_attr "type" "loop_setup")
5145    (set_attr "length" "4")])
5147 ;; if by any chance the lp_count is not used, then use an 'r'
5148 ;; register, instead of going to memory.
5149 (define_insn "loop_end"
5150   [(set (pc)
5151         (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
5152                           (const_int 1))
5153                       (label_ref (match_operand 1 "" ""))
5154                       (pc)))
5155    (set (match_operand:SI 0 "nonimmediate_operand" "=l!r,m")
5156         (plus (match_dup 2) (const_int -1)))
5157    (unspec [(const_int 0)] UNSPEC_ARC_LP)
5158    (clobber (match_scratch:SI 3 "=X,&r"))]
5159   ""
5160   "\\t;%0 %1 %2"
5161   [(set_attr "length" "0")
5162    (set_attr "predicable" "no")
5163    (set_attr "type" "loop_end")])
5165 ;; split pattern for the very slim chance when the loop register is
5166 ;; memory.
5167 (define_split
5168   [(set (pc)
5169         (if_then_else (ne (match_operand:SI 0 "memory_operand")
5170                           (const_int 1))
5171                       (label_ref (match_operand 1 ""))
5172                       (pc)))
5173    (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
5174    (unspec [(const_int 0)] UNSPEC_ARC_LP)
5175    (clobber (match_scratch:SI 2))]
5176   "memory_operand (operands[0], SImode)"
5177   [(set (match_dup 2) (match_dup 0))
5178    (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5179    (set (match_dup 0) (match_dup 2))
5180    (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5181    (set (pc)
5182         (if_then_else (ne (reg:CC CC_REG)
5183                           (const_int 0))
5184                       (label_ref (match_dup 1))
5185                       (pc)))]
5186   "")
5188 (define_insn "loop_fail"
5189   [(set (reg:SI LP_COUNT)
5190         (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5191    (set (reg:CC_ZN CC_REG)
5192         (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5193                        (const_int 0)))]
5194   ""
5195   "sub.f%?\\tlp_count,lp_count,1"
5196   [(set_attr "iscompact" "false")
5197    (set_attr "type" "compare")
5198    (set_attr "cond" "set_zn")
5199    (set_attr "length" "4")
5200    (set_attr "predicable" "yes")])
5202 (define_insn_and_split "dbnz"
5203   [(set (pc)
5204         (if_then_else
5205          (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+r!l,m")
5206                       (const_int -1))
5207              (const_int 0))
5208          (label_ref (match_operand 1 "" ""))
5209          (pc)))
5210    (set (match_dup 0)
5211         (plus:SI (match_dup 0)
5212                  (const_int -1)))
5213    (clobber (match_scratch:SI 2 "=X,r"))]
5214   "TARGET_V2"
5215   "@
5216    dbnz%#\\t%0,%l1
5217    #"
5218   "TARGET_V2 && reload_completed && memory_operand (operands[0], SImode)"
5219   [(set (match_dup 2) (match_dup 0))
5220    (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5221    (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5222    (set (match_dup 0) (match_dup 2))
5223    (set (pc) (if_then_else (ge (reg:CC CC_REG)
5224                                (const_int 0))
5225                            (label_ref (match_dup 1))
5226                            (pc)))]
5227   ""
5228   [(set_attr "iscompact" "false")
5229    (set_attr "type" "loop_end")
5230    (set_attr "length" "4,20")])
5232 (define_expand "movmemsi"
5233   [(match_operand:BLK 0 "" "")
5234    (match_operand:BLK 1 "" "")
5235    (match_operand:SI 2 "nonmemory_operand" "")
5236    (match_operand 3 "immediate_operand" "")]
5237   ""
5238   "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5240 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5241 ;; to the point that we can generate cmove instructions.
5242 (define_expand "cbranch<mode>4"
5243   [(set (reg:CC CC_REG)
5244         (compare:CC (match_operand:SDF 1 "register_operand" "")
5245                     (match_operand:SDF 2 "register_operand" "")))
5246    (set (pc)
5247         (if_then_else
5248          (match_operator 0 "comparison_operator" [(reg CC_REG)
5249                                                       (const_int 0)])
5250          (label_ref (match_operand 3 "" ""))
5251          (pc)))]
5253   "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5255   gcc_assert (XEXP (operands[0], 0) == operands[1]);
5256   gcc_assert (XEXP (operands[0], 1) == operands[2]);
5257   operands[0] = gen_compare_reg (operands[0], VOIDmode);
5258   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5259   DONE;
5262 (define_expand "cmp_float"
5263   [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5264               (clobber (reg:SI RETURN_ADDR_REGNUM))
5265               (clobber (reg:SI R12_REG))])]
5266   ""
5267   "")
5269 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5270 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5271                        (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5273 (define_insn "*cmpsf_<cmp>"
5274   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5275    (clobber (reg:SI RETURN_ADDR_REGNUM))
5276    (clobber (reg:SI R12_REG))]
5277   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5278    && SFUNC_CHECK_PREDICABLE"
5279   "*return arc_output_libcall (\"__<cmp>sf2\");"
5280   [(set_attr "is_sfunc" "yes")
5281    (set_attr "predicable" "yes")])
5283 ;; N.B. for "*cmpdf_ord":
5284 ;; double precision fpx sets bit 31 for NaNs.  We need bit 51 set
5285 ;; for the floating point emulation to recognize the NaN.
5286 (define_insn "*cmpdf_<cmp>"
5287   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5288    (clobber (reg:SI RETURN_ADDR_REGNUM))
5289    (clobber (reg:SI R12_REG))]
5290   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5291    && SFUNC_CHECK_PREDICABLE"
5292   "*return arc_output_libcall (\"__<cmp>df2\");"
5293   [(set_attr "is_sfunc" "yes")
5294    (set_attr "predicable" "yes")])
5296 (define_insn "abssf2"
5297   [(set (match_operand:SF 0 "dest_reg_operand"    "=Rcq#q,Rcw,w")
5298         (abs:SF (match_operand:SF 1 "register_operand" "0,  0,c")))]
5299   ""
5300   "bclr%? %0,%1,31%&"
5301   [(set_attr "type" "unary")
5302    (set_attr "iscompact" "maybe,false,false")
5303    (set_attr "length" "2,4,4")
5304    (set_attr "predicable" "no,yes,no")])
5306 (define_insn "negsf2"
5307   [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5308         (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5309   ""
5310   "bxor%? %0,%1,31"
5311   [(set_attr "type" "unary")
5312    (set_attr "predicable" "yes,no")])
5314 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5315 (define_insn "*millicode_thunk_st"
5316   [(match_parallel 0 "millicode_store_operation"
5317      [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5318   ""
5320   output_asm_insn ("bl%* __st_r13_to_%0",
5321                    &SET_SRC (XVECEXP (operands[0], 0,
5322                                       XVECLEN (operands[0], 0) - 2)));
5323   return "";
5325   [(set_attr "type" "call")])
5327 (define_insn "*millicode_thunk_ld"
5328   [(match_parallel 0 "millicode_load_clob_operation"
5329      [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5330   ""
5332   output_asm_insn ("bl%* __ld_r13_to_%0",
5333                    &SET_DEST (XVECEXP (operands[0], 0,
5334                                        XVECLEN (operands[0], 0) - 2)));
5335   return "";
5337   [(set_attr "type" "call")])
5339 ; the sibthunk restores blink, so we use the return rtx.
5340 (define_insn "*millicode_sibthunk_ld"
5341   [(match_parallel 0 "millicode_load_operation"
5342      [(return)
5343       (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5344       (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5345   ""
5347   output_asm_insn ("b%* __ld_r13_to_%0_ret",
5348                    &SET_DEST (XVECEXP (operands[0], 0,
5349                                        XVECLEN (operands[0], 0) - 1)));
5350   return "";
5352   [(set_attr "type" "call")
5353    (set_attr "is_SIBCALL" "yes")])
5355 (define_insn "tls_load_tp_soft"
5356   [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF))
5357    (clobber (reg:SI RETURN_ADDR_REGNUM))]
5358   ""
5359   "*return arc_output_libcall (\"__read_tp\");"
5360   [(set_attr "is_sfunc" "yes")
5361    (set_attr "predicable" "yes")])
5363 (define_insn "tls_gd_get_addr"
5364   [(set (reg:SI R0_REG)
5365         (call:SI (mem:SI (unspec:SI [(match_operand:SI 0
5366                                       "symbolic_operand" "X,X")]
5367                           UNSPEC_TLS_GD))
5368                  (const_int 0)))
5369    (clobber (reg:SI RETURN_ADDR_REGNUM))]
5370   ""
5371   ".tls_gd_ld %0`bl%* __tls_get_addr@plt"
5372   [(set_attr "type" "call")
5373    ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
5374    (set_attr "predicable" "no")])
5376 ;; For thread pointer builtins
5377 (define_expand "get_thread_pointersi"
5378   [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5379  ""
5380  "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5382 (define_expand "set_thread_pointersi"
5383   [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5384  ""
5385  "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5387 ;; If hardware floating point is available, don't define a negdf pattern;
5388 ;; it would be something like:
5389 ;;(define_insn "negdf2"
5390 ;;  [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5391 ;;      (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5392 ;;   (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5393 ;;  ""
5394 ;;  "@
5395 ;;   bxor%? %H0,%H1,31
5396 ;;   bxor %H0,%H1,31 ` mov %L0,%L1
5397 ;;   drsubh%F0%F1 0,0,0
5398 ;;   drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5399 ;;  [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5400 ;;   (set_attr "iscompact" "false,false,false,false")
5401 ;;   (set_attr "length" "4,4,8,12")
5402 ;;   (set_attr "cond" "canuse,nocond,nocond,nocond")])
5403 ;; and this suffers from always requiring a long immediate when using
5404 ;; the floating point hardware.
5405 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5406 ;; constant zero efficiently into a register when we want to do the
5407 ;; computation using the floating point hardware.  There should be a special
5408 ;; subdf alternative that matches a zero operand 1, which then can allow
5409 ;; to use bxor to flip the high bit of an integer register.
5410 ;; ??? we actually can't use the floating point hardware for neg, because
5411 ;; this would not work right for -0.  OTOH optabs.c has already code
5412 ;; to synthesyze negate by flipping the sign bit.
5414 ;;V2 instructions
5415 (define_insn "bswapsi2"
5416   [(set (match_operand:SI 0 "register_operand"           "= r,r")
5417         (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5418   "TARGET_V2 && TARGET_SWAP"
5419   "swape %0, %1"
5420   [(set_attr "length" "4,8")
5421    (set_attr "type" "two_cycle_core")])
5423 (define_expand "prefetch"
5424   [(prefetch (match_operand:SI 0 "address_operand" "")
5425              (match_operand:SI 1 "const_int_operand" "")
5426              (match_operand:SI 2 "const_int_operand" ""))]
5427   "TARGET_HS"
5428   "")
5430 (define_insn "prefetch_1"
5431   [(prefetch (match_operand:SI 0 "register_operand" "r")
5432              (match_operand:SI 1 "const_int_operand" "n")
5433              (match_operand:SI 2 "const_int_operand" "n"))]
5434   "TARGET_HS"
5435   {
5436    if (INTVAL (operands[1]))
5437       return "prefetchw [%0]";
5438    else
5439       return "prefetch [%0]";
5440   }
5441   [(set_attr "type" "load")
5442    (set_attr "length" "4")])
5444 (define_insn "prefetch_2"
5445   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5446                       (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5447              (match_operand:SI 2 "const_int_operand" "n,n,n")
5448              (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5449   "TARGET_HS"
5450   {
5451    if (INTVAL (operands[2]))
5452       return "prefetchw [%0, %1]";
5453    else
5454       return "prefetch [%0, %1]";
5455   }
5456   [(set_attr "type" "load")
5457    (set_attr "length" "4,4,8")])
5459 (define_insn "prefetch_3"
5460   [(prefetch (match_operand:SI 0 "address_operand" "p")
5461              (match_operand:SI 1 "const_int_operand" "n")
5462              (match_operand:SI 2 "const_int_operand" "n"))]
5463   "TARGET_HS"
5464   {
5465    operands[0] = gen_rtx_MEM (SImode, operands[0]);
5466    if (INTVAL (operands[1]))
5467       return "prefetchw%U0 %0";
5468    else
5469       return "prefetch%U0 %0";
5470    }
5471   [(set_attr "type" "load")
5472    (set_attr "length" "8")])
5474 (define_insn "divsi3"
5475   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r,r,r,  r,  r")
5476         (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5477                 (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5478   "TARGET_DIVREM"
5479   "div%? %0, %1, %2"
5480   [(set_attr "length" "4,4,8,4,4,4,8,8")
5481    (set_attr "iscompact" "false")
5482    (set_attr "type" "div_rem")
5483    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5484    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5485    ])
5487 (define_insn "udivsi3"
5488   [(set (match_operand:SI 0 "register_operand"          "=r,r,  r,r,r,r,  r,  r")
5489         (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5490                  (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5491   "TARGET_DIVREM"
5492   "divu%? %0, %1, %2"
5493   [(set_attr "length" "4,4,8,4,4,4,8,8")
5494    (set_attr "iscompact" "false")
5495    (set_attr "type" "div_rem")
5496    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5497    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5498    ])
5500 (define_insn "modsi3"
5501   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r,r,r,  r,  r")
5502         (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5503                 (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5504   "TARGET_DIVREM"
5505   "rem%? %0, %1, %2"
5506   [(set_attr "length" "4,4,8,4,4,4,8,8")
5507    (set_attr "iscompact" "false")
5508    (set_attr "type" "div_rem")
5509    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5510    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5511    ])
5513 (define_insn "umodsi3"
5514   [(set (match_operand:SI 0 "register_operand"          "=r,r,  r,r,r,r,  r,  r")
5515         (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5516                  (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5517   "TARGET_DIVREM"
5518   "remu%? %0, %1, %2"
5519   [(set_attr "length" "4,4,8,4,4,4,8,8")
5520    (set_attr "iscompact" "false")
5521    (set_attr "type" "div_rem")
5522    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5523    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5524    ])
5526 ;; SETcc instructions
5527 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5529 (define_insn "arcset<code>"
5530   [(set (match_operand:SI 0 "register_operand"                "=r,r,r,r,r,r,r")
5531         (arcCC_cond:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,0,r")
5532                        (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5533   "TARGET_V2 && TARGET_CODE_DENSITY"
5534   "set<code>%? %0, %1, %2"
5535   [(set_attr "length" "4,4,4,4,4,8,8")
5536    (set_attr "iscompact" "false")
5537    (set_attr "type" "compare")
5538    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5539    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5540    ])
5542 (define_insn "arcsetltu"
5543   [(set (match_operand:SI 0 "register_operand"         "=r,r,r,r,r,  r,  r")
5544         (ltu:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,  0,  r")
5545                 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,  n,  n")))]
5546   "TARGET_V2 && TARGET_CODE_DENSITY"
5547   "setlo%? %0, %1, %2"
5548   [(set_attr "length" "4,4,4,4,4,8,8")
5549    (set_attr "iscompact" "false")
5550    (set_attr "type" "compare")
5551    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5552    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5553    ])
5555 (define_insn "arcsetgeu"
5556   [(set (match_operand:SI 0 "register_operand"         "=r,r,r,r,r,  r,  r")
5557         (geu:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,  0,  r")
5558                 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,  n,  n")))]
5559   "TARGET_V2 && TARGET_CODE_DENSITY"
5560   "seths%? %0, %1, %2"
5561   [(set_attr "length" "4,4,4,4,4,8,8")
5562    (set_attr "iscompact" "false")
5563    (set_attr "type" "compare")
5564    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5565    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5566    ])
5568 ;; Special cases of SETCC
5569 (define_insn_and_split "arcsethi"
5570   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r")
5571         (gtu:SI (match_operand:SI 1 "register_operand"  "r,r,  r,r")
5572                 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5573   "TARGET_V2 && TARGET_CODE_DENSITY"
5574   "setlo%? %0, %2, %1"
5575   "reload_completed
5576    && CONST_INT_P (operands[2])
5577    && satisfies_constraint_C62 (operands[2])"
5578   [(const_int 0)]
5579   "{
5580     /* sethi a,b,u6 => seths a,b,u6 + 1.  */
5581     operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5582     emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5583     DONE;
5584  }"
5585  [(set_attr "length" "4,4,4,8")
5586    (set_attr "iscompact" "false")
5587    (set_attr "type" "compare")
5588    (set_attr "predicable" "yes,no,no,no")
5589    (set_attr "cond" "canuse,nocond,nocond,nocond")]
5592 (define_insn_and_split "arcsetls"
5593   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r")
5594         (leu:SI (match_operand:SI 1 "register_operand"  "r,r,  r,r")
5595                 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5596   "TARGET_V2 && TARGET_CODE_DENSITY"
5597   "seths%? %0, %2, %1"
5598   "reload_completed
5599    && CONST_INT_P (operands[2])
5600    && satisfies_constraint_C62 (operands[2])"
5601   [(const_int 0)]
5602   "{
5603     /* setls a,b,u6 => setlo a,b,u6 + 1.  */
5604     operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5605     emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5606     DONE;
5607  }"
5608  [(set_attr "length" "4,4,4,8")
5609    (set_attr "iscompact" "false")
5610    (set_attr "type" "compare")
5611    (set_attr "predicable" "yes,no,no,no")
5612    (set_attr "cond" "canuse,nocond,nocond,nocond")]
5615 ; Any mode that needs to be solved by secondary reload
5616 (define_mode_iterator SRI [QI HI])
5618 (define_expand "reload_<mode>_load"
5619   [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5620               (match_operand:SRI 1 "memory_operand" "m")
5621               (match_operand:SI 2 "register_operand" "=&r")])]
5622   ""
5624  arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5625  DONE;
5628 (define_expand "reload_<mode>_store"
5629   [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5630               (match_operand:SRI 1 "register_operand" "r")
5631               (match_operand:SI 2 "register_operand" "=&r")])]
5632   ""
5634  arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5635  DONE;
5639 (define_insn "extzvsi"
5640   [(set (match_operand:SI 0 "register_operand"                  "=r  , r  , r, r, r")
5641         (zero_extract:SI (match_operand:SI 1 "register_operand"  "0  , r  , 0, 0, r")
5642                          (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5643                          (match_operand:SI 3 "const_int_operand" "i  , i  , i, i, i")))]
5644   "TARGET_HS && TARGET_BARREL_SHIFTER"
5645   {
5646    int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5647    operands[2] = GEN_INT (assemble_op2);
5648    return "xbfu%? %0,%1,%2";
5649   }
5650   [(set_attr "type"       "shift")
5651    (set_attr "iscompact"  "false")
5652    (set_attr "length"     "4,4,4,8,8")
5653    (set_attr "predicable" "yes,no,no,yes,no")
5654    (set_attr "cond"       "canuse,nocond,nocond,canuse,nocond")])
5656 (define_insn "kflag"
5657   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5658                    VUNSPEC_ARC_KFLAG)]
5659   "TARGET_V2"
5660   "@
5661     kflag%? %0
5662     kflag %0
5663     kflag%? %S0"
5664   [(set_attr "length" "4,4,8")
5665    (set_attr "type" "misc,misc,misc")
5666    (set_attr "predicable" "yes,no,yes")
5667    (set_attr "cond" "clob,clob,clob")])
5669 (define_insn "clri"
5670   [(set (match_operand:SI  0 "dest_reg_operand" "=r")
5671         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5672                             VUNSPEC_ARC_CLRI))]
5673   "TARGET_V2"
5674   "clri  %0"
5675   [(set_attr "length" "4")
5676    (set_attr "type" "misc")])
5678 (define_insn "ffs"
5679   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5680         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5681                             UNSPEC_ARC_FFS))]
5682   "TARGET_NORM && TARGET_V2"
5683   "@
5684    ffs \t%0, %1
5685    ffs \t%0, %S1"
5686   [(set_attr "length" "4,8")
5687    (set_attr "type" "two_cycle_core,two_cycle_core")])
5689 (define_insn "ffs_f"
5690   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5691         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5692                             UNSPEC_ARC_FFS))
5693    (set (reg:CC_ZN CC_REG)
5694         (compare:CC_ZN (match_dup 1) (const_int 0)))]
5695   "TARGET_NORM && TARGET_V2"
5696   "@
5697    ffs.f\t%0, %1
5698    ffs.f\t%0, %S1"
5699   [(set_attr "length" "4,8")
5700    (set_attr "type" "two_cycle_core,two_cycle_core")])
5702 (define_expand "ffssi2"
5703   [(parallel [(set (match_dup 2)
5704                    (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5705                               UNSPEC_ARC_FFS))
5706               (set (reg:CC_ZN CC_REG)
5707                    (compare:CC_ZN (match_dup 1) (const_int 0)))])
5708    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5709    (set (match_operand:SI 0 "dest_reg_operand" "")
5710         (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5711                          (const_int 0)
5712                          (match_dup 2)))]
5713   "TARGET_NORM && TARGET_V2"
5714   {
5715    operands[2] = gen_reg_rtx (SImode);
5716    })
5718 (define_insn "fls"
5719   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5720         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5721                             UNSPEC_ARC_FLS))]
5722   "TARGET_NORM && TARGET_V2"
5723   "@
5724    fls \t%0, %1
5725    fls \t%0, %S1"
5726   [(set_attr "length" "4,8")
5727    (set_attr "type" "two_cycle_core,two_cycle_core")])
5729 (define_insn "seti"
5730   [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5731                        VUNSPEC_ARC_SETI)]
5732   "TARGET_V2"
5733   "seti  %0"
5734   [(set_attr "length" "4")
5735    (set_attr "type" "misc")])
5737 ;; FPU/FPX expands
5739 ;;add
5740 (define_expand "addsf3"
5741   [(set (match_operand:SF 0 "register_operand"           "")
5742         (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5743                  (match_operand:SF 2 "nonmemory_operand" "")))]
5744   "TARGET_FP_SP_BASE || TARGET_SPFP"
5745   "
5746   if (!register_operand (operands[1], SFmode)
5747       && !register_operand (operands[2], SFmode))
5748     operands[1] = force_reg (SFmode, operands[1]);
5749   ")
5751 ;;sub
5752 (define_expand "subsf3"
5753   [(set (match_operand:SF 0 "register_operand"            "")
5754         (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5755                   (match_operand:SF 2 "nonmemory_operand" "")))]
5756   "TARGET_FP_SP_BASE || TARGET_SPFP"
5757   "
5758   if (!register_operand (operands[1], SFmode)
5759       && !register_operand (operands[2], SFmode))
5760     operands[1] = force_reg (SFmode, operands[1]);
5761   ")
5763 ;;mul
5764 (define_expand "mulsf3"
5765   [(set (match_operand:SF 0 "register_operand"           "")
5766         (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5767                  (match_operand:SF 2 "nonmemory_operand" "")))]
5768   "TARGET_FP_SP_BASE || TARGET_SPFP"
5769   "
5770   if (!register_operand (operands[1], SFmode)
5771       && !register_operand (operands[2], SFmode))
5772     operands[1] = force_reg (SFmode, operands[1]);
5773   ")
5775 ;;add
5776 (define_expand "adddf3"
5777   [(set (match_operand:DF 0 "double_register_operand"           "")
5778         (plus:DF (match_operand:DF 1 "double_register_operand"  "")
5779                  (match_operand:DF 2 "nonmemory_operand" "")))]
5780  "TARGET_FP_DP_BASE || TARGET_DPFP"
5782   if (TARGET_DPFP)
5783    {
5784     if (GET_CODE (operands[2]) == CONST_DOUBLE)
5785      {
5786         rtx first, second, tmp;
5787         split_double (operands[2], &first, &second);
5788         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5789         emit_insn (gen_adddf3_insn (operands[0], operands[1],
5790                                     operands[2], tmp, const0_rtx));
5791      }
5792     else
5793      emit_insn (gen_adddf3_insn (operands[0], operands[1],
5794                                  operands[2], const1_rtx, const1_rtx));
5795    DONE;
5796   }
5797  else if (TARGET_FP_DP_BASE)
5798   {
5799    if (!even_register_operand (operands[2], DFmode))
5800       operands[2] = force_reg (DFmode, operands[2]);
5802    if (!even_register_operand (operands[1], DFmode))
5803       operands[1] = force_reg (DFmode, operands[1]);
5804   }
5805  else
5806   gcc_unreachable ();
5807  ")
5809 ;;sub
5810 (define_expand "subdf3"
5811   [(set (match_operand:DF 0 "double_register_operand"            "")
5812         (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5813                   (match_operand:DF 2 "nonmemory_operand" "")))]
5814   "TARGET_FP_DP_BASE || TARGET_DPFP"
5815   "
5816    if (TARGET_DPFP)
5817     {
5818      if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5819        operands[1] = force_reg (DFmode, operands[1]);
5820      if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5821           || GET_CODE (operands[2]) == CONST_DOUBLE)
5822       {
5823         rtx first, second, tmp;
5824         int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5825         split_double (operands[const_index], &first, &second);
5826         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5827         emit_insn (gen_subdf3_insn (operands[0], operands[1],
5828                                     operands[2], tmp, const0_rtx));
5829       }
5830     else
5831      emit_insn (gen_subdf3_insn (operands[0], operands[1],
5832                                  operands[2], const1_rtx, const1_rtx));
5833     DONE;
5834    }
5835   else if (TARGET_FP_DP_BASE)
5836    {
5837     if (!even_register_operand (operands[2], DFmode))
5838        operands[2] = force_reg (DFmode, operands[2]);
5840     if (!even_register_operand (operands[1], DFmode))
5841        operands[1] = force_reg (DFmode, operands[1]);
5842    }
5843   else
5844    gcc_unreachable ();
5845   ")
5847 ;;mul
5848 (define_expand "muldf3"
5849   [(set (match_operand:DF 0 "double_register_operand"           "")
5850         (mult:DF (match_operand:DF 1 "double_register_operand"  "")
5851                  (match_operand:DF 2 "nonmemory_operand" "")))]
5852   "TARGET_FP_DP_BASE || TARGET_DPFP"
5853   "
5854    if (TARGET_DPFP)
5855     {
5856      if (GET_CODE (operands[2]) == CONST_DOUBLE)
5857       {
5858         rtx first, second, tmp;
5859         split_double (operands[2], &first, &second);
5860         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5861         emit_insn (gen_muldf3_insn (operands[0], operands[1],
5862                                     operands[2], tmp, const0_rtx));
5863       }
5864      else
5865       emit_insn (gen_muldf3_insn (operands[0], operands[1],
5866                                   operands[2], const1_rtx, const1_rtx));
5867     DONE;
5868    }
5869   else if (TARGET_FP_DP_BASE)
5870    {
5871     if (!even_register_operand (operands[2], DFmode))
5872        operands[2] = force_reg (DFmode, operands[2]);
5874     if (!even_register_operand (operands[1], DFmode))
5875        operands[1] = force_reg (DFmode, operands[1]);
5876    }
5877   else
5878    gcc_unreachable ();
5879  ")
5881 ;;div
5882 (define_expand "divsf3"
5883   [(set (match_operand:SF 0 "register_operand"        "")
5884         (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5885                 (match_operand:SF 2 "nonmemory_operand" "")))]
5886   "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5887   "
5888   if (TARGET_FPX_QUARK)
5889    {
5890      operands[1] = force_reg (SFmode, operands[1]);
5891      operands[2] = force_reg (SFmode, operands[2]);
5892    }
5893   else
5894    {
5895      if (!register_operand (operands[1], SFmode)
5896         && !register_operand (operands[2], SFmode))
5897        operands[1] = force_reg (SFmode, operands[1]);
5898    }
5899   ")
5901 ;; Square root
5902 (define_expand "sqrtsf2"
5903   [(set (match_operand:SF 0 "register_operand"           "")
5904         (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5905   "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5906   "
5907   if (TARGET_FPX_QUARK)
5908    {
5909      operands[1] = force_reg (SFmode, operands[1]);
5910    }
5913 ;; SF->SI (using rounding towards zero)
5914 (define_expand "fix_truncsfsi2"
5915   [(set (match_operand:SI 0 "register_operand"                "")
5916         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5917   "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5918   "")
5920 ;; SI->SF
5921 (define_expand "floatsisf2"
5922   [(set (match_operand:SF 0 "register_operand"            "")
5923         (float:SF (match_operand:SI 1 "register_operand" "")))]
5924   "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5925   "")
5927 (define_expand "extzv"
5928   [(set (match_operand:SI 0 "register_operand" "")
5929         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5930                          (match_operand:SI 2 "const_int_operand" "")
5931                          (match_operand:SI 3 "const_int_operand" "")))]
5932   "TARGET_NPS_BITOPS")
5934 ; We need a sanity check in the instuction predicate because combine
5935 ; will throw any old rubbish at us and see what sticks.
5936 (define_insn "*extzv_i"
5937   [(set (match_operand:SI 0 "register_operand" "=Rrq")
5938         (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5939                          (match_operand:SI 2 "const_int_operand" "n")
5940                          (match_operand:SI 3 "const_int_operand" "n")))]
5941   "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5942   "movb.cl %0,%1,0,%3,%2"
5943   [(set_attr "type" "shift")
5944    (set_attr "length" "4")])
5946 (define_expand "insv"
5947   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5948                          (match_operand:SI 1 "const_int_operand" "")
5949                          (match_operand:SI 2 "const_int_operand" ""))
5950         (match_operand:SI 3 "nonmemory_operand" ""))]
5951   "TARGET_NPS_BITOPS"
5953   int size = INTVAL (operands[1]);
5955   if (size != 1 && size != 2 && size != 4 && size != 8)
5956     operands[3] = force_reg (SImode, operands[3]);
5959 (define_insn "*insv_i"
5960   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5961                          (match_operand:SI 1 "const_int_operand" "C18,n")
5962                          (match_operand:SI 2 "const_int_operand" "n,n"))
5963         (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5964   "TARGET_NPS_BITOPS
5965    && (register_operand (operands[3], SImode)
5966        || satisfies_constraint_C18 (operands[1]))"
5967   "@
5968    movbi %0,%0,%3,%2,%1
5969    movb %0,%0,%3,%2,0,%1"
5970   [(set_attr "type" "shift")
5971    (set_attr "length" "4")])
5973 (define_insn "*movb"
5974   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5975                          (match_operand:SI 1 "const_int_operand" "n")
5976                          (match_operand:SI 2 "const_int_operand" "n"))
5977         (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5978                          (match_dup 1)
5979                          (match_operand:SI 4 "const_int_operand" "n")))]
5980   "TARGET_NPS_BITOPS"
5981   "movb %0,%0,%3,%2,%4,%1"
5982   [(set_attr "type" "shift")
5983    (set_attr "length" "4")])
5985 (define_insn "*movb_signed"
5986   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5987                          (match_operand:SI 1 "const_int_operand" "n")
5988                          (match_operand:SI 2 "const_int_operand" "n"))
5989         (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5990                          (match_dup 1)
5991                          (match_operand:SI 4 "const_int_operand" "n")))]
5992   "TARGET_NPS_BITOPS"
5993   "movb %0,%0,%3,%2,%4,%1"
5994   [(set_attr "type" "shift")
5995    (set_attr "length" "4")])
5997 (define_insn "*movb_high"
5998   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5999                          (match_operand:SI 1 "const_int_operand" "n")
6000                          (match_operand:SI 2 "const_int_operand" "n"))
6001         (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6002                      (match_operand:SI 4 "const_int_operand" "n")))]
6003   "TARGET_NPS_BITOPS
6004    && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6005   "movb %0,%0,%3,%2,%4,%1"
6006   [(set_attr "type" "shift")
6007    (set_attr "length" "4")])
6009 ; N.B.: when processing signed bitfields that fit in the top half of
6010 ; a word, gcc will use a narrow sign extending load, and in this case
6011 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6012 (define_insn "*movb_high_signed"
6013   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6014                          (match_operand:SI 1 "const_int_operand" "n")
6015                          (match_operand:SI 2 "const_int_operand" "n"))
6016         (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6017                      (match_operand:SI 4 "const_int_operand" "n")))]
6018   "TARGET_NPS_BITOPS
6019    && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6020   "movb %0,%0,%3,%2,%4,%1"
6021   [(set_attr "type" "shift")
6022    (set_attr "length" "4")])
6024 (define_split
6025   [(set (match_operand:SI 0 "register_operand" "")
6026         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6027                            (match_operand:SI 2 "const_int_operand" ""))
6028                 (subreg:SI (match_operand 3 "") 0)))]
6029   "TARGET_NPS_BITOPS
6030    && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6031    && !reg_overlap_mentioned_p (operands[0], operands[1])"
6032   [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6033    (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6034         (match_dup 1))]
6035   "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6037 (define_insn "*mrgb"
6038   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6039                          (match_operand:SI 1 "const_int_operand" "n")
6040                          (match_operand:SI 2 "const_int_operand" "n"))
6041         (zero_extract:SI (match_dup 0) (match_dup 1)
6042                          (match_operand:SI 3 "const_int_operand" "n")))
6043    (set (zero_extract:SI (match_dup 0)
6044                          (match_operand:SI 4 "const_int_operand" "n")
6045                          (match_operand:SI 5 "const_int_operand" "n"))
6046         (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6047                          (match_dup 4)
6048                          (match_operand:SI 7 "const_int_operand" "n")))]
6049   "TARGET_NPS_BITOPS"
6051   output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6052   /* The ;%? updates the known unalignment.  */
6053   return arc_short_long (insn, ";%?", "nop_s");
6055   [(set_attr "type" "shift")
6056    (set_attr "length" "6")
6057    (set_attr "iscompact" "true")])
6059 ;; combine fumbles combination of two movb patterns, and then the
6060 ;; combination is rejected by combinable_i3pat.
6061 ;; Thus, we can only use a peephole2 to combine two such insns.
6063 (define_peephole2
6064   [(set (match_operand:SI 0 "register_operand" "")
6065         (match_operand:SI 1 "register_operand" ""))
6066    (set (zero_extract:SI (match_dup 0)
6067                          (match_operand:SI 2 "const_int_operand" "")
6068                          (match_operand:SI 3 "const_int_operand" ""))
6069         (zero_extract:SI (match_dup 1)
6070                          (match_dup 2)
6071                          (match_operand:SI 4 "const_int_operand" "")))
6072    (match_operand 9) ; unrelated insn scheduled here
6073    (set (zero_extract:SI (match_dup 0)
6074                          (match_operand:SI 5 "const_int_operand" "")
6075                          (match_operand:SI 6 "const_int_operand" ""))
6076         (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6077                          (match_dup 5)
6078                          (match_operand:SI 8 "const_int_operand" "")))]
6079   "TARGET_NPS_BITOPS
6080    // Check that the second movb doesn't clobber an input of the extra insn.
6081    && !reg_overlap_mentioned_p (operands[0], operands[9])
6082    // And vice versa.
6083    && !reg_set_p (operands[0], operands[9])
6084    && !reg_set_p (operands[7], operands[9])"
6085   [(set (match_dup 0) (match_dup 1))
6086    (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6087                    (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6088               (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6089                    (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6090    (match_dup 9)])
6092 (define_peephole2
6093   [(set (match_operand:SI 0 "register_operand" "")
6094         (match_operand:SI 1 "register_operand" ""))
6095    (set (zero_extract:SI (match_dup 0)
6096                          (match_operand:SI 2 "const_int_operand" "")
6097                          (match_operand:SI 3 "const_int_operand" ""))
6098         (zero_extract:SI (match_dup 1)
6099                          (match_dup 2)
6100                          (match_operand:SI 4 "const_int_operand" "")))
6101    (set (match_dup 1) (match_operand 8))
6102    (set (zero_extract:SI (match_dup 0)
6103                          (match_operand:SI 5 "const_int_operand" "")
6104                          (match_operand:SI 6 "const_int_operand" ""))
6105         (zero_extract:SI (match_dup 1) (match_dup 5)
6106                          (match_operand:SI 7 "const_int_operand" "")))]
6107   "TARGET_NPS_BITOPS
6108    && !reg_overlap_mentioned_p (operands[0], operands[8])"
6109   [(set (match_dup 0) (match_dup 1))
6110    (set (match_dup 1) (match_dup 8))
6111    (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6112                    (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6113               (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6114                    (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6115    (match_dup 1)])
6117 (define_insn "*rotrsi3_cnt1"
6118   [(set (match_operand:SI 0 "dest_reg_operand"             "=w")
6119         (rotatert:SI (match_operand:SI 1 "register_operand" "c")
6120                      (const_int 1)))]
6121   ""
6122   "ror %0,%1%&"
6123   [(set_attr "type" "shift")
6124    (set_attr "predicable" "no")
6125    (set_attr "length" "4")])
6127 (define_insn "*ashlsi2_cnt1"
6128   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcqq,w")
6129         (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6130                    (const_int 1)))]
6131   ""
6132   "asl%? %0,%1%&"
6133   [(set_attr "type" "shift")
6134    (set_attr "iscompact" "maybe,false")
6135    (set_attr "predicable" "no,no")])
6137 (define_insn "*lshrsi3_cnt1"
6138   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcqq,w")
6139         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6140                      (const_int 1)))]
6141   ""
6142   "lsr%? %0,%1%&"
6143   [(set_attr "type" "shift")
6144    (set_attr "iscompact" "maybe,false")
6145    (set_attr "predicable" "no,no")])
6147 (define_insn "*ashrsi3_cnt1"
6148   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcqq,w")
6149         (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6150                      (const_int 1)))]
6151   ""
6152   "asr%? %0,%1%&"
6153   [(set_attr "type" "shift")
6154    (set_attr "iscompact" "maybe,false")
6155    (set_attr "predicable" "no,no")])
6157 (define_peephole2
6158   [(set (match_operand:SI 0 "register_operand" "")
6159         (zero_extract:SI (match_dup 0)
6160                          (match_operand:SI 1 "const_int_operand" "")
6161                          (match_operand:SI 2 "const_int_operand" "")))
6162    (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6163                          (match_dup 1)
6164                          (match_dup 2))
6165         (match_dup 0))]
6166   "TARGET_NPS_BITOPS
6167    && !reg_overlap_mentioned_p (operands[0], operands[3])"
6168   [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6169         (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6171 ;; Dummy pattern used as a place holder for automatically saved
6172 ;; registers.
6173 (define_insn "stack_irq_dwarf"
6174   [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6175   ""
6176   ""
6177   [(set_attr "length" "0")])
6179 ;; MAC and DMPY instructions
6180 (define_insn_and_split "maddsidi4"
6181   [(set (match_operand:DI 0 "register_operand" "=r")
6182         (plus:DI
6183          (mult:DI
6184           (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6185           (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6186          (match_operand:DI 3 "register_operand" "r")))]
6187   "TARGET_PLUS_DMPY"
6188   "#"
6189   "TARGET_PLUS_DMPY && reload_completed"
6190   [(const_int 0)]
6191   "{
6192    rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6193    emit_move_insn (acc_reg, operands[3]);
6194    if (TARGET_PLUS_MACD)
6195      emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6196    else
6197      {
6198       emit_insn (gen_mac (operands[1], operands[2]));
6199       emit_move_insn (operands[0], acc_reg);
6200      }
6201    DONE;
6202    }"
6203   [(set_attr "type" "multi")
6204    (set_attr "length" "36")])
6206 (define_insn "macd"
6207   [(set (match_operand:DI 0 "even_register_operand"            "=Rcr,r,r")
6208         (plus:DI
6209          (mult:DI
6210           (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6211           (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal")))
6212          (reg:DI ARCV2_ACC)))
6213    (set (reg:DI ARCV2_ACC)
6214         (plus:DI
6215          (mult:DI (sign_extend:DI (match_dup 1))
6216                   (sign_extend:DI (match_dup 2)))
6217          (reg:DI ARCV2_ACC)))]
6218  "TARGET_PLUS_MACD"
6219  "macd %0,%1,%2"
6220   [(set_attr "length" "4,4,8")
6221    (set_attr "type" "multi")
6222    (set_attr "predicable" "yes,no,no")
6223    (set_attr "cond" "canuse,nocond,nocond")])
6225 (define_insn "mac"
6226   [(set (reg:DI ARCV2_ACC)
6227         (plus:DI
6228          (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6229                   (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6230          (reg:DI ARCV2_ACC)))]
6231  "TARGET_PLUS_DMPY"
6232  "mac 0,%0,%1"
6233   [(set_attr "length" "4,8")
6234    (set_attr "type" "multi")
6235    (set_attr "predicable" "no")
6236    (set_attr "cond" "nocond")])
6238 (define_peephole2
6239   [(set (reg:DI ARCV2_ACC)
6240         (plus:DI
6241          (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6242                   (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6243          (reg:DI ARCV2_ACC)))
6244    (set (match_operand:SI 2 "register_operand" "")
6245         (match_operand:SI 3 "accl_operand" ""))]
6246  "TARGET_PLUS_DMPY"
6247  [(const_int 0)]
6249   emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6250   DONE;
6251  })
6253 (define_insn "mac_r"
6254   [(set (match_operand:SI 0 "register_operand" "=r,r")
6255         (truncate:SI
6256          (plus:DI
6257           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6258                    (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6259           (reg:DI ARCV2_ACC))))
6260    (clobber (reg:DI ARCV2_ACC))]
6261  "TARGET_PLUS_DMPY"
6262  "mac %0,%1,%2"
6263   [(set_attr "length" "4,8")
6264    (set_attr "type" "multi")
6265    (set_attr "predicable" "no")
6266    (set_attr "cond" "nocond")])
6268 (define_insn_and_split "umaddsidi4"
6269   [(set (match_operand:DI 0 "register_operand" "=r")
6270         (plus:DI
6271          (mult:DI
6272           (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6273           (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6274          (match_operand:DI 3 "register_operand" "r")))]
6275   "TARGET_PLUS_DMPY"
6276   "#"
6277   "TARGET_PLUS_DMPY && reload_completed"
6278   [(const_int 0)]
6279   "{
6280    rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6281    emit_move_insn (acc_reg, operands[3]);
6282    if (TARGET_PLUS_MACD)
6283      emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6284    else
6285      {
6286       emit_insn (gen_macu (operands[1], operands[2]));
6287       emit_move_insn (operands[0], acc_reg);
6288      }
6289    DONE;
6290    }"
6291   [(set_attr "type" "multi")
6292    (set_attr "length" "36")])
6294 (define_insn "macdu"
6295   [(set (match_operand:DI 0 "even_register_operand"            "=Rcr,r,r")
6296         (plus:DI
6297          (mult:DI
6298           (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6299           (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i")))
6300          (reg:DI ARCV2_ACC)))
6301    (set (reg:DI ARCV2_ACC)
6302         (plus:DI
6303          (mult:DI (zero_extend:DI (match_dup 1))
6304                   (zero_extend:DI (match_dup 2)))
6305          (reg:DI ARCV2_ACC)))]
6306  "TARGET_PLUS_MACD"
6307  "macdu %0,%1,%2"
6308   [(set_attr "length" "4,4,8")
6309    (set_attr "type" "multi")
6310    (set_attr "predicable" "yes,no,no")
6311    (set_attr "cond" "canuse,nocond,nocond")])
6313 (define_insn "macu"
6314   [(set (reg:DI ARCV2_ACC)
6315         (plus:DI
6316          (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6317                   (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6318          (reg:DI ARCV2_ACC)))]
6319  "TARGET_PLUS_DMPY"
6320  "macu 0,%0,%1"
6321   [(set_attr "length" "4,8")
6322    (set_attr "type" "multi")
6323    (set_attr "predicable" "no")
6324    (set_attr "cond" "nocond")])
6326 (define_peephole2
6327   [(set (reg:DI ARCV2_ACC)
6328         (plus:DI
6329          (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6330                   (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6331          (reg:DI ARCV2_ACC)))
6332    (set (match_operand:SI 2 "register_operand" "")
6333         (match_operand:SI 3 "accl_operand" ""))]
6334  "TARGET_PLUS_DMPY"
6335  [(const_int 0)]
6337   emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6338   DONE;
6339  })
6341 (define_insn "macu_r"
6342   [(set (match_operand:SI 0 "register_operand" "=r,r")
6343         (truncate:SI
6344          (plus:DI
6345           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6346                    (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6347           (reg:DI ARCV2_ACC))))
6348    (clobber (reg:DI ARCV2_ACC))]
6349  "TARGET_PLUS_DMPY"
6350  "macu %0,%1,%2"
6351   [(set_attr "length" "4,8")
6352    (set_attr "type" "multi")
6353    (set_attr "predicable" "no")
6354    (set_attr "cond" "nocond")])
6356 (define_insn "mpyd_arcv2hs"
6357   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r")
6358         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "  0, c"))
6359                  (sign_extend:DI (match_operand:SI 2 "register_operand"  "  c, c"))))
6360    (set (reg:DI ARCV2_ACC)
6361         (mult:DI
6362           (sign_extend:DI (match_dup 1))
6363           (sign_extend:DI (match_dup 2))))]
6364   "TARGET_PLUS_MACD"
6365   "mpyd%? %0,%1,%2"
6366   [(set_attr "length" "4,4")
6367   (set_attr "iscompact" "false")
6368   (set_attr "type" "multi")
6369   (set_attr "predicable" "yes,no")
6370   (set_attr "cond" "canuse,nocond")])
6372 (define_insn "mpyd_imm_arcv2hs"
6373   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r,r,Rcr,  r")
6374         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "  0, c,0,  0,  c"))
6375                  (match_operand 2                   "immediate_operand"  "  L, L,I,Cal,Cal")))
6376    (set (reg:DI ARCV2_ACC)
6377         (mult:DI (sign_extend:DI (match_dup 1))
6378                  (match_dup 2)))]
6379   "TARGET_PLUS_MACD"
6380   "mpyd%? %0,%1,%2"
6381   [(set_attr "length" "4,4,4,8,8")
6382   (set_attr "iscompact" "false")
6383   (set_attr "type" "multi")
6384   (set_attr "predicable" "yes,no,no,yes,no")
6385   (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6387 (define_insn "mpydu_arcv2hs"
6388   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r")
6389         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "  0, c"))
6390                  (zero_extend:DI (match_operand:SI 2 "register_operand" "   c, c"))))
6391    (set (reg:DI ARCV2_ACC)
6392         (mult:DI (zero_extend:DI (match_dup 1))
6393                  (zero_extend:DI (match_dup 2))))]
6394   "TARGET_PLUS_MACD"
6395   "mpydu%? %0,%1,%2"
6396   [(set_attr "length" "4,4")
6397   (set_attr "iscompact" "false")
6398   (set_attr "type" "multi")
6399   (set_attr "predicable" "yes,no")
6400   (set_attr "cond" "canuse,nocond")])
6402 (define_insn "mpydu_imm_arcv2hs"
6403   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r,r,Rcr,  r")
6404         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "  0, c,0,  0,  c"))
6405                  (match_operand 2                   "immediate_operand"  "  L, L,I,Cal,Cal")))
6406    (set (reg:DI ARCV2_ACC)
6407         (mult:DI (zero_extend:DI (match_dup 1))
6408                  (match_dup 2)))]
6409   "TARGET_PLUS_MACD"
6410   "mpydu%? %0,%1,%2"
6411   [(set_attr "length" "4,4,4,8,8")
6412   (set_attr "iscompact" "false")
6413   (set_attr "type" "multi")
6414   (set_attr "predicable" "yes,no,no,yes,no")
6415   (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6417 (define_insn "stack_tie"
6418   [(set (mem:BLK (scratch))
6419         (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
6420                      (match_operand:SI 1 "register_operand" "rb")]
6421                     UNSPEC_ARC_STKTIE))]
6422   ""
6423   ""
6424   [(set_attr "length" "0")
6425    (set_attr "iscompact" "false")
6426    (set_attr "type" "block")]
6427   )
6429 ;; include the arc-FPX instructions
6430 (include "fpx.md")
6432 ;; include the arc-FPU instructions
6433 (include "fpu.md")
6435 (include "simdext.md")
6437 ;; include atomic extensions
6438 (include "atomic.md")