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