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