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