gcc/
[official-gcc.git] / gcc / config / arc / arc.md
blob931f9a1870382689c7eb07e93734ae645fa4f941
1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2015 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 ;;    Profiling support and performance improvements by
13 ;;    Joern Rennecke (joern.rennecke@embecosm.com)
15 ;;    Support for DSP multiply instructions and mul64
16 ;;    instructions for ARC600; and improvements in flag setting
17 ;;    instructions by
18 ;;    Muhammad Khurram Riaz (Khurram.Riaz@arc.com)
20 ;; This file is part of GCC.
22 ;; GCC is free software; you can redistribute it and/or modify
23 ;; it under the terms of the GNU General Public License as published by
24 ;; the Free Software Foundation; either version 3, or (at your option)
25 ;; any later version.
27 ;; GCC is distributed in the hope that it will be useful,
28 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
29 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30 ;; GNU General Public License for more details.
32 ;; You should have received a copy of the GNU General Public License
33 ;; along with GCC; see the file COPYING3.  If not see
34 ;; <http://www.gnu.org/licenses/>.
36 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
38 ;; <op> dest, src         Two operand instruction's syntax
39 ;; <op> dest, src1, src2  Three operand instruction's syntax
41 ;; ARC and ARCompact PREDICATES:
43 ;;   comparison_operator   LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE
44 ;;   memory_operand        memory                         [m]
45 ;;   immediate_operand     immediate constant             [IKLMNOP]
46 ;;   register_operand      register                       [rq]
47 ;;   general_operand       register, memory, constant     [rqmIKLMNOP]
49 ;;  Note that the predicates are only used when selecting a pattern
50 ;;  to determine if an operand is valid.
52 ;;  The constraints then select which of the possible valid operands
53 ;;  is present (and guide register selection). The actual assembly
54 ;;  instruction is then selected on the basis of the constraints.
56 ;; ARC and ARCompact CONSTRAINTS:
58 ;;   b  stack pointer                           r28
59 ;;   f  frame pointer                           r27
60 ;;   Rgp global pointer                         r26
61 ;;   g  general reg, memory, constant
62 ;;   m  memory
63 ;;   p  memory address
64 ;;   q  registers commonly used in
65 ;;      16-bit insns                            r0-r3, r12-r15
66 ;;   c  core registers                          r0-r60, ap, pcl
67 ;;   r  general registers                       r0-r28, blink, ap, pcl
69 ;;   H  fp 16-bit constant
70 ;;   I signed 12-bit immediate (for ARCompact)
71 ;;   K  unsigned 3-bit immediate (for ARCompact)
72 ;;   L  unsigned 6-bit immediate (for ARCompact)
73 ;;   M  unsinged 5-bit immediate (for ARCompact)
74 ;;   O  unsinged 7-bit immediate (for ARCompact)
75 ;;   P  unsinged 8-bit immediate (for ARCompact)
76 ;;   N  constant '1' (for ARCompact)
79 ;; TODO:
80 ;; -> prefetch instruction
82 ;;  -----------------------------------------------------------------------------
84 ;; Include DFA scheduluers
85 (include ("arc600.md"))
86 (include ("arc700.md"))
88 ;; Predicates
90 (include ("predicates.md"))
91 (include ("constraints.md"))
92 ;;  -----------------------------------------------------------------------------
94 ;; UNSPEC Usage:
95 ;; ~~~~~~~~~~~~
96 ;;  -----------------------------------------------------------------------------
97 ;;  Symbolic name  Value              Desc.
98 ;;  -----------------------------------------------------------------------------
99 ;;  UNSPEC_PLT       3        symbol to be referenced through the PLT
100 ;;  UNSPEC_GOT       4        symbol to be rerenced through the GOT
101 ;;  UNSPEC_GOTOFF    5        Local symbol.To be referenced relative to the
102 ;;                            GOTBASE.(Referenced as @GOTOFF)
103 ;;  ----------------------------------------------------------------------------
106 (define_constants
107   [(UNSPEC_SWAP 13) ; swap generation through builtins. candidate for scheduling
108    (UNSPEC_MUL64 14) ; mul64 generation through builtins. candidate for scheduling
109    (UNSPEC_MULU64 15) ; mulu64 generation through builtins. candidate for scheduling
110    (UNSPEC_DIVAW 16) ; divaw generation through builtins. candidate for scheduling
111    (UNSPEC_DIRECT 17)
112    (UNSPEC_PROF 18) ; profile callgraph counter
113    (UNSPEC_LP 19) ; to set LP_END
114    (UNSPEC_CASESI 20)
115    (VUNSPEC_RTIE 17) ; blockage insn for rtie generation
116    (VUNSPEC_SYNC 18) ; blockage insn for sync generation
117    (VUNSPEC_BRK 19) ; blockage insn for brk generation
118    (VUNSPEC_FLAG 20) ; blockage insn for flag generation
119    (VUNSPEC_SLEEP 21) ; blockage insn for sleep generation
120    (VUNSPEC_SWI 22) ; blockage insn for swi generation
121    (VUNSPEC_CORE_READ 23) ; blockage insn for reading a core register
122    (VUNSPEC_CORE_WRITE 24) ; blockage insn for writing to a core register
123    (VUNSPEC_LR 25) ; blockage insn for reading an auxiliary register
124    (VUNSPEC_SR 26) ; blockage insn for writing to an auxiliary register
125    (VUNSPEC_TRAP_S 27) ; blockage insn for trap_s generation
126    (VUNSPEC_UNIMP_S 28) ; blockage insn for unimp_s generation
128    (R0_REG 0)
129    (R1_REG 1)
130    (R2_REG 2)
131    (R3_REG 3)
132    (R12_REG 12)
133    (SP_REG 28)
134    (ILINK1_REGNUM 29)
135    (ILINK2_REGNUM 30)
136    (RETURN_ADDR_REGNUM 31)
137    (MUL64_OUT_REG 58)
139    (VUNSPEC_DEXCL 32) ; blockage insn for reading an auxiliary register without LR support
140    (VUNSPEC_DEXCL_NORES 33) ; blockage insn for reading an auxiliary register without LR support
141    (VUNSPEC_LR_HIGH 34) ; blockage insn for reading an auxiliary register
143    (LP_COUNT 60)
144    (CC_REG 61)
145    (LP_START 144)
146    (LP_END 145)
147   ]
150 (define_attr "is_sfunc" "no,yes" (const_string "no"))
152 ;; Insn type.  Used to default other attribute values.
153 ; While the attribute is_sfunc is set for any call of a special function,
154 ; the instruction type sfunc is used only for the special call sequence
155 ; that loads the (pc-relative) function address into r12 and then calls
156 ; via r12.
158 (define_attr "type"
159   "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
160    brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
161    multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
162    misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
163    simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
164    simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
165    simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
166    simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
167    simd_valign, simd_valign_with_acc, simd_vcontrol,
168    simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma"
169   (cond [(eq_attr "is_sfunc" "yes")
170          (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
171                 (match_test "flag_pic") (const_string "sfunc")]
172                (const_string "call_no_delay_slot"))]
173         (const_string "binary")))
175 ;; The following three attributes are mixed case so that they can be
176 ;; used conveniently with the CALL_ATTR macro.
177 (define_attr "is_CALL" "no,yes"
178   (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
179          (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
180         (const_string "no")))
182 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
184 (define_attr "is_NON_SIBCALL" "no,yes"
185   (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
186          (eq_attr "is_CALL" "yes") (const_string "yes")]
187         (const_string "no")))
190 ;; Attribute describing the processor
191 (define_attr "cpu" "none,A5,ARC600,ARC700"
192   (const (symbol_ref "arc_cpu_attr")))
194 ;; true for compact instructions (those with _s suffix)
195 ;; "maybe" means compact unless we conditionalize the insn.
196 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
197   (cond [(eq_attr "type" "sfunc")
198          (const_string "maybe")]
199         (const_string "false")))
202 ; Is there an instruction that we are actually putting into the delay slot?
203 (define_attr "delay_slot_filled" "no,yes"
204   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
205          (const_string "no")
206          (match_test "!TARGET_AT_DBR_CONDEXEC
207                       && JUMP_P (insn)
208                       && INSN_ANNULLED_BRANCH_P (insn)
209                       && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
210          (const_string "no")]
211         (const_string "yes")))
213 ; Is a delay slot present for purposes of shorten_branches?
214 ; We have to take the length of this insn into account for forward branches
215 ; even if we don't put the insn actually into a delay slot.
216 (define_attr "delay_slot_present" "no,yes"
217   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
218          (const_string "no")]
219         (const_string "yes")))
221 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
222 ; length of a different insn with the same uid.
223 (define_attr "delay_slot_length" ""
224   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
225          (const_int 0)]
226         (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
227                      - get_attr_length (insn)")))
230 (define_attr "enabled" "no,yes" (const_string "yes"))
232 (define_attr "predicable" "no,yes" (const_string "no"))
233 ;; if 'predicable' were not so brain-dead, we would specify:
234 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
235 ;;        (eq_attr "iscompact" "maybe") (const_string "no")]
236 ;;       (const_string "yes"))
237 ;; and then for everything but calls, we could just set the cond attribute.
239 ;; Condition codes: this one is used by final_prescan_insn to speed up
240 ;; conditionalizing instructions.  It saves having to scan the rtl to see if
241 ;; it uses or alters the condition codes.
243 ;; USE: This insn uses the condition codes (eg: a conditional branch).
244 ;; CANUSE: This insn can use the condition codes (for conditional execution).
245 ;; SET: All condition codes are set by this insn.
246 ;; SET_ZN: the Z and N flags are set by this insn.
247 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
248 ;; CLOB: The condition codes are set to unknown values by this insn.
249 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
251 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
252   (cond
253     [(and (eq_attr "predicable" "yes")
254           (eq_attr "is_sfunc" "no")
255           (eq_attr "delay_slot_filled" "no"))
256      (const_string "canuse")
258      (eq_attr "type" "call")
259      (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
260             (match_test "!flag_pic") (const_string "canuse_limm")]
261            (const_string "nocond"))
263      (eq_attr "iscompact" "maybe,false")
264      (cond [ (and (eq_attr "type" "move")
265                   (match_operand 1 "immediate_operand" ""))
266              (if_then_else
267                 (ior (match_operand 1 "u6_immediate_operand" "")
268                      (match_operand 1 "long_immediate_operand" ""))
269                 (const_string "canuse")
270                 (const_string "canuse_limm"))
272              (eq_attr "type" "binary")
273              (cond [(ne (symbol_ref "REGNO (operands[0])")
274                         (symbol_ref "REGNO (operands[1])"))
275                     (const_string "nocond")
276                     (match_operand 2 "register_operand" "")
277                     (const_string "canuse")
278                     (match_operand 2 "u6_immediate_operand" "")
279                     (const_string "canuse")
280                     (match_operand 2 "long_immediate_operand" "")
281                     (const_string "canuse")
282                     (match_operand 2 "const_int_operand" "")
283                     (const_string "canuse_limm")]
284                    (const_string "nocond"))
286              (eq_attr "type" "compare")
287              (const_string "set")
289              (eq_attr "type" "cmove,branch")
290              (const_string "use")
292              (eq_attr "is_sfunc" "yes")
293              (cond [(match_test "(TARGET_MEDIUM_CALLS
294                                   && !TARGET_LONG_CALLS_SET
295                                   && flag_pic)")
296                     (const_string "canuse_limm_add")
297                     (match_test "(TARGET_MEDIUM_CALLS
298                                   && !TARGET_LONG_CALLS_SET)")
299                     (const_string "canuse_limm")]
300                    (const_string "canuse"))
302             ]
304             (const_string "nocond"))]
306       (cond [(eq_attr "type" "compare")
307              (const_string "set")
309              (eq_attr "type" "cmove,branch")
310              (const_string "use")
312             ]
314             (const_string "nocond"))))
316 /* ??? Having all these patterns gives ifcvt more freedom to generate
317    inefficient code.  It seem to operate on the premise that
318    register-register copies and registers are free.  I see better code
319    with -fno-if-convert now than without.  */
320 (define_cond_exec
321   [(match_operator 0 "proper_comparison_operator"
322      [(reg CC_REG) (const_int 0)])]
323   "true"
324   "")
326 ;; Length (in # of bytes, long immediate constants counted too).
327 ;; ??? There's a nasty interaction between the conditional execution fsm
328 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
329 (define_attr "length" ""
330   (cond
331     [(eq_attr "iscompact" "true,maybe")
332      (cond
333        [(eq_attr "type" "sfunc")
334         (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
335                (const_int 12)]
336               (const_int 10))
337         (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)]
338       (const_int 2))
340     (eq_attr "iscompact" "true_limm,maybe_limm")
341     (const_int 6)
343     (eq_attr "type" "load")
344     (if_then_else
345        (match_operand 1 "long_immediate_loadstore_operand" "")
346        (const_int 8) (const_int 4))
348     (eq_attr "type" "store")
349     (if_then_else
350       (ior (match_operand 0 "long_immediate_loadstore_operand" "")
351            (match_operand 1 "immediate_operand" ""))
352       (const_int 8) (const_int 4))
354     (eq_attr "type" "move,unary")
355     (cond
356       [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
357        (match_operand 1 "register_operand" "") (const_int 4)
358        (match_operand 1 "long_immediate_operand" "") (const_int 8)
359        (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
360       (const_int 4))
362     (and (eq_attr "type" "shift")
363          (match_operand 1 "immediate_operand"))
364                  (const_int 8)
365     (eq_attr "type" "binary,shift")
366     (if_then_else
367        (ior (match_operand 2 "long_immediate_operand" "")
368             (and (ne (symbol_ref "REGNO (operands[0])")
369                      (symbol_ref "REGNO (operands[1])"))
370                  (eq (match_operand 2 "u6_immediate_operand" "")
371                      (const_int 0))))
373        (const_int 8) (const_int 4))
375     (eq_attr "type" "cmove")
376        (if_then_else (match_operand 1 "register_operand" "")
377                      (const_int 4) (const_int 8))
379     (eq_attr "type" "call_no_delay_slot") (const_int 8)
380    ]
382    (const_int 4))
385 ;; The length here is the length of a single asm.  Unfortunately it might be
386 ;; 4 or 8 so we must allow for 8.  That's ok though.  How often will users
387 ;; lament asm's not being put in delay slots?
389 (define_asm_attributes
390   [(set_attr "length" "8")
391    (set_attr "type" "multi")
392    (set_attr "cond" "clob") ])
394 ;; Delay slots.
395 ;; The first two cond clauses and the default are necessary for correctness;
396 ;; the remaining cond clause is mainly an optimization, as otherwise nops
397 ;; would be inserted; however, if we didn't do this optimization, we would
398 ;; have to be more conservative in our length calculations.
400 (define_attr "in_delay_slot" "false,true"
401   (cond [(eq_attr "type" "uncond_branch,jump,branch,
402                           call,sfunc,call_no_delay_slot,
403                           brcc, brcc_no_delay_slot,loop_setup,loop_end")
404          (const_string "false")
405          (match_test "arc_write_ext_corereg (insn)")
406          (const_string "false")
407          (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
408                                       next_active_insn (insn))")
409              (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
410                            + arc_hazard (insn, next_active_insn (insn)))"))
411          (const_string "false")
412          (eq_attr "iscompact" "maybe") (const_string "true")
413          ]
415          (if_then_else (eq_attr "length" "2,4")
416                        (const_string "true")
417                        (const_string "false"))))
419 ; must not put an insn inside that refers to blink.
420 (define_attr "in_call_delay_slot" "false,true"
421   (cond [(eq_attr "in_delay_slot" "false")
422          (const_string "false")
423          (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
424          (const_string "false")]
425         (const_string "true")))
427 (define_attr "in_sfunc_delay_slot" "false,true"
428   (cond [(eq_attr "in_call_delay_slot" "false")
429          (const_string "false")
430          (match_test "arc_regno_use_in (12, PATTERN (insn))")
431          (const_string "false")]
432         (const_string "true")))
434 ;; Instructions that we can put into a delay slot and conditionalize.
435 (define_attr "cond_delay_insn" "no,yes"
436   (cond [(eq_attr "cond" "!canuse") (const_string "no")
437          (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
438          (const_string "no")
439          (eq_attr "length" "2,4") (const_string "yes")]
440         (const_string "no")))
442 (define_attr "in_ret_delay_slot" "no,yes"
443   (cond [(eq_attr "in_delay_slot" "false")
444          (const_string "no")
445          (match_test "regno_clobbered_p
446                         (arc_return_address_regs
447                           [arc_compute_function_type (cfun)],
448                          insn, SImode, 1)")
449          (const_string "no")]
450         (const_string "yes")))
452 (define_attr "cond_ret_delay_insn" "no,yes"
453   (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
454          (eq_attr "cond_delay_insn" "no") (const_string "no")]
455         (const_string "yes")))
457 (define_attr "annul_ret_delay_insn" "no,yes"
458   (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
459          (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
460          (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
461            (const_string "yes")]
462    (const_string "no")))
465 ;; Delay slot definition for ARCompact ISA
466 ;; ??? FIXME:
467 ;; When outputting an annul-true insn elegible for cond-exec
468 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
469 ;; for ARC600; we could also use this for ARC700 if the branch can't be
470 ;; unaligned and is at least somewhat likely (add parameter for this).
472 (define_delay (eq_attr "type" "call")
473   [(eq_attr "in_call_delay_slot" "true")
474    (eq_attr "in_call_delay_slot" "true")
475    (nil)])
477 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
478                    (eq_attr "type" "brcc"))
479   [(eq_attr "in_delay_slot" "true")
480    (eq_attr "in_delay_slot" "true")
481    (nil)])
483 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
484                    (eq_attr "type" "brcc"))
485   [(eq_attr "in_delay_slot" "true")
486    (nil)
487    (nil)])
489 (define_delay
490   (eq_attr "type" "return")
491   [(eq_attr "in_ret_delay_slot" "yes")
492    (eq_attr "annul_ret_delay_insn" "yes")
493    (eq_attr "cond_ret_delay_insn" "yes")])
495 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
496 ;; non-taken case, so the only meaningful way to have an annull-true
497 ;; filled delay slot is to conditionalize the delay slot insn.
498 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
499                    (eq_attr "type" "branch,uncond_branch,jump")
500                    (match_test "!optimize_size"))
501   [(eq_attr "in_delay_slot" "true")
502    (eq_attr "cond_delay_insn" "yes")
503    (eq_attr "cond_delay_insn" "yes")])
505 ;; For ARC700, anything goes for annulled-true insns, since there is no
506 ;; penalty for the unexposed delay slot when the branch is not taken,
507 ;; however, we must avoid things that have a delay slot themselvese to
508 ;; avoid confusing gcc.
509 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
510                    (eq_attr "type" "branch,uncond_branch,jump")
511                    (match_test "!optimize_size"))
512   [(eq_attr "in_delay_slot" "true")
513    (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
514    (eq_attr "cond_delay_insn" "yes")])
516 ;; -mlongcall -fpic sfuncs use r12 to load the function address
517 (define_delay (eq_attr "type" "sfunc")
518   [(eq_attr "in_sfunc_delay_slot" "true")
519    (eq_attr "in_sfunc_delay_slot" "true")
520    (nil)])
521 ;; ??? need to use a working strategy for canuse_limm:
522 ;; - either canuse_limm is not eligible for delay slots, and has no
523 ;;   delay slots, or arc_reorg has to treat them as nocond, or it has to
524 ;;   somehow modify them to become inelegible for delay slots if a decision
525 ;;   is made that makes conditional execution required.
527 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
528   (const
529    (cond [(symbol_ref "arc_tune == TUNE_ARC600")
530           (const_string "arc600")
531           (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
532           (const_string "arc700_4_2_std")
533           (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
534           (const_string "arc700_4_2_xmac")]
535          (const_string "none"))))
537 (define_attr "tune_arc700" "false,true"
538   (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
539                 (const_string "true")
540                 (const_string "false")))
542 ;; Move instructions.
543 (define_expand "movqi"
544   [(set (match_operand:QI 0 "move_dest_operand" "")
545         (match_operand:QI 1 "general_operand" ""))]
546   ""
547   "if (prepare_move_operands (operands, QImode)) DONE;")
549 ; In order to allow the ccfsm machinery to do its work, the leading compact
550 ; alternatives say 'canuse' - there is another alternative that will match
551 ; when the condition codes are used.
552 ; Rcq won't match if the condition is actually used; to avoid a spurious match
553 ; via q, q is inactivated as constraint there.
554 ; Likewise, the length of an alternative that might be shifted to conditional
555 ; execution must reflect this, lest out-of-range branches are created.
556 ; The iscompact attribute allows the epilogue expander to know for which
557 ; insns it should lengthen the return insn.
558 (define_insn "*movqi_insn"
559   [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
560         (match_operand:QI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
561   "register_operand (operands[0], QImode)
562    || register_operand (operands[1], QImode)"
563   "@
564    mov%? %0,%1%&
565    mov%? %0,%1%&
566    mov%? %0,%1%&
567    mov%? %0,%1
568    mov%? %0,%1
569    mov%? %0,%1
570    mov%? %0,%S1
571    ldb%? %0,%1%&
572    stb%? %1,%0%&
573    ldb%? %0,%1%&
574    ldb%U1%V1 %0,%1
575    stb%U0%V0 %1,%0
576    stb%U0%V0 %1,%0"
577   [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
578    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
579    (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no")])
581 (define_expand "movhi"
582   [(set (match_operand:HI 0 "move_dest_operand" "")
583         (match_operand:HI 1 "general_operand" ""))]
584   ""
585   "if (prepare_move_operands (operands, HImode)) DONE;")
587 (define_insn "*movhi_insn"
588   [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
589         (match_operand:HI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,  ?i,?i,T,Rcq,m,c,?Rac,i"))]
590   "register_operand (operands[0], HImode)
591    || register_operand (operands[1], HImode)
592    || (CONSTANT_P (operands[1])
593        /* Don't use a LIMM that we could load with a single insn - we loose
594           delay-slot filling opportunities.  */
595        && !satisfies_constraint_I (operands[1])
596        && satisfies_constraint_Usc (operands[0]))"
597   "@
598    mov%? %0,%1%&
599    mov%? %0,%1%&
600    mov%? %0,%1%&
601    mov%? %0,%1
602    mov%? %0,%1
603    mov%? %0,%1
604    mov%? %0,%S1%&
605    mov%? %0,%S1
606    ldw%? %0,%1%&
607    stw%? %1,%0%&
608    ldw%U1%V1 %0,%1
609    stw%U0%V0 %1,%0
610    stw%U0%V0 %1,%0
611    stw%U0%V0 %S1,%0"
612   [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
613    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
614    (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no")])
616 (define_expand "movsi"
617   [(set (match_operand:SI 0 "move_dest_operand" "")
618         (match_operand:SI 1 "general_operand" ""))]
619   ""
620   "if (prepare_move_operands (operands, SImode)) DONE;")
622 ; In order to allow the ccfsm machinery to do its work, the leading compact
623 ; alternatives say 'canuse' - there is another alternative that will match
624 ; when the condition codes are used.
625 ; Rcq won't match if the condition is actually used; to avoid a spurious match
626 ; via q, q is inactivated as constraint there.
627 ; Likewise, the length of an alternative that might be shifted to conditional
628 ; execution must reflect this, lest out-of-range branches are created.
629 ; the iscompact attribute allows the epilogue expander to know for which
630 ; insns it should lengthen the return insn.
631 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
632 (define_insn "*movsi_insn"
633   [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,m,???m,VUsc")
634         (match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,m,c,?Rac,C32"))]
635   "register_operand (operands[0], SImode)
636    || register_operand (operands[1], SImode)
637    || (CONSTANT_P (operands[1])
638        /* Don't use a LIMM that we could load with a single insn - we loose
639           delay-slot filling opportunities.  */
640        && !satisfies_constraint_I (operands[1])
641        && satisfies_constraint_Usc (operands[0]))"
642   "@
643    mov%? %0,%1%&        ;0
644    mov%? %0,%1%&        ;1
645    mov%? %0,%1%&        ;2
646    mov%? %0,%1          ;3
647    mov%? %0,%1          ;4
648    ror %0,((%1*2+1) & 0x3f) ;5
649    mov%? %0,%1          ;6
650    add %0,%S1           ;7
651    * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
652    mov%? %0,%S1%&       ;9
653    mov%? %0,%S1         ;10
654    ld%? %0,%1%&         ;11
655    st%? %1,%0%&         ;12
656    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
657    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
658    ld%? %0,%1%&         ;15
659    ld%U1%V1 %0,%1       ;16
660    st%U0%V0 %1,%0       ;17
661    st%U0%V0 %1,%0       ;18
662    st%U0%V0 %S1,%0      ;19"
663   [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,store,store,store")
664    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
665    ; Use default length for iscompact to allow for COND_EXEC.  But set length
666    ; of Crr to 4.
667    (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
668    (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no")])
670 ;; Sometimes generated by the epilogue code.  We don't want to
671 ;; recognize these addresses in general, because the limm is costly,
672 ;; and we can't use them for stores.  */
673 (define_insn "*movsi_pre_mod"
674   [(set (match_operand:SI 0 "register_operand" "=w")
675         (mem:SI (pre_modify
676                   (reg:SI SP_REG)
677                   (plus:SI (reg:SI SP_REG)
678                            (match_operand 1 "immediate_operand" "Cal")))))]
679   "reload_completed"
680   "ld.a %0,[sp,%1]"
681   [(set_attr "type" "load")
682    (set_attr "length" "8")])
684 ;; Store a value to directly to memory.  The location might also be cached.
685 ;; Since the cached copy can cause a write-back at unpredictable times,
686 ;; we first write cached, then we write uncached.
687 (define_insn "store_direct"
688   [(set (match_operand:SI 0 "move_dest_operand" "=m")
689       (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
690        UNSPEC_DIRECT))]
691   ""
692   "st%U0 %1,%0\;st%U0.di %1,%0"
693   [(set_attr "type" "store")])
695 (define_insn_and_split "*movsi_set_cc_insn"
696   [(set (match_operand:CC_ZN 2 "cc_set_register" "")
697         (match_operator 3 "zn_compare_operator"
698           [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
699    (set (match_operand:SI 0 "register_operand" "=w,w,w")
700         (match_dup 1))]
701   ""
702   "mov%?.f %0,%S1"
703   ; splitting to 'tst' allows short insns and combination into brcc.
704   "reload_completed && operands_match_p (operands[0], operands[1])"
705   [(set (match_dup 2) (match_dup 3))]
706   ""
707   [(set_attr "type" "compare")
708    (set_attr "predicable" "no,yes,yes")
709    (set_attr "cond" "set_zn")
710    (set_attr "length" "4,4,8")])
712 (define_insn "unary_comparison"
713   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
714         (match_operator 3 "zn_compare_operator"
715           [(match_operator:SI 2 "unary_operator"
716              [(match_operand:SI 1 "register_operand" "c")])
717            (const_int 0)]))]
718   ""
719   "%O2.f 0,%1"
720   [(set_attr "type" "compare")
721    (set_attr "cond" "set_zn")])
724 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
725 (define_insn "*unary_comparison_result_used"
726   [(set (match_operand 2 "cc_register" "")
727         (match_operator 4 "zn_compare_operator"
728           [(match_operator:SI 3 "unary_operator"
729              [(match_operand:SI 1 "register_operand" "c")])
730                (const_int 0)]))
731    (set (match_operand:SI 0 "register_operand" "=w")
732         (match_dup 3))]
733   ""
734   "%O3.f %0,%1"
735   [(set_attr "type" "compare")
736    (set_attr "cond" "set_zn")
737    (set_attr "length" "4")])
739 (define_insn "*tst"
740   [(set
741      (match_operand 0 "cc_register" "")
742      (match_operator 3 "zn_compare_operator"
743        [(and:SI
744           (match_operand:SI 1 "register_operand"
745            "%Rcq,Rcq, c, c, c,  c,  c,  c")
746           (match_operand:SI 2 "nonmemory_operand"
747            " Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal"))
748         (const_int 0)]))]
749   "(register_operand (operands[1], SImode)
750     && nonmemory_operand (operands[2], SImode))
751    || (memory_operand (operands[1], SImode)
752        && satisfies_constraint_Cux (operands[2]))"
753   "*
754     switch (which_alternative)
755     {
756     case 0: case 2: case 3: case 7:
757       return \"tst%? %1,%2\";
758     case 1:
759       return \"btst%? %1,%z2\";
760     case 4:
761       return \"bmsk%?.f 0,%1,%Z2%&\";
762     case 5:
763       return \"bclr%?.f 0,%1,%M2%&\";
764     case 6:
765       return \"bic%?.f 0,%1,%n2-1\";
766     default:
767       gcc_unreachable ();
768     }
769   "
770   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
771    (set_attr "type" "compare")
772    (set_attr "length" "*,*,4,4,4,4,4,8")
773    (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
774    (set_attr "cond" "set_zn")])
776 (define_insn "*commutative_binary_comparison"
777   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
778         (match_operator 5 "zn_compare_operator"
779           [(match_operator:SI 4 "commutative_operator"
780              [(match_operand:SI 1 "register_operand" "%c,c,c")
781               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
782            (const_int 0)]))
783    (clobber (match_scratch:SI 3 "=X,1,X"))]
784   ""
785   "%O4.f 0,%1,%2"
786   [(set_attr "type" "compare")
787    (set_attr "cond" "set_zn")
788    (set_attr "length" "4,4,8")])
790 ; for flag setting 'add' instructions like if (a+b) { ...}
791 ; the combiner needs this pattern
792 (define_insn "*addsi_compare"
793   [(set (reg:CC_ZN CC_REG)
794         (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
795                        (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
796   ""
797   "add.f 0,%0,%1"
798   [(set_attr "cond" "set")
799    (set_attr "type" "compare")
800    (set_attr "length" "4")])
802 ; for flag setting 'add' instructions like if (a+b < a) { ...}
803 ; the combiner needs this pattern
804 (define_insn "addsi_compare_2"
805   [(set (reg:CC_C CC_REG)
806         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
807                                (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
808                       (match_dup 0)))]
809   ""
810   "add.f 0,%0,%1"
811   [(set_attr "cond" "set")
812    (set_attr "type" "compare")
813    (set_attr "length" "4,8")])
815 (define_insn "*addsi_compare_3"
816   [(set (reg:CC_C CC_REG)
817         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
818                                (match_operand:SI 1 "register_operand" "c"))
819                       (match_dup 1)))]
820   ""
821   "add.f 0,%0,%1"
822   [(set_attr "cond" "set")
823    (set_attr "type" "compare")
824    (set_attr "length" "4")])
826 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
827 (define_insn "*commutative_binary_comparison_result_used"
828   [(set (match_operand 3 "cc_register" "")
829         (match_operator 5 "zn_compare_operator"
830           ; We can accept any commutative operator except mult because
831           ; our 'w' class below could try to use LP_COUNT.
832           [(match_operator:SI 4 "commutative_operator_sans_mult"
833              [(match_operand:SI 1 "register_operand" "c,0,c")
834               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
835            (const_int 0)]))
836    (set (match_operand:SI 0 "register_operand" "=w,w,w")
837         (match_dup 4))]
838   ""
839   "%O4.f %0,%1,%2 ; non-mult commutative"
840   [(set_attr "type" "compare,compare,compare")
841    (set_attr "cond" "set_zn,set_zn,set_zn")
842    (set_attr "length" "4,4,8")])
844 ; a MULT-specific version of this pattern to avoid touching the
845 ; LP_COUNT register
846 (define_insn "*commutative_binary_mult_comparison_result_used"
847   [(set (match_operand 3 "cc_register" "")
848         (match_operator 5 "zn_compare_operator"
849           [(match_operator:SI 4 "mult_operator"
850              [(match_operand:SI 1 "register_operand" "c,0,c")
851               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
852            (const_int 0)]))
853         ; Make sure to use the W class to not touch LP_COUNT.
854    (set (match_operand:SI 0 "register_operand" "=W,W,W")
855         (match_dup 4))]
856   "TARGET_ARC700"
857   "%O4.f %0,%1,%2 ; mult commutative"
858   [(set_attr "type" "compare,compare,compare")
859    (set_attr "cond" "set_zn,set_zn,set_zn")
860    (set_attr "length" "4,4,8")])
862 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
863 (define_insn "*noncommutative_binary_comparison_result_used"
864   [(set (match_operand 3 "cc_register" "")
865         (match_operator 5 "zn_compare_operator"
866           [(match_operator:SI 4 "noncommutative_operator"
867              [(match_operand:SI 1 "register_operand" "c,0,c")
868               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
869                (const_int 0)]))
870    (set (match_operand:SI 0 "register_operand" "=w,w,w")
871         (match_dup 4 ))]
872   "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
873   "%O4.f %0,%1,%2"
874   [(set_attr "type" "compare,compare,compare")
875    (set_attr "cond" "set_zn,set_zn,set_zn")
876    (set_attr "length" "4,4,8")])
878 (define_insn "*noncommutative_binary_comparison"
879   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
880         (match_operator 5 "zn_compare_operator"
881           [(match_operator:SI 4 "noncommutative_operator"
882              [(match_operand:SI 1 "register_operand" "c,c,c")
883               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
884            (const_int 0)]))
885    (clobber (match_scratch:SI 3 "=X,1,X"))]
886   "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
887   "%O4.f 0,%1,%2"
888   [(set_attr "type" "compare")
889    (set_attr "cond" "set_zn")
890    (set_attr "length" "4,4,8")])
892 (define_expand "bic_f_zn"
893   [(parallel
894      [(set (reg:CC_ZN CC_REG)
895            (compare:CC_ZN
896              (and:SI (match_operand:SI 1 "register_operand" "")
897                      (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
898            (const_int 0)))
899       (set (match_operand:SI 0 "register_operand" "")
900            (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
901   "")
903 (define_insn "*bic_f"
904   [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
905         (match_operator 4 "zn_compare_operator"
906           [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
907                    (not:SI
908                      (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
909            (const_int 0)]))
910    (set (match_operand:SI 0 "register_operand" "=w,w,w")
911         (and:SI (match_dup 1) (not:SI (match_dup 2))))]
912   ""
913   "bic.f %0,%1,%2"
914   [(set_attr "type" "compare,compare,compare")
915    (set_attr "cond" "set_zn,set_zn,set_zn")
916    (set_attr "length" "4,4,8")])
918 (define_expand "movdi"
919   [(set (match_operand:DI 0 "move_dest_operand" "")
920         (match_operand:DI 1 "general_operand" ""))]
921   ""
922   "
924   /* Everything except mem = const or mem = mem can be done easily.  */
926   if (GET_CODE (operands[0]) == MEM)
927     operands[1] = force_reg (DImode, operands[1]);
930 (define_insn_and_split "*movdi_insn"
931   [(set (match_operand:DI 0 "move_dest_operand" "=w,w,r,m")
932         (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
933   "register_operand (operands[0], DImode)
934    || register_operand (operands[1], DImode)"
935   "*
937   switch (which_alternative)
938     {
939     default:
940     case 0 :
941       /* We normally copy the low-numbered register first.  However, if
942          the first register operand 0 is the same as the second register of
943          operand 1, we must copy in the opposite order.  */
944       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
945         return \"mov%? %R0,%R1\;mov%? %0,%1\";
946       else
947       return \"mov%? %0,%1\;mov%? %R0,%R1\";
948     case 1 :
949       return \"mov%? %L0,%L1\;mov%? %H0,%H1\";
950     case 2 :
951       /* If the low-address word is used in the address, we must load it
952          last.  Otherwise, load it first.  Note that we cannot have
953          auto-increment in that case since the address register is known to be
954          dead.  */
955       if (refers_to_regno_p (REGNO (operands[0]), operands[1]))
956         return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
957       else switch (GET_CODE (XEXP(operands[1], 0)))
958         {
959         case POST_MODIFY: case POST_INC: case POST_DEC:
960           return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\";
961         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
962           return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\";
963         default:
964           return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\";
965         }
966     case 3 :
967       switch (GET_CODE (XEXP(operands[0], 0)))
968         {
969         case POST_MODIFY: case POST_INC: case POST_DEC:
970           return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\";
971         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
972           return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\";
973         default:
974           return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\";
975         }
976     }
978   "&& reload_completed && optimize"
979   [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
980   "arc_split_move (operands);"
981   [(set_attr "type" "move,move,load,store")
982    ;; ??? The ld/st values could be 4 if it's [reg,bignum].
983    (set_attr "length" "8,16,16,16")])
986 ;; Floating point move insns.
988 (define_expand "movsf"
989   [(set (match_operand:SF 0 "general_operand" "")
990         (match_operand:SF 1 "general_operand" ""))]
991   ""
992   "if (prepare_move_operands (operands, SFmode)) DONE;")
994 (define_insn "*movsf_insn"
995   [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m")
996         (match_operand:SF 1 "move_src_operand" "c,E,m,c"))]
997   "register_operand (operands[0], SFmode)
998    || register_operand (operands[1], SFmode)"
999   "@
1000    mov%? %0,%1
1001    mov%? %0,%1 ; %A1
1002    ld%U1%V1 %0,%1
1003    st%U0%V0 %1,%0"
1004   [(set_attr "type" "move,move,load,store")
1005    (set_attr "predicable" "yes,yes,no,no")])
1007 (define_expand "movdf"
1008   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1009         (match_operand:DF 1 "general_operand" ""))]
1010   ""
1011   "if (prepare_move_operands (operands, DFmode)) DONE;")
1013 (define_insn "*movdf_insn"
1014   [(set (match_operand:DF 0 "move_dest_operand"      "=D,r,c,c,r,m")
1015         (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1016   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1017   "#"
1018   [(set_attr "type" "move,move,move,move,load,store")
1019    (set_attr "predicable" "no,no,yes,yes,no,no")
1020    ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1021    (set_attr "length" "4,16,8,16,16,16")])
1023 (define_split
1024   [(set (match_operand:DF 0 "move_dest_operand" "")
1025         (match_operand:DF 1 "move_double_src_operand" ""))]
1026   "reload_completed"
1027   [(match_dup 2)]
1028   "operands[2] = arc_split_move (operands);")
1030 (define_insn_and_split "*movdf_insn_nolrsr"
1031   [(set (match_operand:DF 0 "register_operand"       "=r")
1032         (match_operand:DF 1 "arc_double_register_operand" "D"))
1033    (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1034    ]
1035   "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1036   "#"
1037   "&& 1"
1038   [
1039     ; mov r0, 0
1040     (set (match_dup 0) (match_dup 3))
1042     ; daddh?? r1, r0, r0
1043     (parallel [
1044         (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1045         (use (const_int 1))
1046         (use (const_int 1))
1047         (use (match_dup 0)) ; used to block can_combine_p
1048         (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1049     ])
1051     ; We have to do this twice, once to read the value into R0 and
1052     ; second time to put back the contents which the first DEXCLx
1053     ; will have overwritten
1054     ; dexcl2 r0, r1, r0
1055     (set (match_dup 4) ; aka r0result
1056          ; aka DF, r1, r0
1057          (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_DEXCL ))
1058     ; Generate the second, which makes sure operand5 and operand4 values
1059     ; are put back in the Dx register properly.
1060     (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_DEXCL_NORES )
1062     ; Note: we cannot use a (clobber (match_scratch)) here because
1063     ; the combine pass will end up replacing uses of it with 0
1064   ]
1065   "operands[3] = CONST0_RTX (DFmode);
1066    operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1067    operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1068   [(set_attr "type" "move")])
1070 ;; Load/Store with update instructions.
1072 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1073 ;; hardware can also do cases where the increment is not the size of the
1074 ;; object.
1076 ;; In all these cases, we use operands 0 and 1 for the register being
1077 ;; incremented because those are the operands that local-alloc will
1078 ;; tie and these are the pair most likely to be tieable (and the ones
1079 ;; that will benefit the most).
1081 ;; We use match_operator here because we need to know whether the memory
1082 ;; object is volatile or not.
1085 ;; Note: loadqi_update has no 16-bit variant
1086 (define_insn "*loadqi_update"
1087   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1088         (match_operator:QI 4 "load_update_operand"
1089          [(match_operand:SI 1 "register_operand" "0,0")
1090           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1091    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1092         (plus:SI (match_dup 1) (match_dup 2)))]
1093   ""
1094   "ldb.a%V4 %3,[%0,%S2]"
1095   [(set_attr "type" "load,load")
1096    (set_attr "length" "4,8")])
1098 (define_insn "*load_zeroextendqisi_update"
1099   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1100         (zero_extend:SI (match_operator:QI 4 "load_update_operand"
1101                          [(match_operand:SI 1 "register_operand" "0,0")
1102                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1103    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1104         (plus:SI (match_dup 1) (match_dup 2)))]
1105   ""
1106   "ldb.a%V4 %3,[%0,%S2]"
1107   [(set_attr "type" "load,load")
1108    (set_attr "length" "4,8")])
1110 (define_insn "*load_signextendqisi_update"
1111   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1112         (sign_extend:SI (match_operator:QI 4 "load_update_operand"
1113                          [(match_operand:SI 1 "register_operand" "0,0")
1114                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1115    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1116         (plus:SI (match_dup 1) (match_dup 2)))]
1117   ""
1118   "ldb.x.a%V4 %3,[%0,%S2]"
1119   [(set_attr "type" "load,load")
1120    (set_attr "length" "4,8")])
1122 (define_insn "*storeqi_update"
1123   [(set (match_operator:QI 4 "store_update_operand"
1124          [(match_operand:SI 1 "register_operand" "0")
1125           (match_operand:SI 2 "short_immediate_operand" "I")])
1126         (match_operand:QI 3 "register_operand" "c"))
1127    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1128         (plus:SI (match_dup 1) (match_dup 2)))]
1129   ""
1130   "stb.a%V4 %3,[%0,%2]"
1131   [(set_attr "type" "store")
1132    (set_attr "length" "4")])
1134 ;; ??? pattern may have to be re-written
1135 ;; Note: no 16-bit variant for this pattern
1136 (define_insn "*loadhi_update"
1137   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1138         (match_operator:HI 4 "load_update_operand"
1139          [(match_operand:SI 1 "register_operand" "0,0")
1140           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1141    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1142         (plus:SI (match_dup 1) (match_dup 2)))]
1143   ""
1144   "ldw.a%V4 %3,[%0,%S2]"
1145   [(set_attr "type" "load,load")
1146    (set_attr "length" "4,8")])
1148 (define_insn "*load_zeroextendhisi_update"
1149   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1150         (zero_extend:SI (match_operator:HI 4 "load_update_operand"
1151                          [(match_operand:SI 1 "register_operand" "0,0")
1152                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1153    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1154         (plus:SI (match_dup 1) (match_dup 2)))]
1155   ""
1156   "ldw.a%V4 %3,[%0,%S2]"
1157   [(set_attr "type" "load,load")
1158    (set_attr "length" "4,8")])
1160 ;; Note: no 16-bit variant for this instruction
1161 (define_insn "*load_signextendhisi_update"
1162   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1163         (sign_extend:SI (match_operator:HI 4 "load_update_operand"
1164                          [(match_operand:SI 1 "register_operand" "0,0")
1165                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1166    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1167         (plus:SI (match_dup 1) (match_dup 2)))]
1168   ""
1169   "ldw.x.a%V4 %3,[%0,%S2]"
1170   [(set_attr "type" "load,load")
1171    (set_attr "length" "4,8")])
1173 (define_insn "*storehi_update"
1174   [(set (match_operator:HI 4 "store_update_operand"
1175          [(match_operand:SI 1 "register_operand" "0")
1176           (match_operand:SI 2 "short_immediate_operand" "I")])
1177         (match_operand:HI 3 "register_operand" "c"))
1178    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1179         (plus:SI (match_dup 1) (match_dup 2)))]
1180   ""
1181   "stw.a%V4 %3,[%0,%2]"
1182   [(set_attr "type" "store")
1183    (set_attr "length" "4")])
1185 ;; No 16-bit variant for this instruction pattern
1186 (define_insn "*loadsi_update"
1187   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1188         (match_operator:SI 4 "load_update_operand"
1189          [(match_operand:SI 1 "register_operand" "0,0")
1190           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1191    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1192         (plus:SI (match_dup 1) (match_dup 2)))]
1193   ""
1194   "ld.a%V4 %3,[%0,%S2]"
1195   [(set_attr "type" "load,load")
1196    (set_attr "length" "4,8")])
1198 (define_insn "*storesi_update"
1199   [(set (match_operator:SI 4 "store_update_operand"
1200          [(match_operand:SI 1 "register_operand" "0")
1201           (match_operand:SI 2 "short_immediate_operand" "I")])
1202         (match_operand:SI 3 "register_operand" "c"))
1203    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1204         (plus:SI (match_dup 1) (match_dup 2)))]
1205   ""
1206   "st.a%V4 %3,[%0,%2]"
1207   [(set_attr "type" "store")
1208    (set_attr "length" "4")])
1210 (define_insn "*loadsf_update"
1211   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1212         (match_operator:SF 4 "load_update_operand"
1213          [(match_operand:SI 1 "register_operand" "0,0")
1214           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1215    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1216         (plus:SI (match_dup 1) (match_dup 2)))]
1217   ""
1218   "ld.a%V4 %3,[%0,%S2]"
1219   [(set_attr "type" "load,load")
1220    (set_attr "length" "4,8")])
1222 (define_insn "*storesf_update"
1223   [(set (match_operator:SF 4 "store_update_operand"
1224          [(match_operand:SI 1 "register_operand" "0")
1225           (match_operand:SI 2 "short_immediate_operand" "I")])
1226         (match_operand:SF 3 "register_operand" "c"))
1227    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1228         (plus:SI (match_dup 1) (match_dup 2)))]
1229   ""
1230   "st.a%V4 %3,[%0,%2]"
1231   [(set_attr "type" "store")
1232    (set_attr "length" "4")])
1234 ;; Conditional move instructions.
1236 (define_expand "movsicc"
1237   [(set (match_operand:SI 0 "dest_reg_operand" "")
1238         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1239                          (match_operand:SI 2 "nonmemory_operand" "")
1240                          (match_operand:SI 3 "register_operand" "")))]
1241   ""
1242   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1245 (define_expand "movdicc"
1246   [(set (match_operand:DI 0 "dest_reg_operand" "")
1247         (if_then_else:DI(match_operand 1 "comparison_operator" "")
1248                         (match_operand:DI 2 "nonmemory_operand" "")
1249                         (match_operand:DI 3 "register_operand" "")))]
1250   ""
1251   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1254 (define_expand "movsfcc"
1255   [(set (match_operand:SF 0 "dest_reg_operand" "")
1256         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1257                       (match_operand:SF 2 "nonmemory_operand" "")
1258                       (match_operand:SF 3 "register_operand" "")))]
1259   ""
1260   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1262 (define_expand "movdfcc"
1263   [(set (match_operand:DF 0 "dest_reg_operand" "")
1264         (if_then_else:DF (match_operand 1 "comparison_operator" "")
1265                       (match_operand:DF 2 "nonmemory_operand" "")
1266                       (match_operand:DF 3 "register_operand" "")))]
1267   ""
1268   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1270 (define_insn "*movsicc_insn"
1271   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1272         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1273                        [(match_operand 4 "cc_register" "") (const_int 0)])
1274                       (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1275                       (match_operand:SI 2 "register_operand" "0,0")))]
1276   ""
1278   if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1279       && satisfies_constraint_Rcq (operands[0]))
1280     return "sub%?.ne %0,%0,%0";
1281   /* ??? might be good for speed on ARC600 too, *if* properly scheduled.  */
1282   if ((TARGET_ARC700 || optimize_size)
1283       && rtx_equal_p (operands[1], constm1_rtx)
1284       && GET_CODE (operands[3]) == LTU)
1285     return "sbc.cs %0,%0,%0";
1286   return "mov.%d3 %0,%S1";
1288   [(set_attr "type" "cmove,cmove")
1289    (set_attr "length" "4,8")])
1291 ; Try to generate more short moves, and/or less limms, by substituting a
1292 ; conditional move with a conditional sub.
1293 (define_peephole2
1294   [(set (match_operand:SI 0 "compact_register_operand")
1295         (match_operand:SI 1 "const_int_operand"))
1296    (set (match_dup 0)
1297         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1298                            [(match_operand 4 "cc_register" "") (const_int 0)])
1299                             (match_operand:SI 2 "const_int_operand" "")
1300                       (match_dup 0)))]
1301   "!satisfies_constraint_P (operands[1])
1302    && satisfies_constraint_P (operands[2])
1303    && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1304   [(set (match_dup 0) (match_dup 2))
1305    (cond_exec
1306      (match_dup 3)
1307      (set (match_dup 0)
1308           (plus:SI (match_dup 0) (match_dup 1))))]
1309   "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1310                                                     GET_MODE (operands[4])),
1311                                  VOIDmode, operands[4], const0_rtx);
1312    operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1314 (define_insn "*movdicc_insn"
1315   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1316         (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1317                         [(match_operand 4 "cc_register" "") (const_int 0)])
1318                       (match_operand:DI 1 "nonmemory_operand" "c,i")
1319                       (match_operand:DI 2 "register_operand" "0,0")))]
1320    ""
1321    "*
1323    switch (which_alternative)
1324      {
1325      default:
1326      case 0 :
1327        /* We normally copy the low-numbered register first.  However, if
1328          the first register operand 0 is the same as the second register of
1329          operand 1, we must copy in the opposite order.  */
1330        if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1331         return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1332        else
1333         return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1334      case 1 :
1335         return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1338      }
1340   [(set_attr "type" "cmove,cmove")
1341    (set_attr "length" "8,16")])
1344 (define_insn "*movsfcc_insn"
1345   [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1346         (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1347                        [(match_operand 4 "cc_register" "") (const_int 0)])
1348                       (match_operand:SF 1 "nonmemory_operand" "c,E")
1349                       (match_operand:SF 2 "register_operand" "0,0")))]
1350   ""
1351   "@
1352    mov.%d3 %0,%1
1353    mov.%d3 %0,%1 ; %A1"
1354   [(set_attr "type" "cmove,cmove")])
1356 (define_insn "*movdfcc_insn"
1357   [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1358         (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1359                  [(match_operand 4 "cc_register" "") (const_int 0)])
1360                       (match_operand:DF 2 "nonmemory_operand" "c,E")
1361                       (match_operand:DF 3 "register_operand" "0,0")))]
1362   ""
1363   "*
1365   switch (which_alternative)
1366     {
1367     default:
1368     case 0 :
1369       /* We normally copy the low-numbered register first.  However, if
1370          the first register operand 0 is the same as the second register of
1371          operand 1, we must copy in the opposite order.  */
1372       if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1373         return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1374       else
1375         return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1376     case 1 :
1377               return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1379     }
1381   [(set_attr "type" "cmove,cmove")
1382    (set_attr "length" "8,16")])
1385 (define_insn "*zero_extendqihi2_i"
1386   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
1387         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
1388   ""
1389   "@
1390    extb%? %0,%1%&
1391    extb%? %0,%1%&
1392    bmsk%? %0,%1,7
1393    extb %0,%1
1394    ldb%U1 %0,%1"
1395   [(set_attr "type" "unary,unary,unary,unary,load")
1396    (set_attr "iscompact" "maybe,true,false,false,false")
1397    (set_attr "predicable" "no,no,yes,no,no")])
1399 (define_expand "zero_extendqihi2"
1400   [(set (match_operand:HI 0 "dest_reg_operand" "")
1401         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1402   ""
1403   "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1406 (define_insn "*zero_extendqisi2_ac"
1407   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
1408         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
1409   ""
1410   "@
1411    extb%? %0,%1%&
1412    extb%? %0,%1%&
1413    bmsk%? %0,%1,7
1414    extb %0,%1
1415    ldb%? %0,%1%&
1416    ldb%? %0,%1%&
1417    ldb%U1 %0,%1"
1418   [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1419    (set_attr "iscompact" "maybe,true,false,false,true,true,false")
1420    (set_attr "predicable" "no,no,yes,no,no,no,no")])
1422 (define_expand "zero_extendqisi2"
1423   [(set (match_operand:SI 0 "dest_reg_operand" "")
1424         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1425   ""
1426   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1429 (define_insn "*zero_extendhisi2_i"
1430   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
1431         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
1432   ""
1433   "@
1434    extw%? %0,%1%&
1435    extw%? %0,%1%&
1436    bmsk%? %0,%1,15
1437    extw %0,%1
1438    ldw%? %0,%1%&
1439    ldw%U1 %0,%1
1440    ldw%U1%V1 %0,%1"
1441   [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1442    (set_attr "iscompact" "maybe,true,false,false,true,false,false")
1443    (set_attr "predicable" "no,no,yes,no,no,no,no")])
1446 (define_expand "zero_extendhisi2"
1447   [(set (match_operand:SI 0 "dest_reg_operand" "")
1448         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1449   ""
1450   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1453 ;; Sign extension instructions.
1455 (define_insn "*extendqihi2_i"
1456   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
1457         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
1458   ""
1459   "@
1460    sexb%? %0,%1%&
1461    sexb %0,%1
1462    ldb.x%U1 %0,%1"
1463   [(set_attr "type" "unary,unary,load")
1464    (set_attr "iscompact" "true,false,false")])
1467 (define_expand "extendqihi2"
1468   [(set (match_operand:HI 0 "dest_reg_operand" "")
1469         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1470   ""
1471   "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1474 (define_insn "*extendqisi2_ac"
1475   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1476         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1477   ""
1478   "@
1479    sexb%? %0,%1%&
1480    sexb %0,%1
1481    ldb.x%U1 %0,%1"
1482   [(set_attr "type" "unary,unary,load")
1483    (set_attr "iscompact" "true,false,false")])
1485 (define_expand "extendqisi2"
1486   [(set (match_operand:SI 0 "dest_reg_operand" "")
1487         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1488   ""
1489   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1492 (define_insn "*extendhisi2_i"
1493   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1494         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1495   ""
1496   "@
1497    sexw%? %0,%1%&
1498    sexw %0,%1
1499    ldw.x%U1%V1 %0,%1"
1500   [(set_attr "type" "unary,unary,load")
1501    (set_attr "iscompact" "true,false,false")])
1503 (define_expand "extendhisi2"
1504   [(set (match_operand:SI 0 "dest_reg_operand" "")
1505         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1506   ""
1507   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1510 ;; Unary arithmetic insns
1512 ;; We allow constant operands to enable late constant propagation, but it is
1513 ;; not worth while to have more than one dedicated alternative to output them -
1514 ;; if we are really worried about getting these the maximum benefit of all
1515 ;; the available alternatives, we should add an extra pass to fold such
1516 ;; operations to movsi.
1518 ;; Absolute instructions
1520 (define_insn "*abssi2_mixed"
1521   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1522         (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1523   "TARGET_MIXED_CODE"
1524   "abs%? %0,%1%&"
1525   [(set_attr "type" "two_cycle_core")
1526    (set_attr "iscompact" "true")])
1528 (define_insn "abssi2"
1529   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1530         (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1531   ""
1532   "abs%? %0,%1%&"
1533   [(set_attr "type" "two_cycle_core")
1534    (set_attr "length" "*,4,8")
1535    (set_attr "iscompact" "true,false,false")])
1537 ;; Maximum and minimum insns
1539 (define_insn "smaxsi3"
1540    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1541          (smax:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1542                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1543   ""
1544   "max%? %0,%1,%2"
1545   [(set_attr "type" "two_cycle_core")
1546    (set_attr "length" "4,4,8")
1547    (set_attr "predicable" "yes,no,no")]
1550 (define_insn "sminsi3"
1551    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1552          (smin:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1553                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1554   ""
1555   "min%? %0,%1,%2"
1556   [(set_attr "type" "two_cycle_core")
1557    (set_attr "length" "4,4,8")
1558    (set_attr "predicable" "yes,no,no")]
1561 ;; Arithmetic instructions.
1563 ; We say an insn can be conditionalized if this doesn't introduce a long
1564 ; immediate.  We set the type such that we still have good scheduling if the
1565 ; insn is conditionalized.
1566 ; ??? It would make sense to allow introduction of long immediates, but
1567 ;     we'd need to communicate to the ccfsm machinery the extra cost.
1568 ; The alternatives in the constraints still serve three purposes:
1569 ; - estimate insn size assuming conditional execution
1570 ; - guide reload to re-order the second and third operand to get a better fit.
1571 ; - give tentative insn type to guide scheduling
1572 ;   N.B. "%" for commutativity doesn't help when there is another matching
1573 ;   (but longer) alternative.
1574 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1575 ;  register class 'W' instead of 'w'.
1576 (define_insn_and_split "*addsi3_mixed"
1577   ;;                                                      0       1   2   3   4   5   6    7     8    9     a   b c   d    e   f  10
1578   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcq#q,Rcq,Rcw,Rcw,Rcq,Rcb,Rcq, Rcw, Rcqq,Rcqq,    W,  W,W,  W,Rcqq,Rcw,  W")
1579         (plus:SI (match_operand:SI 1 "register_operand" "%0,      c,  0,  c,  0,  0,Rcb,   0, Rcqq,   0,    c,  c,0,  0,   0,  0,  c")
1580                  (match_operand:SI 2 "nonmemory_operand" "cL,     0, cL,  0,CL2,Csp,CM4,cCca,RcqqK,  cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1581   ""
1583   arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1584   return "";
1586   "&& reload_completed && get_attr_length (insn) == 8
1587    && satisfies_constraint_I (operands[2])
1588    && GET_CODE (PATTERN (insn)) != COND_EXEC"
1589   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1590   "split_addsi (operands);"
1591   [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*")
1592    (set (attr "iscompact")
1593         (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1594                (const_string "false")
1595                (match_operand 2 "long_immediate_operand" "")
1596                (const_string "maybe_limm")]
1597               (const_string "maybe")))
1598    (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8")
1599    (set_attr "predicable" "no,no,yes,yes,no,no,no,yes,no,no,no,no,no,no,no,yes,no")
1600    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1603 ;; ARC700/ARC600 multiply
1604 ;; SI <- SI * SI
1606 (define_expand "mulsi3"
1607  [(set (match_operand:SI 0 "nonimmediate_operand"            "")
1608         (mult:SI (match_operand:SI 1 "register_operand"  "")
1609                  (match_operand:SI 2 "nonmemory_operand" "")))]
1610   ""
1612   if (TARGET_ARC700 && !TARGET_NOMPY_SET)
1613     {
1614       if (!register_operand (operands[0], SImode))
1615         {
1616           rtx result = gen_reg_rtx (SImode);
1618           emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1619           emit_move_insn (operands[0], result);
1620           DONE;
1621         }
1622     }
1623   else if (TARGET_MUL64_SET)
1624     {
1625       emit_insn (gen_mulsi_600 (operands[1], operands[2],
1626                                 gen_mlo (), gen_mhi ()));
1627       emit_move_insn (operands[0], gen_mlo ());
1628       DONE;
1629     }
1630   else if (TARGET_MULMAC_32BY16_SET)
1631     {
1632       if (immediate_operand (operands[2], SImode)
1633           && INTVAL (operands[2]) >= 0
1634           && INTVAL (operands[2]) <= 65535)
1635         {
1636           emit_insn (gen_umul_600 (operands[1], operands[2],
1637                                      gen_acc2 (), gen_acc1 ()));
1638           emit_move_insn (operands[0], gen_acc2 ());
1639           DONE;
1640         }
1641       operands[2] = force_reg (SImode, operands[2]);
1642       emit_insn (gen_umul_600 (operands[1], operands[2],
1643                                gen_acc2 (), gen_acc1 ()));
1644       emit_insn (gen_mac_600 (operands[1], operands[2],
1645                                gen_acc2 (), gen_acc1 ()));
1646       emit_move_insn (operands[0], gen_acc2 ());
1647       DONE;
1648     }
1649   else
1650     {
1651       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1652       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1653       emit_insn (gen_mulsi3_600_lib ());
1654       emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1655       DONE;
1656     }
1659 ; mululw conditional execution without a LIMM clobbers an input register;
1660 ; we'd need a different pattern to describe this.
1661 ; To make the conditional execution valid for the LIMM alternative, we
1662 ; have to emit the LIMM before the register operand.
1663 (define_insn "umul_600"
1664   [(set (match_operand:SI 2 "acc2_operand" "")
1665         (mult:SI (match_operand:SI 0 "register_operand"  "c,c,c")
1666                  (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
1667                                                          "c,L,Cal")
1668                                   (const_int 16)
1669                                   (const_int 0))))
1670    (clobber (match_operand:SI 3 "acc1_operand" ""))]
1671   "TARGET_MULMAC_32BY16_SET"
1672   "@mululw 0, %0, %1
1673     mululw 0, %0, %1
1674     mululw%? 0, %1, %0"
1675   [(set_attr "length" "4,4,8")
1676    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1677    (set_attr "predicable" "no, no, yes")
1678    (set_attr "cond" "nocond, canuse_limm, canuse")])
1680 (define_insn "mac_600"
1681   [(set (match_operand:SI 2 "acc2_operand" "")
1682         (plus:SI
1683           (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1684                    (ashift:SI
1685                      (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
1686                                       (const_int 16)
1687                                       (const_int 16))
1688                      (const_int 16)))
1689           (match_dup 2)))
1690    (clobber (match_operand:SI 3 "acc1_operand" ""))]
1691   "TARGET_MULMAC_32BY16_SET"
1692   "machlw%? 0, %0, %1"
1693   [(set_attr "length" "4,4,8")
1694    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1695    (set_attr "predicable" "no, no, yes")
1696    (set_attr "cond" "nocond, canuse_limm, canuse")])
1698 (define_insn "mulsi_600"
1699   [(set (match_operand:SI 2 "mlo_operand" "")
1700         (mult:SI (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c")
1701                  (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
1702    (clobber (match_operand:SI 3 "mhi_operand" ""))]
1703   "TARGET_MUL64_SET"
1704 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
1705 ; using a machine code pattern that only allows "L" constraint constants.
1706 ;  "mul64%? \t0, %0, %1%&"
1708   if (satisfies_constraint_I (operands[1])
1709       && !satisfies_constraint_L (operands[1]))
1710     {
1711       /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS  */
1712       int n = true_regnum (operands[0]);
1713       int i = INTVAL (operands[1]);
1714       asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
1715       asm_fprintf (asm_out_file, "\t.short %d`",
1716                    ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
1717       return "; mul64%? \t0, %0, %1%&";
1718     }
1719   return "mul64%? \t0, %0, %1%&";
1721   [(set_attr "length" "*,4,4,8")
1722    (set_attr "iscompact" "maybe,false,false,false")
1723    (set_attr "type" "multi,multi,multi,multi")
1724    (set_attr "predicable" "yes,yes,no,yes")
1725    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1727 ; If we compile without an mul option enabled, but link with libraries
1728 ; for a mul option, we'll see clobbers of multiplier output registers.
1729 ; There is also an implementation using norm that clobbers the loop registers.
1730 (define_insn "mulsi3_600_lib"
1731   [(set (reg:SI R0_REG)
1732         (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
1733    (clobber (reg:SI RETURN_ADDR_REGNUM))
1734    (clobber (reg:SI R1_REG))
1735    (clobber (reg:SI R2_REG))
1736    (clobber (reg:SI R3_REG))
1737    (clobber (reg:DI MUL64_OUT_REG))
1738    (clobber (reg:SI LP_COUNT))
1739    (clobber (reg:SI LP_START))
1740    (clobber (reg:SI LP_END))
1741    (clobber (reg:CC CC_REG))]
1742   "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
1743    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
1744    && SFUNC_CHECK_PREDICABLE"
1745   "*return arc_output_libcall (\"__mulsi3\");"
1746   [(set_attr "is_sfunc" "yes")
1747    (set_attr "predicable" "yes")])
1749 (define_insn "mulsidi_600"
1750   [(set (reg:DI MUL64_OUT_REG)
1751         (mult:DI (sign_extend:DI
1752                    (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c"))
1753                  (sign_extend:DI
1754 ; assembler issue for "I", see mulsi_600
1755 ;                  (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,Cal"))))]
1756                    (match_operand:SI 1 "register_operand" "Rcq#q,cL,L,C32"))))]
1757   "TARGET_MUL64_SET"
1758   "mul64%? \t0, %0, %1%&"
1759   [(set_attr "length" "*,4,4,8")
1760    (set_attr "iscompact" "maybe,false,false,false")
1761    (set_attr "type" "multi,multi,multi,multi")
1762    (set_attr "predicable" "yes,yes,no,yes")
1763    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1765 (define_insn "umulsidi_600"
1766   [(set (reg:DI MUL64_OUT_REG)
1767         (mult:DI (zero_extend:DI
1768                    (match_operand:SI 0 "register_operand"  "%c,c,c"))
1769                  (sign_extend:DI
1770 ; assembler issue for "I", see mulsi_600
1771 ;                  (match_operand:SI 1 "register_operand" "cL,I,Cal"))))]
1772                    (match_operand:SI 1 "register_operand" "cL,L,C32"))))]
1773   "TARGET_MUL64_SET"
1774   "mulu64%? \t0, %0, %1%&"
1775   [(set_attr "length" "4,4,8")
1776    (set_attr "iscompact" "false")
1777    (set_attr "type" "umulti")
1778    (set_attr "predicable" "yes,no,yes")
1779    (set_attr "cond" "canuse,canuse_limm,canuse")])
1781 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
1782 ; may not be used as destination constraint.
1784 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
1785 ; but mpyu is faster for the standard multiplier.
1786 ; Note: we must make sure LP_COUNT is not one of the destination
1787 ; registers, since it cannot be the destination of a multi-cycle insn
1788 ; like MPY or MPYU.
1789 (define_insn "mulsi3_700"
1790  [(set (match_operand:SI 0 "mpy_dest_reg_operand"        "=Rcr,r,r,Rcr,r")
1791         (mult:SI (match_operand:SI 1 "register_operand"  " 0,c,0,0,c")
1792                  (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
1793 "TARGET_ARC700 && !TARGET_NOMPY_SET"
1794   "mpyu%? %0,%1,%2"
1795   [(set_attr "length" "4,4,4,8,8")
1796    (set_attr "type" "umulti")
1797    (set_attr "predicable" "yes,no,no,yes,no")
1798    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
1800 (define_expand "mulsidi3"
1801   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1802         (mult:DI (sign_extend:DI(match_operand:SI 1 "register_operand" ""))
1803                  (sign_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
1804   "(TARGET_ARC700 && !TARGET_NOMPY_SET)
1805    || TARGET_MUL64_SET
1806    || TARGET_MULMAC_32BY16_SET"
1809   if (TARGET_ARC700 && !TARGET_NOMPY_SET)
1810     {
1811       operands[2] = force_reg (SImode, operands[2]);
1812       if (!register_operand (operands[0], DImode))
1813         {
1814           rtx result = gen_reg_rtx (DImode);
1816           operands[2] = force_reg (SImode, operands[2]);
1817           emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
1818           emit_move_insn (operands[0], result);
1819           DONE;
1820         }
1821     }
1822   else if (TARGET_MUL64_SET)
1823     {
1824       operands[2] = force_reg (SImode, operands[2]);
1825       emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
1826       emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
1827       DONE;
1828     }
1829   else if (TARGET_MULMAC_32BY16_SET)
1830     {
1831       rtx result_hi = gen_highpart(SImode, operands[0]);
1832       rtx result_low = gen_lowpart(SImode, operands[0]);
1834       emit_insn (gen_mul64_600 (operands[1], operands[2]));
1835       emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
1836       emit_move_insn (result_low, gen_acc2 ());
1837       DONE;
1838     }
1841 (define_insn "mul64_600"
1842   [(set (reg:DI 56)
1843         (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
1844                                   "c,c,c"))
1845                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
1846                                   "c,L,Cal")
1847                                   (const_int 16)
1848                                   (const_int 0))))
1849   ]
1850   "TARGET_MULMAC_32BY16_SET"
1851   "mullw%? 0, %0, %1"
1852   [(set_attr "length" "4,4,8")
1853    (set_attr "type" "mulmac_600")
1854    (set_attr "predicable" "no,no,yes")
1855    (set_attr "cond" "nocond, canuse_limm, canuse")])
1858 ;; ??? check if this is canonical rtl
1859 (define_insn "mac64_600"
1860   [(set (reg:DI 56)
1861         (plus:DI
1862           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
1863                    (ashift:DI
1864                      (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
1865                                       (const_int 16) (const_int 16))
1866                      (const_int 16)))
1867           (reg:DI 56)))
1868    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1869         (zero_extract:SI
1870           (plus:DI
1871             (mult:DI (sign_extend:DI (match_dup 1))
1872                      (ashift:DI
1873                        (sign_extract:DI (match_dup 2)
1874                                         (const_int 16) (const_int 16))
1875                           (const_int 16)))
1876             (reg:DI 56))
1877           (const_int 32) (const_int 32)))]
1878   "TARGET_MULMAC_32BY16_SET"
1879   "machlw%? %0, %1, %2"
1880   [(set_attr "length" "4,4,8")
1881    (set_attr "type" "mulmac_600")
1882    (set_attr "predicable" "no,no,yes")
1883    (set_attr "cond" "nocond, canuse_limm, canuse")])
1886 ;; DI <- DI(signed SI) * DI(signed SI)
1887 (define_insn_and_split "mulsidi3_700"
1888   [(set (match_operand:DI 0 "register_operand" "=&r")
1889         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
1890                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
1891   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1892   "#"
1893   "&& reload_completed"
1894   [(const_int 0)]
1896   int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1897   int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1898   rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
1899   rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
1900   emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
1901   emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
1902   DONE;
1904   [(set_attr "type" "multi")
1905    (set_attr "length" "8")])
1907 (define_insn "mulsi3_highpart"
1908   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
1909         (truncate:SI
1910          (lshiftrt:DI
1911           (mult:DI
1912            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
1913            (sign_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
1914           (const_int 32))))]
1915   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1916   "mpyh%? %0,%1,%2"
1917   [(set_attr "length" "4,4,8,8")
1918    (set_attr "type" "multi")
1919    (set_attr "predicable" "yes,no,yes,no")
1920    (set_attr "cond" "canuse,nocond,canuse,nocond")])
1922 ; Note that mpyhu has the same latency as mpy / mpyh,
1923 ; thus we use the type multi.
1924 (define_insn "*umulsi3_highpart_i"
1925   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
1926         (truncate:SI
1927          (lshiftrt:DI
1928           (mult:DI
1929            (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
1930            (zero_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
1931           (const_int 32))))]
1932   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1933   "mpyhu%? %0,%1,%2"
1934   [(set_attr "length" "4,4,8,8")
1935    (set_attr "type" "multi")
1936    (set_attr "predicable" "yes,no,yes,no")
1937    (set_attr "cond" "canuse,nocond,canuse,nocond")])
1939 ; Implementations include additional labels for umulsidi3, so we got all
1940 ; the same clobbers - plus one for the result low part.  */
1941 (define_insn "umulsi3_highpart_600_lib_le"
1942   [(set (reg:SI R1_REG)
1943         (truncate:SI
1944          (lshiftrt:DI
1945           (mult:DI (zero_extend:DI (reg:SI R0_REG))
1946                    (zero_extend:DI (reg:SI R1_REG)))
1947           (const_int 32))))
1948    (clobber (reg:SI RETURN_ADDR_REGNUM))
1949    (clobber (reg:SI R0_REG))
1950    (clobber (reg:DI R2_REG))
1951    (clobber (reg:SI R12_REG))
1952    (clobber (reg:DI MUL64_OUT_REG))
1953    (clobber (reg:CC CC_REG))]
1954   "!TARGET_BIG_ENDIAN
1955    && !TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
1956    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
1957    && SFUNC_CHECK_PREDICABLE"
1958   "*return arc_output_libcall (\"__umulsi3_highpart\");"
1959   [(set_attr "is_sfunc" "yes")
1960    (set_attr "predicable" "yes")])
1962 (define_insn "umulsi3_highpart_600_lib_be"
1963   [(set (reg:SI R0_REG)
1964         (truncate:SI
1965          (lshiftrt:DI
1966           (mult:DI (zero_extend:DI (reg:SI R0_REG))
1967                    (zero_extend:DI (reg:SI R1_REG)))
1968           (const_int 32))))
1969    (clobber (reg:SI RETURN_ADDR_REGNUM))
1970    (clobber (reg:SI R1_REG))
1971    (clobber (reg:DI R2_REG))
1972    (clobber (reg:SI R12_REG))
1973    (clobber (reg:DI MUL64_OUT_REG))
1974    (clobber (reg:CC CC_REG))]
1975   "TARGET_BIG_ENDIAN
1976    && !TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
1977    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
1978    && SFUNC_CHECK_PREDICABLE"
1979   "*return arc_output_libcall (\"__umulsi3_highpart\");"
1980   [(set_attr "is_sfunc" "yes")
1981    (set_attr "predicable" "yes")])
1983 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
1984 ;; need a separate pattern for immediates
1985 ;; ??? This is fine for combine, but not for reload.
1986 (define_insn "umulsi3_highpart_int"
1987   [(set (match_operand:SI 0 "register_operand"            "=Rcr, r, r,Rcr,  r")
1988         (truncate:SI
1989          (lshiftrt:DI
1990           (mult:DI
1991            (zero_extend:DI (match_operand:SI 1 "register_operand"  " 0, c, 0,  0,  c"))
1992            (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
1993           (const_int 32))))]
1994   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1995   "mpyhu%? %0,%1,%2"
1996   [(set_attr "length" "4,4,4,8,8")
1997    (set_attr "type" "multi")
1998    (set_attr "predicable" "yes,no,no,yes,no")
1999    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2001 (define_expand "umulsi3_highpart"
2002   [(set (match_operand:SI 0 "general_operand"  "")
2003         (truncate:SI
2004          (lshiftrt:DI
2005           (mult:DI
2006            (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2007            (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2008           (const_int 32))))]
2009   "TARGET_ARC700 || (!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET)"
2010   "
2012   rtx target = operands[0];
2014   if (!TARGET_ARC700 || TARGET_NOMPY_SET)
2015     {
2016       emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2017       emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2018       if (TARGET_BIG_ENDIAN)
2019         emit_insn (gen_umulsi3_highpart_600_lib_be ());
2020       else
2021         emit_insn (gen_umulsi3_highpart_600_lib_le ());
2022       emit_move_insn (target, gen_rtx_REG (SImode, 0));
2023       DONE;
2024     }
2026   if (!register_operand (target, SImode))
2027     target = gen_reg_rtx (SImode);
2029   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2030     operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2031                                                   operands[2], SImode);
2032   else if (!immediate_operand (operands[2], SImode))
2033     operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2034   emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2035   if (target != operands[0])
2036     emit_move_insn (operands[0], target);
2037   DONE;
2040 (define_expand "umulsidi3"
2041   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2042         (mult:DI (zero_extend:DI(match_operand:SI 1 "register_operand" ""))
2043                  (zero_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2044   ""
2046   if (TARGET_ARC700 && !TARGET_NOMPY_SET)
2047     {
2048       operands[2] = force_reg (SImode, operands[2]);
2049       if (!register_operand (operands[0], DImode))
2050         {
2051           rtx result = gen_reg_rtx (DImode);
2053           emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2054           emit_move_insn (operands[0], result);
2055           DONE;
2056         }
2057     }
2058   else if (TARGET_MUL64_SET)
2059     {
2060       operands[2] = force_reg (SImode, operands[2]);
2061       emit_insn (gen_umulsidi_600 (operands[1], operands[2]));
2062       emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2063       DONE;
2064     }
2065   else if (TARGET_MULMAC_32BY16_SET)
2066     {
2067       rtx result_hi = gen_reg_rtx (SImode);
2068       rtx result_low = gen_reg_rtx (SImode);
2070       result_hi = gen_highpart(SImode , operands[0]);
2071       result_low = gen_lowpart(SImode , operands[0]);
2073       emit_insn (gen_umul64_600 (operands[1], operands[2]));
2074       emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2075       emit_move_insn (result_low, gen_acc2 ());
2076       DONE;
2077     }
2078   else
2079     {
2080       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2081       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2082       emit_insn (gen_umulsidi3_600_lib ());
2083       emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2084       DONE;
2085     }
2088 (define_insn "umul64_600"
2089   [(set (reg:DI 56)
2090         (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2091                                   "c,c,c"))
2092                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2093                                   "c,L,Cal")
2094                                   (const_int 16)
2095                                   (const_int 0))))
2096   ]
2097   "TARGET_MULMAC_32BY16_SET"
2098   "@mululw 0, %0, %1
2099     mululw 0, %0, %1
2100     mululw%? 0, %1, %0"
2101   [(set_attr "length" "4,4,8")
2102    (set_attr "type" "mulmac_600")
2103    (set_attr "predicable" "no,no,yes")
2104    (set_attr "cond" "nocond, canuse_limm, canuse")])
2107 (define_insn "umac64_600"
2108   [(set (reg:DI 56)
2109         (plus:DI
2110           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2111                    (ashift:DI
2112                      (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2113                                       (const_int 16) (const_int 16))
2114                      (const_int 16)))
2115           (reg:DI 56)))
2116    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2117         (zero_extract:SI
2118           (plus:DI
2119             (mult:DI (zero_extend:DI (match_dup 1))
2120                      (ashift:DI
2121                        (zero_extract:DI (match_dup 2)
2122                                         (const_int 16) (const_int 16))
2123                           (const_int 16)))
2124             (reg:DI 56))
2125           (const_int 32) (const_int 32)))]
2126   "TARGET_MULMAC_32BY16_SET"
2127   "machulw%? %0, %1, %2"
2128   [(set_attr "length" "4,4,8")
2129    (set_attr "type" "mulmac_600")
2130    (set_attr "predicable" "no,no,yes")
2131    (set_attr "cond" "nocond, canuse_limm, canuse")])
2135 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2136 (define_insn_and_split "umulsidi3_700"
2137   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2138         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2139                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2140   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2141   "#"
2142   "reload_completed"
2143   [(const_int 0)]
2145   int hi = !TARGET_BIG_ENDIAN;
2146   int lo = !hi;
2147   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2148   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2149   emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2150   emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
2151   DONE;
2153   [(set_attr "type" "umulti")
2154   (set_attr "length" "8")])
2156 (define_insn "umulsidi3_600_lib"
2157   [(set (reg:DI R0_REG)
2158         (mult:DI (zero_extend:DI (reg:SI R0_REG))
2159                  (zero_extend:DI (reg:SI R1_REG))))
2160    (clobber (reg:SI RETURN_ADDR_REGNUM))
2161    (clobber (reg:DI R2_REG))
2162    (clobber (reg:SI R12_REG))
2163    (clobber (reg:DI MUL64_OUT_REG))
2164    (clobber (reg:CC CC_REG))]
2165    "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
2166    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
2167    && SFUNC_CHECK_PREDICABLE"
2168   "*return arc_output_libcall (\"__umulsidi3\");"
2169   [(set_attr "is_sfunc" "yes")
2170    (set_attr "predicable" "yes")])
2172 (define_peephole2
2173   [(parallel
2174      [(set (reg:DI R0_REG)
2175            (mult:DI (zero_extend:DI (reg:SI R0_REG))
2176                     (zero_extend:DI (reg:SI R1_REG))))
2177       (clobber (reg:SI RETURN_ADDR_REGNUM))
2178       (clobber (reg:DI R2_REG))
2179       (clobber (reg:SI R12_REG))
2180       (clobber (reg:DI MUL64_OUT_REG))
2181       (clobber (reg:CC CC_REG))])]
2182   "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
2183    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
2184    && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2185   [(pc)]
2187   if (TARGET_BIG_ENDIAN)
2188     emit_insn (gen_umulsi3_highpart_600_lib_be ());
2189   else
2190     emit_insn (gen_umulsi3_highpart_600_lib_le ());
2191   DONE;
2194 (define_expand "addsi3"
2195   [(set (match_operand:SI 0 "dest_reg_operand" "")
2196         (plus:SI (match_operand:SI 1 "register_operand" "")
2197                  (match_operand:SI 2 "nonmemory_operand" "")))]
2198   ""
2199   "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2200      {
2201        operands[2]=force_reg(SImode, operands[2]);
2202      }
2203   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2204    {
2205       operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2206    }
2208   ")
2210 (define_expand "adddi3"
2211   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2212                    (plus:DI (match_operand:DI 1 "register_operand" "")
2213                             (match_operand:DI 2 "nonmemory_operand" "")))
2214               (clobber (reg:CC CC_REG))])]
2215   ""
2217   if (TARGET_EXPAND_ADDDI)
2218     {
2219       rtx l0 = gen_lowpart (SImode, operands[0]);
2220       rtx h0 = disi_highpart (operands[0]);
2221       rtx l1 = gen_lowpart (SImode, operands[1]);
2222       rtx h1 = disi_highpart (operands[1]);
2223       rtx l2 = gen_lowpart (SImode, operands[2]);
2224       rtx h2 = disi_highpart (operands[2]);
2225       rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2227       if (CONST_INT_P (h2) && INTVAL (h2) < 0 && SIGNED_INT12 (INTVAL (h2)))
2228         {
2229           emit_insn (gen_sub_f (l0, l1, gen_int_mode (-INTVAL (l2), SImode)));
2230           emit_insn (gen_sbc (h0, h1,
2231                               gen_int_mode (-INTVAL (h2) - (l1 != 0), SImode),
2232                               cc_c));
2233           DONE;
2234         }
2235       emit_insn (gen_add_f (l0, l1, l2));
2236       emit_insn (gen_adc (h0, h1, h2));
2237       DONE;
2238     }
2241 ; This assumes that there can be no strictly partial overlap between
2242 ; operands[1] and operands[2].
2243 (define_insn_and_split "*adddi3_i"
2244   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2245         (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2246                  (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2247    (clobber (reg:CC CC_REG))]
2248   ""
2249   "#"
2250   "reload_completed"
2251   [(const_int 0)]
2253   int hi = !TARGET_BIG_ENDIAN;
2254   int lo = !hi;
2255   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2256   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2257   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2258   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2259   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2260   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2263   if (l2 == const0_rtx)
2264     {
2265       if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2266         emit_move_insn (l0, l1);
2267       emit_insn (gen_addsi3 (h0, h1, h2));
2268       if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2269         emit_move_insn (l0, l1);
2270       DONE;
2271     }
2272   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2273       && INTVAL (operands[2]) >= -0x7fffffff)
2274     {
2275       emit_insn (gen_subdi3_i (operands[0], operands[1],
2276                  GEN_INT (-INTVAL (operands[2]))));
2277       DONE;
2278     }
2279   if (rtx_equal_p (l0, h1))
2280     {
2281       if (h2 != const0_rtx)
2282         emit_insn (gen_addsi3 (h0, h1, h2));
2283       else if (!rtx_equal_p (h0, h1))
2284         emit_move_insn (h0, h1);
2285       emit_insn (gen_add_f (l0, l1, l2));
2286       emit_insn
2287         (gen_rtx_COND_EXEC
2288           (VOIDmode,
2289            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2290            gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2291       DONE;
2292     }
2293   emit_insn (gen_add_f (l0, l1, l2));
2294   emit_insn (gen_adc (h0, h1, h2));
2295   DONE;
2297   [(set_attr "cond" "clob")
2298    (set_attr "type" "binary")
2299    (set_attr "length" "16,16,20")])
2301 (define_insn "add_f"
2302   [(set (reg:CC_C CC_REG)
2303         (compare:CC_C
2304           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2305                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2306           (match_dup 1)))
2307    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2308         (plus:SI (match_dup 1) (match_dup 2)))]
2309   ""
2310   "add.f %0,%1,%2"
2311   [(set_attr "cond" "set")
2312    (set_attr "type" "compare")
2313    (set_attr "length" "4,4,8")])
2315 (define_insn "*add_f_2"
2316   [(set (reg:CC_C CC_REG)
2317         (compare:CC_C
2318           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2319                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2320           (match_dup 2)))
2321    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2322         (plus:SI (match_dup 1) (match_dup 2)))]
2323   ""
2324   "add.f %0,%1,%2"
2325   [(set_attr "cond" "set")
2326    (set_attr "type" "compare")
2327    (set_attr "length" "4,4,8")])
2329 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2330 ; needlessly prioritizing the matching constraint.
2331 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2332 ; execution is used where possible.
2333 (define_insn_and_split "adc"
2334   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2335         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2336                           (match_operand:SI 1 "nonmemory_operand"
2337                                                          "%c,0,c,0,cCal"))
2338                  (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2339   "register_operand (operands[1], SImode)
2340    || register_operand (operands[2], SImode)"
2341   "@
2342         adc %0,%1,%2
2343         add.cs %0,%1,1
2344         adc %0,%1,%2
2345         adc %0,%1,%2
2346         adc %0,%1,%2"
2347   ; if we have a bad schedule after sched2, split.
2348   "reload_completed
2349    && !optimize_size && TARGET_ARC700
2350    && arc_scheduling_not_expected ()
2351    && arc_sets_cc_p (prev_nonnote_insn (insn))
2352    /* If next comes a return or other insn that needs a delay slot,
2353       expect the adc to get into the delay slot.  */
2354    && next_nonnote_insn (insn)
2355    && !arc_need_delay (next_nonnote_insn (insn))
2356    /* Restore operands before emitting.  */
2357    && (extract_insn_cached (insn), 1)"
2358   [(set (match_dup 0) (match_dup 3))
2359    (cond_exec
2360      (ltu (reg:CC_C CC_REG) (const_int 0))
2361      (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2362   "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2363   [(set_attr "cond" "use")
2364    (set_attr "type" "cc_arith")
2365    (set_attr "length" "4,4,4,4,8")])
2367 ; combiner-splitter cmp / scc -> cmp / adc
2368 (define_split
2369   [(set (match_operand:SI 0 "dest_reg_operand" "")
2370         (gtu:SI (match_operand:SI 1 "register_operand" "")
2371                 (match_operand:SI 2 "register_operand" "")))
2372    (clobber (reg CC_REG))]
2373   ""
2374   [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2375    (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2377 ; combine won't work when an intermediate result is used later...
2378 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2379 (define_peephole2
2380   [(set (match_operand:SI 0 "dest_reg_operand" "")
2381         (plus:SI (match_operand:SI 1 "register_operand" "")
2382                  (match_operand:SI 2 "nonmemory_operand" "")))
2383    (set (reg:CC_C CC_REG)
2384         (compare:CC_C (match_dup 0)
2385                       (match_operand:SI 3 "nonmemory_operand" "")))]
2386   "rtx_equal_p (operands[1], operands[3])
2387    || rtx_equal_p (operands[2], operands[3])"
2388   [(parallel
2389      [(set (reg:CC_C CC_REG)
2390            (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2391       (set (match_dup 0)
2392            (plus:SI (match_dup 1) (match_dup 2)))])])
2394 ; ??? need to delve into combine to find out why this is not useful.
2395 ; We'd like to be able to grok various C idioms for carry bit usage.
2396 ;(define_insn "*adc_0"
2397 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2398 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2399 ;                (match_operand:SI 1 "register_operand" "c")))]
2400 ;  ""
2401 ;  "adc %0,%1,0"
2402 ;  [(set_attr "cond" "use")
2403 ;   (set_attr "type" "cc_arith")
2404 ;   (set_attr "length" "4")])
2406 ;(define_split
2407 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2408 ;       (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2409 ;                        (match_operand:SI 2 "register_operand" "c"))
2410 ;                (match_operand:SI 3 "register_operand" "c")))
2411 ;   (clobber (reg CC_REG))]
2412 ;  ""
2413 ;  [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2414 ;   (set (match_dup 0)
2415 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2416 ;                (match_dup 3)))])
2418 (define_expand "subsi3"
2419   [(set (match_operand:SI 0 "dest_reg_operand" "")
2420         (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2421                  (match_operand:SI 2 "nonmemory_operand" "")))]
2422   ""
2423   "
2425   int c = 1;
2427   if (!register_operand (operands[2], SImode))
2428     {
2429       operands[1] = force_reg (SImode, operands[1]);
2430       c = 2;
2431     }
2432   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2433     operands[c] = force_reg (SImode, operands[c]);
2434   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2435       operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2438 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2439 ; combine should make such an insn go away.
2440 (define_insn_and_split "subsi3_insn"
2441   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcw,Rcw,w,w,w,  w,  w,  w")
2442         (minus:SI (match_operand:SI 1 "nonmemory_operand"   "0,  0, cL,c,L,I,Cal,Cal,  c")
2443                   (match_operand:SI 2 "nonmemory_operand" "Rcqq, c,  0,c,c,0,  0,  c,Cal")))]
2444   "register_operand (operands[1], SImode)
2445    || register_operand (operands[2], SImode)"
2446   "@
2447     sub%? %0,%1,%2%&
2448     sub%? %0,%1,%2
2449     rsub%? %0,%2,%1
2450     sub %0,%1,%2
2451     rsub %0,%2,%1
2452     rsub %0,%2,%1
2453     rsub%? %0,%2,%1
2454     rsub %0,%2,%1
2455     sub %0,%1,%2"
2456   "reload_completed && get_attr_length (insn) == 8
2457    && satisfies_constraint_I (operands[1])
2458    && GET_CODE (PATTERN (insn)) != COND_EXEC"
2459   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2460   "split_subsi (operands);"
2461   [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false")
2462   (set_attr "length" "*,4,4,4,4,4,8,8,8")
2463   (set_attr "predicable" "yes,yes,yes,no,no,no,yes,no,no")
2464   (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2466 (define_expand "subdi3"
2467   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2468                    (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2469                              (match_operand:DI 2 "nonmemory_operand" "")))
2470               (clobber (reg:CC CC_REG))])]
2471   ""
2473   if (!register_operand (operands[2], DImode))
2474     operands[1] = force_reg (DImode, operands[1]);
2475   if (TARGET_EXPAND_ADDDI)
2476     {
2477       rtx l0 = gen_lowpart (SImode, operands[0]);
2478       rtx h0 = disi_highpart (operands[0]);
2479       rtx l1 = gen_lowpart (SImode, operands[1]);
2480       rtx h1 = disi_highpart (operands[1]);
2481       rtx l2 = gen_lowpart (SImode, operands[2]);
2482       rtx h2 = disi_highpart (operands[2]);
2483       rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2485       emit_insn (gen_sub_f (l0, l1, l2));
2486       emit_insn (gen_sbc (h0, h1, h2, cc_c));
2487       DONE;
2488     }
2491 (define_insn_and_split "subdi3_i"
2492   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2493         (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2494                   (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2495    (clobber (reg:CC CC_REG))]
2496   "register_operand (operands[1], DImode)
2497    || register_operand (operands[2], DImode)"
2498   "#"
2499   "reload_completed"
2500   [(const_int 0)]
2502   int hi = !TARGET_BIG_ENDIAN;
2503   int lo = !hi;
2504   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2505   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2506   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2507   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2508   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2509   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2511   if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2512     {
2513       h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2514       if (!rtx_equal_p (h0, h1))
2515         emit_insn (gen_rtx_SET (h0, h1));
2516       emit_insn (gen_sub_f (l0, l1, l2));
2517       emit_insn
2518         (gen_rtx_COND_EXEC
2519           (VOIDmode,
2520            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2521            gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2522       DONE;
2523     }
2524   emit_insn (gen_sub_f (l0, l1, l2));
2525   emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2526   DONE;
2528   [(set_attr "cond" "clob")
2529    (set_attr "length" "16,16,16,20,20")])
2531 (define_insn "*sbc_0"
2532   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2533         (minus:SI (match_operand:SI 1 "register_operand" "c")
2534                   (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2535                           (const_int 0))))]
2536   ""
2537   "sbc %0,%1,0"
2538   [(set_attr "cond" "use")
2539    (set_attr "type" "cc_arith")
2540    (set_attr "length" "4")])
2542 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2543 ; needlessly prioritizing the matching constraint.
2544 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2545 ; is used where possible.
2546 (define_insn_and_split "sbc"
2547   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2548         (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2549                                                 "c,0,c,0,cCal")
2550                             (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2551                                     (const_int 0)))
2552                   (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2553   "register_operand (operands[1], SImode)
2554    || register_operand (operands[2], SImode)"
2555   "@
2556         sbc %0,%1,%2
2557         sub.cs %0,%1,1
2558         sbc %0,%1,%2
2559         sbc %0,%1,%2
2560         sbc %0,%1,%2"
2561   ; if we have a bad schedule after sched2, split.
2562   "reload_completed
2563    && !optimize_size && TARGET_ARC700
2564    && arc_scheduling_not_expected ()
2565    && arc_sets_cc_p (prev_nonnote_insn (insn))
2566    /* If next comes a return or other insn that needs a delay slot,
2567       expect the adc to get into the delay slot.  */
2568    && next_nonnote_insn (insn)
2569    && !arc_need_delay (next_nonnote_insn (insn))
2570    /* Restore operands before emitting.  */
2571    && (extract_insn_cached (insn), 1)"
2572   [(set (match_dup 0) (match_dup 4))
2573    (cond_exec
2574      (ltu (reg:CC_C CC_REG) (const_int 0))
2575      (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2576   "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2577   [(set_attr "cond" "use")
2578    (set_attr "type" "cc_arith")
2579    (set_attr "length" "4,4,4,4,8")])
2581 (define_insn "sub_f"
2582   [(set (reg:CC CC_REG)
2583         (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2584                     (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2585    (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2586         (minus:SI (match_dup 1) (match_dup 2)))]
2587   "register_operand (operands[1], SImode)
2588    || register_operand (operands[2], SImode)"
2589   "@
2590         sub.f %0,%1,%2
2591         rsub.f %0,%2,%1
2592         sub.f %0,%1,%2
2593         rsub.f %0,%2,%1
2594         sub.f %0,%1,%2
2595         sub.f %0,%1,%2"
2596   [(set_attr "type" "compare")
2597    (set_attr "length" "4,4,4,4,8,8")])
2599 ; combine won't work when an intermediate result is used later...
2600 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2601 (define_peephole2
2602   [(set (reg:CC CC_REG)
2603         (compare:CC (match_operand:SI 1 "register_operand" "")
2604                     (match_operand:SI 2 "nonmemory_operand" "")))
2605    (set (match_operand:SI 0 "dest_reg_operand" "")
2606         (minus:SI (match_dup 1) (match_dup 2)))]
2607   ""
2608   [(parallel
2609      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2610       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
2612 (define_peephole2
2613   [(set (reg:CC CC_REG)
2614         (compare:CC (match_operand:SI 1 "register_operand" "")
2615                     (match_operand:SI 2 "nonmemory_operand" "")))
2616    (set (match_operand 3 "" "") (match_operand 4 "" ""))
2617    (set (match_operand:SI 0 "dest_reg_operand" "")
2618         (minus:SI (match_dup 1) (match_dup 2)))]
2619   "!reg_overlap_mentioned_p (operands[3], operands[1])
2620    && !reg_overlap_mentioned_p (operands[3], operands[2])
2621    && !reg_overlap_mentioned_p (operands[0], operands[4])
2622    && !reg_overlap_mentioned_p (operands[0], operands[3])"
2623   [(parallel
2624      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2625       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2626    (set (match_dup 3) (match_dup 4))])
2628 (define_insn "*add_n"
2629   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
2630         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
2631                           (match_operand:SI 2 "_2_4_8_operand" ""))
2632                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
2633   ""
2634   "add%z2%? %0,%3,%1%&"
2635   [(set_attr "type" "shift")
2636    (set_attr "length" "*,4,4,8,4,8")
2637    (set_attr "predicable" "yes,yes,no,no,no,no")
2638    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
2639    (set_attr "iscompact" "maybe,false,false,false,false,false")])
2641 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
2642 ;; what synth_mult likes.
2643 (define_insn "*sub_n"
2644   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2645         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
2646                   (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
2647                            (match_operand:SI 3 "_2_4_8_operand" ""))))]
2648   ""
2649   "sub%z3%? %0,%1,%2"
2650   [(set_attr "type" "shift")
2651    (set_attr "length" "4,4,8")
2652    (set_attr "predicable" "yes,no,no")
2653    (set_attr "cond" "canuse,nocond,nocond")
2654    (set_attr "iscompact" "false")])
2656 ; ??? check if combine matches this.
2657 (define_insn "*bset"
2658   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2659         (ior:SI (ashift:SI (const_int 1)
2660                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2661                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2662   ""
2663   "bset%? %0,%2,%1"
2664   [(set_attr "length" "4,4,8")
2665    (set_attr "predicable" "yes,no,no")
2666    (set_attr "cond" "canuse,nocond,nocond")]
2669 ; ??? check if combine matches this.
2670 (define_insn "*bxor"
2671   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2672         (xor:SI (ashift:SI (const_int 1)
2673                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2674                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2675   ""
2676   "bxor%? %0,%2,%1"
2677   [(set_attr "length" "4,4,8")
2678    (set_attr "predicable" "yes,no,no")
2679    (set_attr "cond" "canuse,nocond,nocond")]
2682 ; ??? check if combine matches this.
2683 (define_insn "*bclr"
2684   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2685         (and:SI (not:SI (ashift:SI (const_int 1)
2686                                    (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
2687                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2688   ""
2689   "bclr%? %0,%2,%1"
2690   [(set_attr "length" "4,4,8")
2691    (set_attr "predicable" "yes,no,no")
2692    (set_attr "cond" "canuse,nocond,nocond")]
2695 ; ??? FIXME: find combine patterns for bmsk.
2697 ;;Following are the define_insns added for the purpose of peephole2's
2699 ; see also iorsi3 for use with constant bit number.
2700 (define_insn "*bset_insn"
2701   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2702         (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2703                 (ashift:SI (const_int 1)
2704                            (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2705   ""
2706   "@
2707      bset%? %0,%1,%2 ;;peep2, constr 1
2708      bset %0,%1,%2 ;;peep2, constr 2
2709      bset %0,%S1,%2 ;;peep2, constr 3"
2710   [(set_attr "length" "4,4,8")
2711    (set_attr "predicable" "yes,no,no")
2712    (set_attr "cond" "canuse,nocond,nocond")]
2715 ; see also xorsi3 for use with constant bit number.
2716 (define_insn "*bxor_insn"
2717   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2718         (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2719                 (ashift:SI (const_int 1)
2720                         (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2721   ""
2722   "@
2723      bxor%? %0,%1,%2
2724      bxor %0,%1,%2
2725      bxor %0,%S1,%2"
2726   [(set_attr "length" "4,4,8")
2727    (set_attr "predicable" "yes,no,no")
2728    (set_attr "cond" "canuse,nocond,nocond")]
2731 ; see also andsi3 for use with constant bit number.
2732 (define_insn "*bclr_insn"
2733   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2734         (and:SI (not:SI (ashift:SI (const_int 1)
2735                                    (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
2736                 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
2737   ""
2738   "@
2739      bclr%? %0,%1,%2
2740      bclr %0,%1,%2
2741      bclr %0,%S1,%2"
2742   [(set_attr "length" "4,4,8")
2743    (set_attr "predicable" "yes,no,no")
2744    (set_attr "cond" "canuse,nocond,nocond")]
2747 ; see also andsi3 for use with constant bit number.
2748 (define_insn "*bmsk_insn"
2749   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2750         (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2751                 (plus:SI (ashift:SI (const_int 1)
2752                                     (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
2753                                              (const_int 1)))
2754                          (const_int -1))))]
2755   ""
2756   "@
2757      bmsk%? %0,%S1,%2
2758      bmsk %0,%1,%2
2759      bmsk %0,%S1,%2"
2760   [(set_attr "length" "4,4,8")
2761    (set_attr "predicable" "yes,no,no")
2762    (set_attr "cond" "canuse,nocond,nocond")]
2765 ;;Instructions added for peephole2s end
2767 ;; Boolean instructions.
2769 (define_expand "andsi3"
2770   [(set (match_operand:SI 0 "dest_reg_operand" "")
2771         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2772                 (match_operand:SI 2 "nonmemory_operand" "")))]
2773   ""
2774   "if (!satisfies_constraint_Cux (operands[2]))
2775      operands[1] = force_reg (SImode, operands[1]);
2776    else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
2777      operands[1] = arc_rewrite_small_data (operands[1]);")
2779 (define_insn "andsi3_i"
2780   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,  w,  w,  w,  w,w,Rcw,  w,  W")
2781         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,   0,   0,Rcqq,  0,  c,  0,  0,  0,  0,  c,  c,  c,  c,0,  0,  c,  o")
2782                 (match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, C1p, Ccp, Cux, cL,  0,C1p,Ccp,CnL,  I, Lc,C1p,Ccp,CnL,I,Cal,Cal,Cux")))]
2783   "(register_operand (operands[1], SImode)
2784     && nonmemory_operand (operands[2], SImode))
2785    || (memory_operand (operands[1], SImode)
2786        && satisfies_constraint_Cux (operands[2]))"
2787   "*
2789   switch (which_alternative)
2790     {
2791     case 0: case 5: case 10: case 11: case 15: case 16: case 17:
2792       return \"and%? %0,%1,%2%&\";
2793     case 1: case 6:
2794       return \"and%? %0,%2,%1%&\";
2795     case 2: case 7: case 12:
2796       return \"bmsk%? %0,%1,%Z2%&\";
2797     case 3: case 8: case 13:
2798       return \"bclr%? %0,%1,%M2%&\";
2799     case 4:
2800       return (INTVAL (operands[2]) == 0xff
2801               ? \"extb%? %0,%1%&\" : \"extw%? %0,%1%&\");
2802     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
2803     case 18:
2804       if (TARGET_BIG_ENDIAN)
2805         {
2806           rtx xop[2];
2808           xop[0] = operands[0];
2809           xop[1] = adjust_address (operands[1], QImode,
2810                                    INTVAL (operands[2]) == 0xff ? 3 : 2);
2811           output_asm_insn (INTVAL (operands[2]) == 0xff
2812                            ? \"ldb %0,%1\" : \"ldw %0,%1\",
2813                            xop);
2814           return \"\";
2815         }
2816       return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ldw %0,%1\";
2817     default:
2818       gcc_unreachable ();
2819     }
2821   [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
2822    (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
2823    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
2824    (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no")
2825    (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2827 ; combiner splitter, pattern found in ldtoa.c .
2828 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
2829 (define_split
2830   [(set (reg:CC_Z CC_REG)
2831         (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
2832                               (match_operand 1 "const_int_operand" ""))
2833                       (match_operand 2 "const_int_operand" "")))
2834    (clobber (match_operand:SI 3 "register_operand" ""))]
2835   "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
2836   [(set (match_dup 3)
2837         (plus:SI (match_dup 0) (match_dup 4)))
2838    (set (reg:CC_Z CC_REG)
2839         (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
2840                       (const_int 0)))]
2841   "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
2843 ;;bic define_insn that allows limm to be the first operand
2844 (define_insn "*bicsi3_insn"
2845    [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
2846         (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
2847                 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
2848   ""
2849   "@
2850    bic%? %0, %2, %1%& ;;constraint 0
2851    bic%? %0,%2,%1  ;;constraint 1
2852    bic %0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
2853    bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
2854    bic %0,%2,%1    ;;constraint 4
2855    bic %0,%2,%S1   ;;constraint 5, FIXME: will it ever get generated ???
2856    bic %0,%S2,%1   ;;constraint 6"
2857   [(set_attr "length" "*,4,4,8,4,8,8")
2858   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
2859   (set_attr "predicable" "no,yes,no,yes,no,no,no")
2860   (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
2862 (define_insn "iorsi3"
2863   [(set (match_operand:SI 0 "dest_reg_operand"        "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w,  w,w,Rcw,  w")
2864         (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq,   0,  0,  c,  0, 0, c,  c,0,  0,  c")
2865                 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL,  0,C0p, I,cL,C0p,I,Cal,Cal")))]
2866   ""
2867   "*
2868   switch (which_alternative)
2869     {
2870     case 0: case 3: case 6: case 7: case 9: case 10: case 11:
2871       return \"or%? %0,%1,%2%&\";
2872     case 1: case 4:
2873       return \"or%? %0,%2,%1%&\";
2874     case 2: case 5: case 8:
2875       return \"bset%? %0,%1,%z2%&\";
2876     default:
2877       gcc_unreachable ();
2878     }"
2879   [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
2880    (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
2881    (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
2882    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
2884 (define_insn "xorsi3"
2885   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w,  w,w,  w,  w")
2886         (xor:SI (match_operand:SI 1 "register_operand"  "%0,   Rcq,  0,  c,  0,  0, c,  c,0,  0,  c")
2887                 (match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, cL,  0,C0p,  I,cL,C0p,I,Cal,Cal")))]
2888   ""
2889   "*
2890   switch (which_alternative)
2891     {
2892     case 0: case 2: case 5: case 6: case 8: case 9: case 10:
2893       return \"xor%? %0,%1,%2%&\";
2894     case 1: case 3:
2895       return \"xor%? %0,%2,%1%&\";
2896     case 4: case 7:
2897       return \"bxor%? %0,%1,%z2\";
2898     default:
2899       gcc_unreachable ();
2900     }
2901   "
2902   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
2903    (set_attr "type" "binary")
2904    (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
2905    (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
2906    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
2908 (define_insn "negsi2"
2909   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
2910         (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
2911   ""
2912   "neg%? %0,%1%&"
2913   [(set_attr "type" "unary")
2914    (set_attr "iscompact" "maybe,true,false,false")
2915    (set_attr "predicable" "no,no,yes,no")])
2917 (define_insn "one_cmplsi2"
2918   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
2919         (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
2920   ""
2921   "not%? %0,%1%&"
2922   [(set_attr "type" "unary,unary")
2923    (set_attr "iscompact" "true,false")])
2925 (define_insn_and_split "one_cmpldi2"
2926   [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
2927         (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
2928   ""
2929   "#"
2930   "&& reload_completed"
2931   [(set (match_dup 2) (not:SI (match_dup 3)))
2932    (set (match_dup 4) (not:SI (match_dup 5)))]
2934   int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
2936   operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
2937   operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
2938   operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
2939   operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
2941   [(set_attr "type" "unary,unary")
2942    (set_attr "cond" "nocond,nocond")
2943    (set_attr "length" "4,8")])
2945 ;; Shift instructions.
2947 (define_expand "ashlsi3"
2948   [(set (match_operand:SI 0 "dest_reg_operand" "")
2949         (ashift:SI (match_operand:SI 1 "register_operand" "")
2950                    (match_operand:SI 2 "nonmemory_operand" "")))]
2951   ""
2952   "
2954   if (!TARGET_BARREL_SHIFTER)
2955     {
2956       emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
2957       DONE;
2958     }
2961 (define_expand "ashrsi3"
2962   [(set (match_operand:SI 0 "dest_reg_operand" "")
2963         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2964                      (match_operand:SI 2 "nonmemory_operand" "")))]
2965   ""
2966   "
2968   if (!TARGET_BARREL_SHIFTER)
2969     {
2970       emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
2971       DONE;
2972     }
2975 (define_expand "lshrsi3"
2976   [(set (match_operand:SI 0 "dest_reg_operand" "")
2977         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2978                      (match_operand:SI 2 "nonmemory_operand" "")))]
2979   ""
2980   "
2982   if (!TARGET_BARREL_SHIFTER)
2983     {
2984       emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
2985       DONE;
2986     }
2989 (define_insn "shift_si3"
2990   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
2991         (match_operator:SI 3 "shift4_operator"
2992                            [(match_operand:SI 1 "register_operand" "0")
2993                             (match_operand:SI 2 "const_int_operand" "n")]))
2994    (clobber (match_scratch:SI 4 "=&r"))
2995    (clobber (reg:CC CC_REG))
2996   ]
2997   "!TARGET_BARREL_SHIFTER"
2998   "* return output_shift (operands);"
2999   [(set_attr "type" "shift")
3000    (set_attr "length" "16")])
3002 (define_insn "shift_si3_loop"
3003   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3004         (match_operator:SI 3 "shift_operator"
3005                            [(match_operand:SI 1 "register_operand" "0,0")
3006                             (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3007    (clobber (match_scratch:SI 4 "=X,X"))
3008    (clobber (reg:SI LP_COUNT))
3009    (clobber (reg:SI LP_START))
3010    (clobber (reg:SI LP_END))
3011    (clobber (reg:CC CC_REG))
3012   ]
3013   "!TARGET_BARREL_SHIFTER"
3014   "* return output_shift (operands);"
3015   [(set_attr "type" "shift")
3016    (set_attr "length" "16,20")])
3018 ; asl, asr, lsr patterns:
3019 ; There is no point in including an 'I' alternative since only the lowest 5
3020 ; bits are used for the shift.  OTOH Cal can be useful if the shift amount
3021 ; is defined in an external symbol, as we don't have special relocations
3022 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3023 ; provide one alternatice for this, without condexec support.
3024 (define_insn "*ashlsi3_insn"
3025   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3026         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3027                    (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3028   "TARGET_BARREL_SHIFTER
3029    && (register_operand (operands[1], SImode)
3030        || register_operand (operands[2], SImode))"
3031   "asl%? %0,%1,%2%&"
3032   [(set_attr "type" "shift")
3033    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3034    (set_attr "predicable" "no,no,no,yes,no,no")
3035    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3037 (define_insn "*ashrsi3_insn"
3038   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3039         (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3040                      (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3041   "TARGET_BARREL_SHIFTER
3042    && (register_operand (operands[1], SImode)
3043        || register_operand (operands[2], SImode))"
3044   "asr%? %0,%1,%2%&"
3045   [(set_attr "type" "shift")
3046    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3047    (set_attr "predicable" "no,no,no,yes,no,no")
3048    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3050 (define_insn "*lshrsi3_insn"
3051   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3052         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3053                      (match_operand:SI 2 "nonmemory_operand"  "N,  N,RcqqM, cL,cL,cCal")))]
3054   "TARGET_BARREL_SHIFTER
3055    && (register_operand (operands[1], SImode)
3056        || register_operand (operands[2], SImode))"
3057   "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3058             ?  \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3059   [(set_attr "type" "shift")
3060    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3061    (set_attr "predicable" "no,no,no,yes,no,no")
3062    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3064 (define_insn "rotrsi3"
3065   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
3066         (rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCal")
3067                      (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3068   "TARGET_BARREL_SHIFTER"
3069   "ror%? %0,%1,%2"
3070   [(set_attr "type" "shift,shift,shift")
3071    (set_attr "predicable" "yes,no,no")
3072    (set_attr "length" "4,4,8")])
3074 ;; Compare / branch instructions.
3076 (define_expand "cbranchsi4"
3077   [(set (reg:CC CC_REG)
3078         (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3079                     (match_operand:SI 2 "nonmemory_operand" "")))
3080    (set (pc)
3081         (if_then_else
3082               (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3083                                                                (const_int 0)])
3084               (label_ref (match_operand 3 "" ""))
3085               (pc)))]
3086   ""
3088   gcc_assert (XEXP (operands[0], 0) == operands[1]);
3089   gcc_assert (XEXP (operands[0], 1) == operands[2]);
3090   operands[0] = gen_compare_reg (operands[0], VOIDmode);
3091   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3092   DONE;
3095 ;; ??? Could add a peephole to generate compare with swapped operands and
3096 ;; modifed cc user if second, but not first operand is a compact register.
3097 (define_insn "cmpsi_cc_insn_mixed"
3098   [(set (reg:CC CC_REG)
3099         (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,c,c, qRcq, c")
3100                     (match_operand:SI 1 "nonmemory_operand" "cO,cI,cL,  Cal, Cal")))]
3101   ""
3102   "cmp%? %0,%B1%&"
3103   [(set_attr "type" "compare")
3104    (set_attr "iscompact" "true,false,false,true_limm,false")
3105    (set_attr "predicable" "no,no,yes,no,yes")
3106    (set_attr "cond" "set")
3107    (set_attr "length" "*,4,4,*,8")])
3109 (define_insn "*cmpsi_cc_zn_insn"
3110   [(set (reg:CC_ZN CC_REG)
3111         (compare:CC_ZN (match_operand:SI 0 "register_operand"  "qRcq,c")
3112                        (const_int 0)))]
3113   ""
3114   "tst%? %0,%0%&"
3115   [(set_attr "type" "compare,compare")
3116    (set_attr "iscompact" "true,false")
3117    (set_attr "predicable" "no,yes")
3118    (set_attr "cond" "set_zn")
3119    (set_attr "length" "*,4")])
3121 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3122 (define_insn "*btst"
3123   [(set (reg:CC_ZN CC_REG)
3124         (compare:CC_ZN
3125           (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3126                            (const_int 1)
3127                            (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3128           (const_int 0)))]
3129   ""
3130   "btst%? %0,%1"
3131   [(set_attr "iscompact" "true,false")
3132    (set_attr "predicable" "no,yes")
3133    (set_attr "cond" "set")
3134    (set_attr "type" "compare")
3135    (set_attr "length" "*,4")])
3137 ; combine suffers from 'simplifications' that replace a one-bit zero
3138 ; extract with a shift if it can prove that the upper bits are zero.
3139 ; arc_reorg sees the code after sched2, which can have caused our
3140 ; inputs to be clobbered even if they were not clobbered before.
3141 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3142 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3143 ; bbit (i.e. bad scheduling) and missed conditional execution,
3144 ; so make this an option.
3145 (define_peephole2
3146   [(set (reg:CC_ZN CC_REG)
3147         (compare:CC_ZN
3148           (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3149                            (const_int 1)
3150                            (match_operand:SI 1 "nonmemory_operand" ""))
3151           (const_int 0)))
3152    (set (pc)
3153         (if_then_else (match_operator 3 "equality_comparison_operator"
3154                                       [(reg:CC_ZN CC_REG) (const_int 0)])
3155                       (label_ref (match_operand 2 "" ""))
3156                       (pc)))]
3157   "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3158   [(parallel [(set (pc)
3159                    (if_then_else
3160                      (match_op_dup 3
3161                        [(zero_extract:SI (match_dup 0)
3162                                          (const_int 1) (match_dup 1))
3163                         (const_int 0)])
3164                      (label_ref (match_dup 2))
3165                      (pc)))
3166               (clobber (reg:CC_ZN CC_REG))])])
3168 (define_insn "*cmpsi_cc_z_insn"
3169   [(set (reg:CC_Z CC_REG)
3170         (compare:CC_Z (match_operand:SI 0 "register_operand"  "qRcq,c")
3171                       (match_operand:SI 1 "p2_immediate_operand"  "O,n")))]
3172   ""
3173   "@
3174         cmp%? %0,%1%&
3175         bxor.f 0,%0,%z1"
3176   [(set_attr "type" "compare,compare")
3177    (set_attr "iscompact" "true,false")
3178    (set_attr "cond" "set,set_zn")
3179    (set_attr "length" "*,4")])
3181 (define_insn "*cmpsi_cc_c_insn"
3182   [(set (reg:CC_C CC_REG)
3183         (compare:CC_C (match_operand:SI 0 "register_operand"  "Rcqq, c,Rcqq,  c")
3184                       (match_operand:SI 1 "nonmemory_operand" "cO,  cI, Cal,Cal")))]
3185   ""
3186   "cmp%? %0,%S1%&"
3187   [(set_attr "type" "compare")
3188    (set_attr "iscompact" "true,false,true_limm,false")
3189    (set_attr "cond" "set")
3190    (set_attr "length" "*,4,*,8")])
3192 ;; Next come the scc insns.
3194 (define_expand "cstoresi4"
3195   [(set (reg:CC CC_REG)
3196         (compare:CC (match_operand:SI 2 "nonmemory_operand" "")
3197                     (match_operand:SI 3 "nonmemory_operand" "")))
3198    (set (match_operand:SI 0 "dest_reg_operand" "")
3199         (match_operator:SI 1 "ordered_comparison_operator" [(reg CC_REG)
3200                                                             (const_int 0)]))]
3201   ""
3203   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3204   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3205   operands[1] = gen_compare_reg (operands[1], SImode);
3206   emit_insn (gen_scc_insn (operands[0], operands[1]));
3207   DONE;
3210 (define_mode_iterator SDF [SF DF])
3212 (define_expand "cstore<mode>4"
3213   [(set (reg:CC CC_REG)
3214         (compare:CC (match_operand:SDF 2 "register_operand" "")
3215                     (match_operand:SDF 3 "register_operand" "")))
3216    (set (match_operand:SI 0 "dest_reg_operand" "")
3217         (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3218                                                     (const_int 0)]))]
3220   "TARGET_OPTFPE"
3222   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3223   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3224   operands[1] = gen_compare_reg (operands[1], SImode);
3225   emit_insn (gen_scc_insn (operands[0], operands[1]));
3226   DONE;
3229 ; We need a separate expander for this lest we loose the mode of CC_REG
3230 ; when match_operator substitutes the literal operand into the comparison.
3231 (define_expand "scc_insn"
3232   [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3234 (define_insn_and_split "*scc_insn"
3235   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3236         (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3237   ""
3238   "#"
3239   "reload_completed"
3240   [(set (match_dup 0) (const_int 1))
3241    (cond_exec
3242      (match_dup 1)
3243      (set (match_dup 0) (const_int 0)))]
3245   operands[1]
3246     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3247                                          GET_MODE (XEXP (operands[1], 0))),
3248                       VOIDmode,
3249                       XEXP (operands[1], 0), XEXP (operands[1], 1));
3251   [(set_attr "type" "unary")])
3253 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3254 ;; that is one lower if the carry flag is set.
3256 ;; ??? Look up negscc insn.  See pa.md for example.
3257 (define_insn "*neg_scc_insn"
3258   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3259         (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3260                  [(reg CC_REG) (const_int 0)])))]
3261   ""
3262   "mov %0,-1\;sub.%D1 %0,%0,%0"
3263   [(set_attr "type" "unary")
3264    (set_attr "length" "8")])
3266 (define_insn "*not_scc_insn"
3267   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3268         (not:SI (match_operator:SI 1 "proper_comparison_operator"
3269                  [(reg CC_REG) (const_int 0)])))]
3270   ""
3271   "mov %0,1\;sub.%d1 %0,%0,%0"
3272   [(set_attr "type" "unary")
3273    (set_attr "length" "8")])
3275 ; cond_exec patterns
3276 (define_insn "*movsi_ne"
3277   [(cond_exec
3278      (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc") (const_int 0))
3279      (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
3280           (match_operand:SI 1 "nonmemory_operand" "C_0,Lc,?Cal")))]
3281   ""
3282   "@
3283         * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3284         mov.ne %0,%1
3285         mov.ne %0,%S1"
3286   [(set_attr "type" "cmove,cmove,cmove")
3287    (set_attr "iscompact" "true,false,false")
3288    (set_attr "length" "2,4,8")])
3290 (define_insn "*movsi_cond_exec"
3291   [(cond_exec
3292      (match_operator 3 "proper_comparison_operator"
3293        [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3294      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3295           (match_operand:SI 1 "nonmemory_operand" "Lc,?Cal")))]
3296   ""
3297   "mov.%d3 %0,%S1"
3298   [(set_attr "type" "cmove")
3299    (set_attr "length" "4,8")])
3301 (define_insn "*commutative_cond_exec"
3302   [(cond_exec
3303      (match_operator 5 "proper_comparison_operator"
3304        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3305      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3306           (match_operator:SI 3 "commutative_operator"
3307             [(match_operand:SI 1 "register_operand" "%0,0")
3308              (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3309   ""
3311   arc_output_commutative_cond_exec (operands, true);
3312   return "";
3314   [(set_attr "cond" "use")
3315    (set_attr "type" "cmove")
3316    (set_attr_alternative "length"
3317      [(const_int 4)
3318       (cond
3319         [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3320              (const_int 4))
3321          (const_int 4)]
3322         (const_int 8))])])
3324 (define_insn "*sub_cond_exec"
3325   [(cond_exec
3326      (match_operator 4 "proper_comparison_operator"
3327        [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3328      (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3329           (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3330                     (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3331   ""
3332   "@
3333         sub.%d4 %0,%1,%2
3334         rsub.%d4 %0,%2,%1
3335         rsub.%d4 %0,%2,%1"
3336   [(set_attr "cond" "use")
3337    (set_attr "type" "cmove")
3338    (set_attr "length" "4,4,8")])
3340 (define_insn "*noncommutative_cond_exec"
3341   [(cond_exec
3342      (match_operator 5 "proper_comparison_operator"
3343        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3344      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3345           (match_operator:SI 3 "noncommutative_operator"
3346             [(match_operand:SI 1 "register_operand" "0,0")
3347              (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3348   ""
3349   "%O3.%d5 %0,%1,%2"
3350   [(set_attr "cond" "use")
3351    (set_attr "type" "cmove")
3352    (set_attr "length" "4,8")])
3354 ;; These control RTL generation for conditional jump insns
3355 ;; Match both normal and inverted jump.
3357 ; We need a separate expander for this lest we loose the mode of CC_REG
3358 ; when match_operator substitutes the literal operand into the comparison.
3359 (define_expand "branch_insn"
3360   [(set (pc)
3361         (if_then_else (match_operand 1 "" "")
3362                       (label_ref (match_operand 0 "" ""))
3363                       (pc)))])
3365 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3366 ; are three reasons why we need to consider branches to be length 6:
3367 ; - annull-false delay slot insns are implemented using conditional execution,
3368 ;   thus preventing short insn formation where used.
3369 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3370 ;   using conditional execution, preventing short insn formation where used.
3371 ; - for ARC700: likely or somewhat likely taken branches are made long and
3372 ;   unaligned if possible to avoid branch penalty.
3373 (define_insn "*branch_insn"
3374   [(set (pc)
3375         (if_then_else (match_operator 1 "proper_comparison_operator"
3376                                       [(reg CC_REG) (const_int 0)])
3377                       (label_ref (match_operand 0 "" ""))
3378                       (pc)))]
3379   ""
3380   "*
3382   if (arc_ccfsm_branch_deleted_p ())
3383     {
3384       arc_ccfsm_record_branch_deleted ();
3385       return \"; branch deleted, next insns conditionalized\";
3386     }
3387   else
3388     {
3389       arc_ccfsm_record_condition (operands[1], false, insn, 0);
3390       if (get_attr_length (insn) == 2)
3391          return \"b%d1%? %^%l0%&\";
3392       else
3393          return \"b%d1%# %^%l0\";
3394     }
3396   [(set_attr "type" "branch")
3397    (set
3398      (attr "length")
3399      (cond [
3400        (eq_attr "delay_slot_filled" "yes")
3401        (const_int 4)
3403        (ne
3404          (if_then_else
3405            (match_operand 1 "equality_comparison_operator" "")
3406            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3407                 (gt (minus (match_dup 0) (pc))
3408                     (minus (const_int 506)
3409                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3410            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3411                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3412                 (gt (minus (match_dup 0) (pc))
3413                     (minus (const_int 58)
3414                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3415          (const_int 0))
3416        (const_int 4)]
3417       (const_int 2)))
3419    (set (attr "iscompact")
3420         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3421               (const_string "false")))])
3423 (define_insn "*rev_branch_insn"
3424   [(set (pc)
3425         (if_then_else (match_operator 1 "proper_comparison_operator"
3426                                       [(reg CC_REG) (const_int 0)])
3427                       (pc)
3428                       (label_ref (match_operand 0 "" ""))))]
3429   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3430   "*
3432   if (arc_ccfsm_branch_deleted_p ())
3433     {
3434       arc_ccfsm_record_branch_deleted ();
3435       return \"; branch deleted, next insns conditionalized\";
3436     }
3437   else
3438     {
3439       arc_ccfsm_record_condition (operands[1], true, insn, 0);
3440       if (get_attr_length (insn) == 2)
3441          return \"b%D1%? %^%l0\";
3442       else
3443          return \"b%D1%# %^%l0\";
3444     }
3446   [(set_attr "type" "branch")
3447    (set
3448      (attr "length")
3449      (cond [
3450        (eq_attr "delay_slot_filled" "yes")
3451        (const_int 4)
3453        (ne
3454          (if_then_else
3455            (match_operand 1 "equality_comparison_operator" "")
3456            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3457                 (gt (minus (match_dup 0) (pc))
3458                     (minus (const_int 506)
3459                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3460            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3461                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3462                 (gt (minus (match_dup 0) (pc))
3463                     (minus (const_int 58)
3464                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3465          (const_int 0))
3466        (const_int 4)]
3467       (const_int 2)))
3469    (set (attr "iscompact")
3470         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3471               (const_string "false")))])
3473 ;; Unconditional and other jump instructions.
3475 (define_expand "jump"
3476   [(set (pc) (label_ref (match_operand 0 "" "")))]
3477   ""
3478   "")
3480 (define_insn "jump_i"
3481   [(set (pc) (label_ref (match_operand 0 "" "")))]
3482   "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3483   "b%!%* %^%l0%&"
3484   [(set_attr "type" "uncond_branch")
3485    (set (attr "iscompact")
3486         (if_then_else (match_test "get_attr_length (insn) == 2")
3487                       (const_string "true") (const_string "false")))
3488    (set_attr "cond" "canuse")
3489    (set (attr "length")
3490         (cond [
3491           ; In arc_reorg we just guesstimate; might be more or less than 4.
3492           (match_test "arc_branch_size_unknown_p ()")
3493           (const_int 4)
3495           (eq_attr "delay_slot_filled" "yes")
3496           (const_int 4)
3498           (match_test "CROSSING_JUMP_P (insn)")
3499           (const_int 4)
3501           (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3502                (gt (minus (match_dup 0) (pc))
3503                    (minus (const_int 506)
3504                           (symbol_ref "get_attr_delay_slot_length (insn)"))))
3505           (const_int 4)]
3506          (const_int 2)))])
3508 (define_insn "indirect_jump"
3509   [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3510   ""
3511   "j%!%* [%0]%&"
3512   [(set_attr "type" "jump")
3513    (set_attr "iscompact" "false,false,false,maybe,false")
3514    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3516 ;; Implement a switch statement.
3518 (define_expand "casesi"
3519   [(set (match_dup 5)
3520         (minus:SI (match_operand:SI 0 "register_operand" "")
3521                   (match_operand:SI 1 "nonmemory_operand" "")))
3522    (set (reg:CC CC_REG)
3523         (compare:CC (match_dup 5)
3524                     (match_operand:SI 2 "nonmemory_operand" "")))
3525    (set (pc)
3526         (if_then_else (gtu (reg:CC CC_REG)
3527                            (const_int 0))
3528                       (label_ref (match_operand 4 "" ""))
3529                       (pc)))
3530    (set (match_dup 6)
3531         (unspec:SI [(match_operand 3 "" "")
3532                     (match_dup 5) (match_dup 7)] UNSPEC_CASESI))
3533    (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
3534   ""
3535   "
3537   rtx x;
3539   operands[5] = gen_reg_rtx (SImode);
3540   operands[6] = gen_reg_rtx (SImode);
3541   operands[7] = operands[3];
3542   emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
3543   emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
3544   x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
3545   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
3546                             gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
3547   emit_jump_insn (gen_rtx_SET (pc_rtx, x));
3548   if (TARGET_COMPACT_CASESI)
3549     {
3550       emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
3551     }
3552   else
3553     {
3554       operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3555       if (flag_pic || !cse_not_expected)
3556         operands[3] = force_reg (Pmode, operands[3]);
3557       emit_insn (gen_casesi_load (operands[6],
3558                                   operands[3], operands[5], operands[7]));
3559       if (CASE_VECTOR_PC_RELATIVE || flag_pic)
3560         emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
3561       emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
3562     }
3563   DONE;
3566 (define_insn "casesi_load"
3567   [(set (match_operand:SI 0 "register_operand"             "=Rcq,r,r")
3568         (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
3569                     (match_operand:SI 2 "register_operand"  "Rcq,c,c")
3570                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))]
3571   ""
3572   "*
3574   rtx diff_vec = PATTERN (next_nonnote_insn (operands[3]));
3576   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
3577     {
3578       gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
3579       gcc_assert (GET_MODE (diff_vec) == SImode);
3580       gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
3581     }
3583   switch (GET_MODE (diff_vec))
3584     {
3585     case SImode:
3586       return \"ld.as %0,[%1,%2]%&\";
3587     case HImode:
3588       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3589         return \"ldw.as %0,[%1,%2]\";
3590       return \"ldw.x.as %0,[%1,%2]\";
3591     case QImode:
3592       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3593         return \"ldb%? %0,[%1,%2]%&\";
3594       return \"ldb.x %0,[%1,%2]\";
3595     default:
3596       gcc_unreachable ();
3597     }
3599   [(set_attr "type" "load")
3600    (set_attr_alternative "iscompact"
3601      [(cond
3602         [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn (operands[3])))")
3603              (symbol_ref "QImode"))
3604          (const_string "false")
3605          (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn (operands[3]))).offset_unsigned")
3606          (const_string "false")]
3607         (const_string "true"))
3608       (const_string "false")
3609       (const_string "false")])
3610    (set_attr_alternative "length"
3611      [(cond
3612         [(eq_attr "iscompact" "false") (const_int 4)
3613         ; We have to mention (match_dup 3) to convince genattrtab.c that this
3614         ; is a varying length insn.
3615          (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
3616          (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
3617         (const_int 2))
3618       (const_int 4)
3619       (const_int 8)])])
3621 ; Unlike the canonical tablejump, this pattern always uses a jump address,
3622 ; even for CASE_VECTOR_PC_RELATIVE.
3623 (define_insn "casesi_jump"
3624   [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
3625    (use (label_ref (match_operand 1 "" "")))]
3626   ""
3627   "j%!%* [%0]%&"
3628   [(set_attr "type" "jump")
3629    (set_attr "iscompact" "false,maybe,false")
3630    (set_attr "cond" "canuse")])
3632 (define_insn "casesi_compact_jump"
3633   [(set (pc)
3634         (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
3635                    UNSPEC_CASESI))
3636    (use (label_ref (match_operand 1 "" "")))
3637    (clobber (match_scratch:SI 2 "=q,0"))]
3638   "TARGET_COMPACT_CASESI"
3639   "*
3641   rtx diff_vec = PATTERN (next_nonnote_insn (operands[1]));
3642   int unalign = arc_get_unalign ();
3643   rtx xop[3];
3644   const char *s;
3646   xop[0] = operands[0];
3647   xop[2] = operands[2];
3648   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
3650   switch (GET_MODE (diff_vec))
3651     {
3652     case SImode:
3653       /* Max length can be 12 in this case, but this is OK because
3654          2 of these are for alignment, and are anticipated in the length
3655          of the ADDR_DIFF_VEC.  */
3656       if (unalign && !satisfies_constraint_Rcq (xop[0]))
3657         s = \"add2 %2,pcl,%0\n\tld_s%2,[%2,12]\";
3658       else if (unalign)
3659         s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
3660       else
3661         s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
3662       arc_clear_unalign ();
3663       break;
3664     case HImode:
3665       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3666         {
3667           if (satisfies_constraint_Rcq (xop[0]))
3668             {
3669               s = \"add_s %2,%0,%1\n\tldw.as %2,[pcl,%2]\";
3670               xop[1] = GEN_INT ((10 - unalign) / 2U);
3671             }
3672           else
3673             {
3674               s = \"add1 %2,pcl,%0\n\tldw_s %2,[%2,%1]\";
3675               xop[1] = GEN_INT (10 + unalign);
3676             }
3677         }
3678       else
3679         {
3680           if (satisfies_constraint_Rcq (xop[0]))
3681             {
3682               s = \"add_s %2,%0,%1\n\tldw.x.as %2,[pcl,%2]\";
3683               xop[1] = GEN_INT ((10 - unalign) / 2U);
3684             }
3685           else
3686             {
3687               s = \"add1 %2,pcl,%0\n\tldw_s.x %2,[%2,%1]\";
3688               xop[1] = GEN_INT (10 + unalign);
3689             }
3690         }
3691       arc_toggle_unalign ();
3692       break;
3693     case QImode:
3694       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3695         {
3696           if ((rtx_equal_p (xop[2], xop[0])
3697                || find_reg_note (insn, REG_DEAD, xop[0]))
3698               && satisfies_constraint_Rcq (xop[0]))
3699             {
3700               s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
3701               xop[1] = GEN_INT (8 + unalign);
3702             }
3703           else
3704             {
3705               s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
3706               xop[1] = GEN_INT (10 + unalign);
3707               arc_toggle_unalign ();
3708             }
3709         }
3710       else if ((rtx_equal_p (xop[0], xop[2])
3711                 || find_reg_note (insn, REG_DEAD, xop[0]))
3712                && satisfies_constraint_Rcq (xop[0]))
3713         {
3714           s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
3715           xop[1] = GEN_INT (10 - unalign);
3716           arc_toggle_unalign ();
3717         }
3718       else
3719         {
3720           /* ??? Length is 12.  */
3721           s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
3722           xop[1] = GEN_INT (8 + unalign);
3723         }
3724       break;
3725     default:
3726       gcc_unreachable ();
3727     }
3728   output_asm_insn (s, xop);
3729   return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
3731   [(set_attr "length" "10")
3732    (set_attr "type" "jump")
3733    (set_attr "iscompact" "true")
3734    (set_attr "cond" "nocond")])
3736 (define_expand "call"
3737   ;; operands[1] is stack_size_rtx
3738   ;; operands[2] is next_arg_register
3739   [(parallel [(call (match_operand:SI 0 "call_operand" "")
3740                     (match_operand 1 "" ""))
3741              (clobber (reg:SI 31))])]
3742   ""
3743   "{
3744     rtx callee;
3746     gcc_assert (MEM_P (operands[0]));
3747     callee  = XEXP (operands[0], 0);
3748     if (crtl->profile && arc_profile_call (callee))
3749       {
3750         emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
3751                                                            \"_mcount_call\"),
3752                                        operands[1]));
3753         DONE;
3754       }
3755     /* This is to decide if we should generate indirect calls by loading the
3756        32 bit address of the callee into a register before performing the
3757        branch and link - this exposes cse opportunities.
3758        Also, in weird cases like compile/20010107-1.c, we may get a PLUS.  */
3759     if (GET_CODE (callee) != REG
3760         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
3761       XEXP (operands[0], 0) = force_reg (Pmode, callee);
3762   }
3766 ; Rcq, which is used in alternative 0, checks for conditional execution.
3767 ; At instruction output time, if it doesn't match and we end up with
3768 ; alternative 1 ("q"), that means that we can't use the short form.
3769 (define_insn "*call_i"
3770   [(call (mem:SI (match_operand:SI 0
3771                   "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
3772          (match_operand 1 "" ""))
3773    (clobber (reg:SI 31))]
3774   ""
3775   "@
3776    jl%!%* [%0]%&
3777    jl%!%* [%0]%&
3778    jl%!%* [%0]
3779    bl%!%* %P0
3780    bl%!%* %P0
3781    jl%!%* %S0
3782    jl%* %S0
3783    jl%! %S0"
3784   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
3785    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
3786    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
3787    (set_attr "length" "*,*,4,4,4,4,4,8")])
3789 (define_insn "call_prof"
3790   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal"))
3791          (match_operand 1 "" ""))
3792    (clobber (reg:SI 31))
3793    (use (reg:SI 8))
3794    (use (reg:SI 9))]
3795    ""
3796   "@
3797    bl%!%* %P0;2
3798    jl%! %^%S0"
3799   [(set_attr "type" "call,call_no_delay_slot")
3800    (set_attr "predicable" "yes,yes")
3801    (set_attr "length" "4,8")])
3803 (define_expand "call_value"
3804   ;; operand 2 is stack_size_rtx
3805   ;; operand 3 is next_arg_register
3806   [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
3807                    (call (match_operand:SI 1 "call_operand" "")
3808                          (match_operand 2 "" "")))
3809              (clobber (reg:SI 31))])]
3810   ""
3811   "
3812   {
3813     rtx callee;
3815     gcc_assert (MEM_P (operands[1]));
3816     callee = XEXP (operands[1], 0);
3817     if (crtl->profile && arc_profile_call (callee))
3818       {
3819         emit_call_insn (gen_call_value_prof (operands[0],
3820                                              gen_rtx_SYMBOL_REF (Pmode,
3821                                                             \"_mcount_call\"),
3822                                              operands[2]));
3823         DONE;
3824       }
3825      /* See the comment in define_expand \"call\".  */
3826     if (GET_CODE (callee) != REG
3827         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
3828       XEXP (operands[1], 0) = force_reg (Pmode, callee);
3829   }")
3832 ; Rcq, which is used in alternative 0, checks for conditional execution.
3833 ; At instruction output time, if it doesn't match and we end up with
3834 ; alternative 1 ("q"), that means that we can't use the short form.
3835 (define_insn "*call_value_i"
3836   [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,w,w,  w")
3837         (call (mem:SI (match_operand:SI 1
3838                        "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
3839               (match_operand 2 "" "")))
3840    (clobber (reg:SI 31))]
3841   ""
3842   "@
3843    jl%!%* [%1]%&
3844    jl%!%* [%1]%&
3845    jl%!%* [%1]
3846    bl%!%* %P1;1
3847    bl%!%* %P1;1
3848    jl%!%* %S1
3849    jl%* %S1
3850    jl%! %S1"
3851   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
3852    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
3853    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
3854    (set_attr "length" "*,*,4,4,4,4,4,8")])
3856 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
3857 ; use it for lack of inter-procedural branch shortening.
3858 ; Link-time relaxation would help...
3861 (define_insn "call_value_prof"
3862   [(set (match_operand 0 "dest_reg_operand" "=r,r")
3863         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal"))
3864               (match_operand 2 "" "")))
3865    (clobber (reg:SI 31))
3866    (use (reg:SI 8))
3867    (use (reg:SI 9))]
3868    ""
3869   "@
3870    bl%!%* %P1;1
3871    jl%! %^%S1"
3872   [(set_attr "type" "call,call_no_delay_slot")
3873    (set_attr "predicable" "yes,yes")
3874    (set_attr "length" "4,8")])
3876 (define_insn "nop"
3877   [(const_int 0)]
3878   ""
3879   "nop%?"
3880   [(set_attr "type" "misc")
3881    (set_attr "iscompact" "true")
3882    (set_attr "cond" "canuse")
3883    (set_attr "length" "2")])
3885 ;; Special pattern to flush the icache.
3886 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
3888 (define_insn "flush_icache"
3889   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
3890   ""
3891   "* return \"\";"
3892   [(set_attr "type" "misc")])
3894 ;; Split up troublesome insns for better scheduling.
3896 ;; Peepholes go at the end.
3897 ;;asl followed by add can be replaced by an add{1,2,3}
3898 ;; Three define_peepholes have been added for this optimization
3899 ;; ??? This used to target non-canonical rtl.  Now we use add_n, which
3900 ;; can be generated by combine.  Check if these peepholes still provide
3901 ;; any benefit.
3903 ;; -------------------------------------------------------------
3904 ;; Pattern 1 : r0 = r1 << {i}
3905 ;;             r3 = r4/INT + r0     ;;and commutative
3906 ;;                 ||
3907 ;;                 \/
3908 ;;             add{i} r3,r4/INT,r1
3909 ;; -------------------------------------------------------------
3910 ;; ??? This should be covered by combine, alas, at times combine gets
3911 ;; too clever for it's own good: when the shifted input is known to be
3912 ;; either 0 or 1, the operation will be made into an if-then-else, and
3913 ;; thus fail to match the add_n pattern.  Example: _mktm_r, line 85 in
3914 ;; newlib/libc/time/mktm_r.c .
3916 (define_peephole2
3917   [(set (match_operand:SI 0 "dest_reg_operand" "")
3918         (ashift:SI (match_operand:SI 1 "register_operand" "")
3919                    (match_operand:SI 2 "const_int_operand" "")))
3920   (set (match_operand:SI 3 "dest_reg_operand" "")
3921        (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
3922                 (match_operand:SI 5 "nonmemory_operand" "")))]
3923   "(INTVAL (operands[2]) == 1
3924     || INTVAL (operands[2]) == 2
3925     || INTVAL (operands[2]) == 3)
3926    && (true_regnum (operands[4]) == true_regnum (operands[0])
3927        || true_regnum (operands[5]) == true_regnum (operands[0]))
3928    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
3929  ;; the preparation statements take care to put proper operand in operands[4]
3930  ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
3931   [(set (match_dup 3)
3932         (plus:SI (mult:SI (match_dup 1)
3933                           (match_dup 2))
3934                  (match_dup 4)))]
3935   "if (true_regnum (operands[4]) == true_regnum (operands[0]))
3936       operands[4] = operands[5];
3937    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
3940 ;; -------------------------------------------------------------
3941 ;; Pattern 1 : r0 = r1 << {i}
3942 ;;             r3 = r4 - r0
3943 ;;                 ||
3944 ;;                 \/
3945 ;;             sub{i} r3,r4,r1
3946 ;; -------------------------------------------------------------
3947 ;; ??? This should be covered by combine, alas, at times combine gets
3948 ;; too clever for it's own good: when the shifted input is known to be
3949 ;; either 0 or 1, the operation will be made into an if-then-else, and
3950 ;; thus fail to match the sub_n pattern.  Example: __ieee754_yn, line 239 in
3951 ;; newlib/libm/math/e_jn.c .
3953 (define_peephole2
3954   [(set (match_operand:SI 0 "dest_reg_operand" "")
3955         (ashift:SI (match_operand:SI 1 "register_operand" "")
3956                    (match_operand:SI 2 "const_int_operand" "")))
3957    (set (match_operand:SI 3 "dest_reg_operand" "")
3958         (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
3959                   (match_dup 0)))]
3960   "(INTVAL (operands[2]) == 1
3961     || INTVAL (operands[2]) == 2
3962     || INTVAL (operands[2]) == 3)
3963    && (peep2_reg_dead_p (2, operands[0])
3964        || (true_regnum (operands[3]) == true_regnum (operands[0])))"
3965   [(set (match_dup 3)
3966         (minus:SI (match_dup 4)
3967                   (mult:SI (match_dup 1)
3968                            (match_dup 2))))]
3969   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
3974 ; When using the high single bit, the result of a multiply is either
3975 ; the original number or zero.  But MPY costs 4 cycles, which we
3976 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
3977 (define_peephole2
3978   [(set (match_operand:SI 0 "dest_reg_operand" "")
3979         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3980                      (const_int 31)))
3981    (set (match_operand:SI 4 "register_operand" "")
3982         (mult:SI (match_operand:SI 2 "register_operand")
3983                  (match_operand:SI 3 "nonmemory_operand" "")))]
3984   "TARGET_ARC700 && !TARGET_NOMPY_SET
3985    && (rtx_equal_p (operands[0], operands[2])
3986        || rtx_equal_p (operands[0], operands[3]))
3987    && peep2_regno_dead_p (0, CC_REG)
3988    && (rtx_equal_p (operands[0], operands[4])
3989        || (peep2_reg_dead_p (2, operands[0])
3990           && peep2_reg_dead_p (1, operands[4])))"
3991   [(parallel [(set (reg:CC_Z CC_REG)
3992                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
3993                                  (const_int 0)))
3994               (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
3995    (cond_exec
3996      (ne (reg:CC_Z CC_REG) (const_int 0))
3997      (set (match_dup 4) (match_dup 5)))]
3999   if (!rtx_equal_p (operands[0], operands[2]))
4000     operands[5] = operands[2];
4001   else if (!rtx_equal_p (operands[0], operands[3]))
4002     operands[5] = operands[3];
4003   else
4004     operands[5] = operands[4]; /* Actually a no-op... presumably rare.  */
4007 (define_peephole2
4008   [(set (match_operand:SI 0 "dest_reg_operand" "")
4009         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4010                      (const_int 31)))
4011    (set (match_operand:SI 4 "register_operand" "")
4012         (mult:SI (match_operand:SI 2 "register_operand")
4013                  (match_operand:SI 3 "nonmemory_operand" "")))]
4014   "TARGET_ARC700 && !TARGET_NOMPY_SET
4015    && (rtx_equal_p (operands[0], operands[2])
4016        || rtx_equal_p (operands[0], operands[3]))
4017    && peep2_regno_dead_p (2, CC_REG)"
4018   [(parallel [(set (reg:CC_Z CC_REG)
4019                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4020                                  (const_int 0)))
4021               (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4022    (set (match_dup 4) (match_dup 5))
4023    (cond_exec
4024      (eq (reg:CC_Z CC_REG) (const_int 0))
4025      (set (match_dup 4) (const_int 0)))]
4026  "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4028 ;; Instructions generated through builtins
4030 (define_insn "clrsbsi2"
4031   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4032         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4033   "TARGET_NORM"
4034   "@
4035    norm \t%0, %1
4036    norm \t%0, %S1"
4037   [(set_attr "length" "4,8")
4038    (set_attr "type" "two_cycle_core,two_cycle_core")])
4040 (define_insn "norm_f"
4041   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4042         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4043    (set (reg:CC_ZN CC_REG)
4044         (compare:CC_ZN (match_dup 1) (const_int 0)))]
4045   "TARGET_NORM"
4046   "@
4047    norm.f\t%0, %1
4048    norm.f\t%0, %S1"
4049   [(set_attr "length" "4,8")
4050    (set_attr "type" "two_cycle_core,two_cycle_core")])
4052 (define_insn_and_split "clrsbhi2"
4053   [(set (match_operand:HI  0 "dest_reg_operand" "=w,w")
4054         (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4055   "TARGET_NORM"
4056   "#"
4057   "reload_completed"
4058   [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4059   "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4061 (define_insn "normw"
4062   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4063         (zero_extend:SI
4064           (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4065   "TARGET_NORM"
4066   "@
4067    normw \t%0, %1
4068    normw \t%0, %S1"
4069   [(set_attr "length" "4,8")
4070    (set_attr "type" "two_cycle_core,two_cycle_core")])
4072 (define_expand "clzsi2"
4073   [(set (match_operand:SI 0 "dest_reg_operand" "")
4074         (clz:SI (match_operand:SI 1 "register_operand" "")))]
4075   "TARGET_NORM"
4077   emit_insn (gen_norm_f (operands[0], operands[1]));
4078   emit_insn
4079     (gen_rtx_COND_EXEC
4080       (VOIDmode,
4081        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4082        gen_rtx_SET (operands[0], const0_rtx)));
4083   emit_insn
4084     (gen_rtx_COND_EXEC
4085       (VOIDmode,
4086        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4087        gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4088   DONE;
4091 (define_expand "ctzsi2"
4092   [(set (match_operand:SI 0 "register_operand" "")
4093         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
4094   "TARGET_NORM"
4096   rtx temp = operands[0];
4098   if (reg_overlap_mentioned_p (temp, operands[1])
4099       || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4100           && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4101                                  REGNO (temp))))
4102     temp = gen_reg_rtx (SImode);
4103   emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4104   emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4105   emit_insn (gen_clrsbsi2 (temp, temp));
4106   emit_insn
4107     (gen_rtx_COND_EXEC
4108       (VOIDmode,
4109        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4110        gen_rtx_SET (operands[0], GEN_INT (32))));
4111   emit_insn
4112     (gen_rtx_COND_EXEC
4113       (VOIDmode,
4114        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4115        gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31), temp))));
4116   DONE;
4120 (define_insn "swap"
4121   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
4122         (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4123                             UNSPEC_SWAP))]
4124   "TARGET_SWAP"
4125   "@
4126    swap \t%0, %1
4127    swap \t%0, %S1
4128    swap \t%0, %1"
4129   [(set_attr "length" "4,8,4")
4130    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4132 ;; FIXME: an intrinsic for multiply is daft.  Can we remove this?
4133 (define_insn "mul64"
4134   [(unspec [(match_operand:SI 0 "general_operand" "%q,r,r,r")
4135                      (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
4136                    UNSPEC_MUL64)]
4137   "TARGET_MUL64_SET"
4138   "@
4139    mul64%? \t0, %0, %1%&
4140    mul64%? \t0, %0, %1
4141    mul64 \t0, %0, %1
4142    mul64%? \t0, %0, %S1"
4143   [(set_attr "length" "2,4,4,8")
4144   (set_attr "iscompact" "true,false,false,false")
4145   (set_attr "type" "binary,binary,binary,binary")
4146   (set_attr "cond" "canuse,canuse, nocond, canuse")])
4148 (define_insn "mulu64"
4149   [(unspec [(match_operand:SI 0 "general_operand" "%r,r,r,r")
4150                      (match_operand:SI 1 "general_operand" "rL,I,r,Cal")]
4151                    UNSPEC_MULU64)]
4152   "TARGET_MUL64_SET"
4153   "@
4154    mulu64%? \t0, %0, %1
4155    mulu64 \t0, %0, %1
4156    mulu64 \t0, %0, %1
4157    mulu64%? \t0, %0, %S1"
4158   [(set_attr "length" "4,4,4,8")
4159    (set_attr "type" "binary,binary,binary,binary")
4160    (set_attr "cond" "canuse,nocond,nocond,canuse")])
4162 (define_insn "divaw"
4163   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4164                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4165                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4166                                            UNSPEC_DIVAW))]
4167   "TARGET_ARC700 || TARGET_EA_SET"
4168   "@
4169    divaw \t%0, %1, %2
4170    divaw \t%0, %S1, %2
4171    divaw \t%0, %1, %S2"
4172   [(set_attr "length" "4,8,8")
4173    (set_attr "type" "divaw,divaw,divaw")])
4175 (define_insn "flag"
4176   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4177                    VUNSPEC_FLAG)]
4178   ""
4179   "@
4180     flag%? %0
4181     flag %0
4182     flag%? %S0"
4183   [(set_attr "length" "4,4,8")
4184    (set_attr "type" "misc,misc,misc")
4185    (set_attr "predicable" "yes,no,yes")
4186    (set_attr "cond" "clob,clob,clob")])
4188 (define_insn "brk"
4189   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4190                    VUNSPEC_BRK)]
4191   ""
4192   "brk"
4193   [(set_attr "length" "4")
4194   (set_attr "type" "misc")])
4196 (define_insn "rtie"
4197   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4198                    VUNSPEC_RTIE)]
4199   ""
4200   "rtie"
4201   [(set_attr "length" "4")
4202   (set_attr "type" "misc")
4203   (set_attr "cond" "clob")])
4205 (define_insn "sync"
4206   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4207                    VUNSPEC_SYNC)]
4208   ""
4209   "sync"
4210   [(set_attr "length" "4")
4211   (set_attr "type" "misc")])
4213 (define_insn "swi"
4214   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4215                    VUNSPEC_SWI)]
4216   ""
4217   "*
4219     if(TARGET_ARC700)
4220         return \"trap0\";
4221     else
4222         return \"swi\";
4224   [(set_attr "length" "4")
4225   (set_attr "type" "misc")])
4228 (define_insn "sleep"
4229   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4230                    VUNSPEC_SLEEP)]
4231   "check_if_valid_sleep_operand(operands,0)"
4232   "sleep %0"
4233   [(set_attr "length" "4")
4234   (set_attr "type" "misc")])
4236 (define_insn "core_read"
4237   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4238         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4239                             VUNSPEC_CORE_READ))]
4240   ""
4241   "*
4242     if (check_if_valid_regno_const (operands, 1))
4243       return \"mov \t%0, r%1\";
4244     return \"mov \t%0, r%1\";
4245   "
4246   [(set_attr "length" "4")
4247    (set_attr "type" "unary")])
4249 (define_insn "core_write"
4250   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4251                      (match_operand:SI 1 "general_operand" "Hn,!r")]
4252                    VUNSPEC_CORE_WRITE)]
4253   ""
4254   "*
4255     if (check_if_valid_regno_const (operands, 1))
4256       return \"mov \tr%1, %0\";
4257     return \"mov \tr%1, %0\";
4258   "
4259   [(set_attr "length" "4")
4260    (set_attr "type" "unary")])
4262 (define_insn "lr"
4263   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
4264         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4265                             VUNSPEC_LR))]
4266   ""
4267   "lr\t%0, [%1]"
4268   [(set_attr "length" "4,8,4,8")
4269    (set_attr "type" "lr,lr,lr,lr")])
4271 (define_insn "sr"
4272   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4273                      (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4274                    VUNSPEC_SR)]
4275   ""
4276   "sr\t%S0, [%1]"
4277   [(set_attr "length" "8,4,8,4")
4278    (set_attr "type" "sr,sr,sr,sr")])
4280 (define_insn "trap_s"
4281   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4282                    VUNSPEC_TRAP_S)]
4283   "TARGET_ARC700"
4285   if (which_alternative == 0)
4286     {
4287       arc_toggle_unalign ();
4288       return \"trap_s %0\";
4289     }
4291   /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4292      because *.md files do not get scanned by exgettext.  */
4293   fatal_error (input_location,
4294                \"operand to trap_s should be an unsigned 6-bit value\");
4296   [(set_attr "length" "2")
4297   (set_attr "type" "misc")])
4299 (define_insn "unimp_s"
4300   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4301                    VUNSPEC_UNIMP_S)]
4302   "TARGET_ARC700"
4303   "unimp_s"
4304   [(set_attr "length" "4")
4305   (set_attr "type" "misc")])
4307 ;; End of instructions generated through builtins
4309 ; Since the demise of REG_N_SETS as reliable data readily available to the
4310 ; target, it is no longer possible to find out
4311 ; in the prologue / epilogue expanders how many times blink is set.
4312 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4313 ; any explicit use of blink will cause it to be saved; hence we cannot
4314 ; represent the blink use in return / sibcall instructions themselves, and
4315 ; instead have to show it in EPILOGUE_USES and must explicitly
4316 ; forbid instructions that change blink in the return / sibcall delay slot.
4317 (define_expand "sibcall"
4318   [(parallel [(call (match_operand 0 "memory_operand" "")
4319                     (match_operand 1 "general_operand" ""))
4320               (simple_return)
4321               (use (match_operand 2 "" ""))])]
4322   ""
4323   "
4324   {
4325     rtx callee = XEXP (operands[0], 0);
4327     if (operands[2] == NULL_RTX)
4328       operands[2] = const0_rtx;
4329     if (crtl->profile && arc_profile_call (callee))
4330       {
4331         emit_insn (gen_sibcall_prof
4332                     (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4333                      operands[1], operands[2]));
4334         DONE;
4335       }
4336     if (GET_CODE (callee) != REG
4337         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4338       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4339   }"
4342 (define_expand "sibcall_value"
4343   [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4344                    (call (match_operand 1 "memory_operand" "")
4345                          (match_operand 2 "general_operand" "")))
4346               (simple_return)
4347               (use (match_operand 3 "" ""))])]
4348   ""
4349   "
4350   {
4351     rtx callee = XEXP (operands[1], 0);
4353     if (operands[3] == NULL_RTX)
4354       operands[3] = const0_rtx;
4355     if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
4356       {
4357         emit_insn (gen_sibcall_value_prof
4358                     (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4359                      operands[2], operands[3]));
4360         DONE;
4361       }
4362     if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4363       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4364   }"
4367 (define_insn "*sibcall_insn"
4368  [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4369                  "Cbp,Cbr,Rs5,Rsc,Cal"))
4370         (match_operand 1 "" ""))
4371   (simple_return)
4372   (use (match_operand 2 "" ""))]
4373   ""
4374   "@
4375    b%!%* %P0
4376    b%!%* %P0
4377    j%!%* [%0]%&
4378    j%!%* [%0]
4379    j%! %P0"
4380   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4381    (set_attr "predicable" "yes,no,no,yes,yes")
4382    (set_attr "iscompact" "false,false,maybe,false,false")
4383    (set_attr "is_SIBCALL" "yes")]
4386 (define_insn "*sibcall_value_insn"
4387  [(set (match_operand 0 "dest_reg_operand" "")
4388        (call (mem:SI (match_operand:SI 1 "call_address_operand"
4389               "Cbp,Cbr,Rs5,Rsc,Cal"))
4390              (match_operand 2 "" "")))
4391   (simple_return)
4392   (use (match_operand 3 "" ""))]
4393   ""
4394   "@
4395    b%!%* %P1
4396    b%!%* %P1
4397    j%!%* [%1]%&
4398    j%!%* [%1]
4399    j%! %P1"
4400   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4401    (set_attr "predicable" "yes,no,no,yes,yes")
4402    (set_attr "iscompact" "false,false,maybe,false,false")
4403    (set_attr "is_SIBCALL" "yes")]
4406 (define_insn "sibcall_prof"
4407  [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal"))
4408         (match_operand 1 "" ""))
4409   (simple_return)
4410   (use (match_operand 2 "" ""))
4411   (use (reg:SI 8))
4412   (use (reg:SI 9))]
4413   ""
4414   "@
4415    b%!%* %P0;2
4416    j%! %^%S0;2"
4417   [(set_attr "type" "call,call_no_delay_slot")
4418    (set_attr "predicable" "yes")
4419    (set_attr "is_SIBCALL" "yes")]
4422 (define_insn "sibcall_value_prof"
4423  [(set (match_operand 0 "dest_reg_operand" "")
4424        (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal"))
4425              (match_operand 2 "" "")))
4426   (simple_return)
4427   (use (match_operand 3 "" ""))
4428   (use (reg:SI 8))
4429   (use (reg:SI 9))]
4430   ""
4431   "@
4432    b%!%* %P1;1
4433    j%! %^%S1;1"
4434   [(set_attr "type" "call,call_no_delay_slot")
4435    (set_attr "predicable" "yes")
4436    (set_attr "is_SIBCALL" "yes")]
4439 (define_expand "prologue"
4440   [(pc)]
4441   ""
4443   arc_expand_prologue ();
4444   DONE;
4447 (define_expand "epilogue"
4448   [(pc)]
4449   ""
4451   arc_expand_epilogue (0);
4452   DONE;
4455 (define_expand "sibcall_epilogue"
4456   [(pc)]
4457   ""
4459   arc_expand_epilogue (1);
4460   DONE;
4463 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4464 ; in the prologue / epilogue expanders how many times blink is set.
4465 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4466 ; any explicit use of blink will cause it to be saved; hence we cannot
4467 ; represent the blink use in return / sibcall instructions themselves, and
4468 ; instead have to show it in EPILOGUE_USES and must explicitly
4469 ; forbid instructions that change blink in the return / sibcall delay slot.
4470 (define_insn "simple_return"
4471   [(simple_return)]
4472   "reload_completed"
4474   rtx reg
4475     = gen_rtx_REG (Pmode,
4476                    arc_return_address_regs[arc_compute_function_type (cfun)]);
4478   if (TARGET_PAD_RETURN)
4479     arc_pad_return ();
4480   output_asm_insn (\"j%!%* [%0]%&\", &reg);
4481   return \"\";
4483   [(set_attr "type" "return")
4484    ; predicable won't help here since the canonical rtl looks different
4485    ; for branches.
4486    (set_attr "cond" "canuse")
4487    (set (attr "iscompact")
4488         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4489                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4490                (const_string "maybe")]
4491               (const_string "false")))
4492    (set (attr "length")
4493         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4494                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4495                (const_int 4)]
4496               (const_int 2)))])
4498 (define_insn "p_return_i"
4499   [(set (pc)
4500         (if_then_else (match_operator 0 "proper_comparison_operator"
4501                                       [(reg CC_REG) (const_int 0)])
4502                       (simple_return) (pc)))]
4503   "reload_completed"
4505   rtx xop[2];
4506   xop[0] = operands[0];
4507   xop[1]
4508     = gen_rtx_REG (Pmode,
4509                    arc_return_address_regs[arc_compute_function_type (cfun)]);
4511   if (TARGET_PAD_RETURN)
4512     arc_pad_return ();
4513   output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4514   /* record the condition in case there is a delay insn.  */
4515   arc_ccfsm_record_condition (xop[0], false, insn, 0);
4516   return \"\";
4518   [(set_attr "type" "return")
4519    (set_attr "cond" "use")
4520    (set (attr "iscompact")
4521         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4522                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4523                (const_string "maybe")]
4524               (const_string "false")))
4525    (set (attr "length")
4526         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4527                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4528                (const_int 4)
4529                (not (match_operand 0 "equality_comparison_operator" ""))
4530                (const_int 4)
4531                (eq_attr "delay_slot_filled" "yes")
4532                (const_int 4)]
4533               (const_int 2)))])
4535 (define_insn_and_split "eh_return"
4536   [(eh_return)
4537    (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4538    (clobber (match_scratch:SI 1  "=X,r"))
4539    (clobber (match_scratch:SI 2 "=&r,r"))]
4540   ""
4541   "#"
4542   "reload_completed"
4543   [(set (match_dup 2) (match_dup 0))]
4545   int offs = arc_return_slot_offset ();
4547   if (offs < 0)
4548     operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4549   else
4550     {
4551       if (!register_operand (operands[0], Pmode)
4552           && !satisfies_constraint_C32 (operands[0]))
4553         {
4554           emit_move_insn (operands[1], operands[0]);
4555           operands[0] = operands[1];
4556         }
4557       rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4558       if (!strict_memory_address_p (Pmode, addr))
4559         {
4560           emit_move_insn (operands[2], addr);
4561           addr = operands[2];
4562         }
4563       operands[2] = gen_frame_mem (Pmode, addr);
4564     }
4566   [(set_attr "length" "12")])
4568 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4569 ;; non-constant predicate.
4570 (define_expand "return"
4571   [(return)]
4572   "optimize < 0")
4574  ;; Comment in final.c (insn_current_reference_address) says
4575  ;; forward branch addresses are calculated from the next insn after branch
4576  ;; and for backward branches, it is calculated from the branch insn start.
4577  ;; The shortening logic here is tuned to accomodate this behaviour
4578 ;; ??? This should be grokked by the ccfsm machinery.
4579 (define_insn "cbranchsi4_scratch"
4580   [(set (pc)
4581         (if_then_else (match_operator 0 "proper_comparison_operator"
4582                         [(match_operand:SI 1 "register_operand" "c,c, c")
4583                          (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4584                       (label_ref (match_operand 3 "" ""))
4585                       (pc)))
4586    (clobber (match_operand 4 "cc_register" ""))]
4587    "(reload_completed
4588      || (TARGET_EARLY_CBRANCHSI
4589          && brcc_nolimm_operator (operands[0], VOIDmode)))
4590     && !CROSSING_JUMP_P (insn)"
4591    "*
4592      switch (get_attr_length (insn))
4593      {
4594        case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4595        case 4: return \"br%d0%* %1, %B2, %^%l3\";
4596        case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4597                  return \"br%d0%* %1, %B2, %^%l3\";
4598        case 6: case 10:
4599        case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\";
4600        default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4601      }
4602    "
4603   [(set_attr "cond" "clob, clob, clob")
4604    (set (attr "type")
4605         (if_then_else
4606           (match_test "valid_brcc_with_delay_p (operands)")
4607           (const_string "brcc")
4608           (const_string "brcc_no_delay_slot")))
4609    ; For forward branches, we need to account not only for the distance to
4610    ; the target, but also the difference between pcl and pc, the instruction
4611    ; length, and any delay insn, if present.
4612    (set
4613      (attr "length")
4614      (cond ; the outer cond does a test independent of branch shortening.
4615        [(match_operand 0 "brcc_nolimm_operator" "")
4616         (cond
4617           [(and (match_operand:CC_Z 4 "cc_register")
4618                 (eq_attr "delay_slot_filled" "no")
4619                 (ge (minus (match_dup 3) (pc)) (const_int -128))
4620                 (le (minus (match_dup 3) (pc))
4621                     (minus (const_int 122)
4622                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4623            (const_int 2)
4624            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4625                 (le (minus (match_dup 3) (pc))
4626                     (minus (const_int 244)
4627                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4628            (const_int 4)
4629            (match_operand:SI 1 "compact_register_operand" "")
4630            (const_int 6)]
4631           (const_int 8))]
4632          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
4633                      (le (minus (match_dup 3) (pc)) (const_int 244)))
4634                 (const_int 8)
4635                 (match_operand:SI 1 "compact_register_operand" "")
4636                 (const_int 10)]
4637                (const_int 12))))
4638    (set (attr "iscompact")
4639         (if_then_else (match_test "get_attr_length (insn) & 2")
4640                       (const_string "true") (const_string "false")))])
4642 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
4643 (define_insn "*bbit"
4644   [(set (pc)
4645         (if_then_else
4646           (match_operator 3 "equality_comparison_operator"
4647             [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
4648                               (const_int 1)
4649                               (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
4650              (const_int 0)])
4651           (label_ref (match_operand 0 "" ""))
4652           (pc)))
4653    (clobber (reg:CC_ZN CC_REG))]
4654   "!CROSSING_JUMP_P (insn)"
4656   switch (get_attr_length (insn))
4657     {
4658       case 4: return (GET_CODE (operands[3]) == EQ
4659                       ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
4660       case 6:
4661       case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
4662       default: gcc_unreachable ();
4663     }
4665   [(set_attr "type" "brcc")
4666    (set_attr "cond" "clob")
4667    (set (attr "length")
4668         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
4669                     (le (minus (match_dup 0) (pc))
4670                     (minus (const_int 248)
4671                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4672                (const_int 4)
4673                (eq (symbol_ref "which_alternative") (const_int 0))
4674                (const_int 6)]
4675               (const_int 8)))
4676    (set (attr "iscompact")
4677         (if_then_else (match_test "get_attr_length (insn) == 6")
4678                       (const_string "true") (const_string "false")))])
4680 ; ??? When testing a bit from a DImode register, combine creates a
4681 ; zero_extract in DImode.  This goes via an AND with a DImode constant,
4682 ; so can only be observed on 64 bit hosts.
4683 (define_insn_and_split "*bbit_di"
4684   [(set (pc)
4685         (if_then_else
4686           (match_operator 3 "equality_comparison_operator"
4687             [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
4688                               (const_int 1)
4689                               (match_operand 2 "immediate_operand" "L,L"))
4690              (const_int 0)])
4691           (label_ref (match_operand 0 "" ""))
4692           (pc)))
4693    (clobber (reg:CC_ZN CC_REG))]
4694   "!CROSSING_JUMP_P (insn)"
4695   "#"
4696   ""
4697   [(parallel
4698      [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
4699       (clobber (reg:CC_ZN CC_REG))])]
4701   rtx xtr;
4703   xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
4704   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
4705                                 xtr, const0_rtx);
4708 ; operand 0 is the loop count pseudo register
4709 ; operand 1 is the loop end pattern
4710 (define_expand "doloop_begin"
4711   [(use (match_operand 0 "register_operand" ""))
4712    (use (match_operand 1 "" ""))]
4713   ""
4715   /* Using the INSN_UID of the loop end pattern to identify it causes
4716      trouble with -fcompare-debug, so allocate a debug-independent
4717      id instead.  We use negative numbers so that we can use the same
4718      slot in doloop_end_i where we later store a CODE_LABEL_NUMBER, and
4719      still be able to tell what kind of number this is.  */
4720   static HOST_WIDE_INT loop_end_id = 0;
4722   rtx id = GEN_INT (--loop_end_id);
4723   XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
4724   emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
4725                                  const0_rtx, const0_rtx));
4726   DONE;
4729 ; ??? can't describe the insn properly as then the optimizers try to
4730 ; hoist the SETs.
4731 ;(define_insn "doloop_begin_i"
4732 ;  [(set (reg:SI LP_START) (pc))
4733 ;   (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_LP))
4734 ;   (use (match_operand 0 "const_int_operand" "n"))]
4735 ;  ""
4736 ;  "lp .L__GCC__LP%0"
4739 ; The operands of doloop_end_i are also read / written by arc_reorg with
4740 ; XVECEXP (PATTERN (lp, 0, N), so if you want to change the pattern, you
4741 ; might have to adjust arc_reorg.
4742 ; operands 0 / 2 are supplied by the expander, 1, 3 and 4 are filled in
4743 ; by arc_reorg.  arc_reorg might also alter operand 0.
4745 ; N in XVECEXP PATTERN (lp, 0 N)
4746 ;  V              rtl                 purpose
4747 ;  0           unspec UNSPEC_LP     identify pattern
4748 ;  1           clobber LP_START     show LP_START is set
4749 ;  2           clobber LP_END       show LP_END is set
4750 ;  3           use operand0         loop count pseudo register
4751 ;  4           use operand1         before arc_reorg: -id
4752 ;                                   after : CODE_LABEL_NUMBER of loop top label
4753 ;  5           use operand2         INSN_UID of loop end insn
4754 ;  6           use operand3         loop setup not at start (1 above, 2 below)
4755 ;  7           use operand4         LABEL_REF of top label, if not
4756 ;                                   immediately following
4757 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
4758 ; instruction that was not at the start of the loop.
4759 ; There is no point is reloading this insn - then lp_count would still not
4760 ; be available for the loop end.
4761 (define_insn "doloop_begin_i"
4762   [(unspec:SI [(pc)] UNSPEC_LP)
4763    (clobber (reg:SI LP_START))
4764    (clobber (reg:SI LP_END))
4765    (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
4766    (use (match_operand 1 "const_int_operand" "n,n,C_0"))
4767    (use (match_operand 2 "const_int_operand" "n,n,X"))
4768    (use (match_operand 3 "const_int_operand" "C_0,n,X"))
4769    (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
4770   ""
4772   rtx_insn *scan;
4773   int len, size = 0;
4774   int n_insns = 0;
4775   rtx loop_start = operands[4];
4777   if (CONST_INT_P (loop_start))
4778     loop_start = NULL_RTX;
4779   /* Size implications of the alignment will be taken care of by the
4780      alignment inserted at the loop start.  */
4781   if (LOOP_ALIGN (0) && INTVAL (operands[1]))
4782     {
4783       asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
4784       arc_clear_unalign ();
4785     }
4786   if (!INTVAL (operands[1]))
4787     return "; LITTLE LOST LOOP";
4788   if (loop_start && flag_pic)
4789     {
4790       /* ??? Can do better for when a scratch register
4791          is known.  But that would require extra testing.  */
4792       return "push_s r0\;add r0,pcl,%4-(.&-4)\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-(.&-4)\;sr r0,[3]; LP_END\;pop_s r0";
4793     }
4794   /* Check if the loop end is in range to be set by the lp instruction.  */
4795   size = INTVAL (operands[3]) < 2 ? 0 : 2048;
4796   for (scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
4797     {
4798       if (!INSN_P (scan))
4799         continue;
4800       if (recog_memoized (scan) == CODE_FOR_doloop_end_i
4801           && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
4802               == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
4803         break;
4804       len = get_attr_length (scan);
4805       size += len;
4806     }
4807   /* Try to verify that there are at least three instruction fetches
4808      between the loop setup and the first encounter of the loop end.  */
4809   for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
4810     {
4811       if (!INSN_P (scan))
4812         continue;
4813       if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (scan)))
4814         scan = seq->insn (0);
4815       if (JUMP_P (scan))
4816         {
4817           if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
4818             {
4819               n_insns += 2;
4820               if (simplejump_p (scan))
4821                 {
4822                   scan = as_a <rtx_insn *> (XEXP (SET_SRC (PATTERN (scan)), 0));
4823                   continue;
4824                 }
4825               if (JUMP_LABEL (scan)
4826                   /* JUMP_LABEL might be simple_return instead if an insn.  */
4827                   && (!INSN_P (JUMP_LABEL (scan))
4828                       || (!next_active_insn (JUMP_LABEL (scan))
4829                           || (recog_memoized (next_active_insn (JUMP_LABEL (scan)))
4830                               != CODE_FOR_doloop_begin_i)))
4831                   && (!next_active_insn (NEXT_INSN (PREV_INSN (scan)))
4832                       || (recog_memoized
4833                            (next_active_insn (NEXT_INSN (PREV_INSN (scan))))
4834                           != CODE_FOR_doloop_begin_i)))
4835                 n_insns++;
4836             }
4837           break;
4838         }
4839       len = get_attr_length (scan);
4840       /* Size estimation of asms assumes that each line which is nonempty
4841          codes an insn, and that each has a long immediate.  For minimum insn
4842          count, assume merely that a nonempty asm has at least one insn.  */
4843       if (GET_CODE (PATTERN (scan)) == ASM_INPUT
4844           || asm_noperands (PATTERN (scan)) >= 0)
4845         n_insns += (len != 0);
4846       else
4847         n_insns += (len > 4 ? 2 : (len ? 1 : 0));
4848     }
4849   if (LOOP_ALIGN (0))
4850     {
4851       asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
4852       arc_clear_unalign ();
4853     }
4854   gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
4855   if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
4856     {
4857       if (flag_pic)
4858         {
4859           /* ??? Can do better for when a scratch register
4860              is known.  But that would require extra testing.  */
4861           arc_clear_unalign ();
4862           return ".p2align 2\;push_s r0\;add r0,pcl,24\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-.+2\;sr r0,[3]; LP_END\;pop_s r0";
4863         }
4864       output_asm_insn ((size < 2048
4865                         ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
4866                        operands);
4867       output_asm_insn (loop_start
4868                        ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
4869                        operands);
4870       if (TARGET_ARC600 && n_insns < 1)
4871         output_asm_insn ("nop", operands);
4872       return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
4873     }
4874   else if (TARGET_ARC600 && n_insns < 3)
4875     {
4876       /* At least four instructions are needed between the setting of LP_COUNT
4877          and the loop end - but the lp instruction qualifies as one.  */
4878       rtx_insn *prev = prev_nonnote_insn (insn);
4880       if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
4881         output_asm_insn ("nop", operands);
4882     }
4883   return "lp .L__GCC__LP%1";
4885   [(set_attr "type" "loop_setup")
4886    (set_attr_alternative "length"
4887 ;     FIXME: length is usually 4, but we need branch shortening
4888 ;     to get this right.
4889 ;     [(if_then_else (match_test "TARGET_ARC600") (const_int 16) (const_int 4))
4890      [(if_then_else (match_test "flag_pic") (const_int 24) (const_int 16))
4891       (if_then_else (match_test "flag_pic") (const_int 28) (const_int 16))
4892       (const_int 0)])]
4893   ;; ??? we should really branch shorten this insn, but then we'd
4894   ;; need a proper label first.  N.B. the end label can not only go out
4895   ;; of range when it is far away, but also when it precedes the loop -
4896   ;; which, unfortunately, it sometimes does, when the loop "optimizer"
4897   ;; messes things up.
4900 ; operand 0 is the loop count pseudo register
4901 ; operand 1 is the label to jump to at the top of the loop
4902 ; Use this for the ARC600 and ARC700.  For ARCtangent-A5, this is unsafe
4903 ; without further checking for nearby branches etc., and without proper
4904 ; annotation of shift patterns that clobber lp_count
4905 ; ??? ARC600 might want to check if the loop has few iteration and only a
4906 ; single insn - loop setup is expensive then.
4907 (define_expand "doloop_end"
4908   [(use (match_operand 0 "register_operand" ""))
4909    (use (label_ref (match_operand 1 "" "")))]
4910   "TARGET_ARC600 || TARGET_ARC700"
4912   /* We could do smaller bivs with biv widening, and wider bivs by having
4913      a high-word counter in an outer loop - but punt on this for now.  */
4914   if (GET_MODE (operands[0]) != SImode)
4915     FAIL;
4916   emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
4917   DONE;
4920 (define_insn_and_split "doloop_end_i"
4921   [(set (pc)
4922         (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
4923                            (const_int 1))
4924                       (label_ref (match_operand 1 "" ""))
4925                       (pc)))
4926    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
4927    (use (reg:SI LP_START))
4928    (use (reg:SI LP_END))
4929    (use (match_operand 2 "const_int_operand" "n,???Cn0,???X"))
4930    (clobber (match_scratch:SI 3 "=X,X,&????r"))]
4931   ""
4932   "*
4934   rtx_insn *prev = prev_nonnote_insn (insn);
4936   /* If there is an immediately preceding label, we must output a nop,
4937      lest a branch to that label will fall out of the loop.
4938      ??? We could try to avoid this by claiming to have a delay slot if there
4939      is a preceding label, and outputting the delay slot insn instead, if
4940      present.
4941      Or we could have some optimization that changes the source edge to update
4942      the loop count and jump to the loop start instead.  */
4943   /* For ARC600, we must also prevent jumps inside the loop and jumps where
4944      the loop counter value is live at the target from being directly at the
4945      loop end.  Being sure that the loop counter is dead at the target is
4946      too much hair - we can't rely on data flow information at this point -
4947      so insert a nop for all branches.
4948      The ARC600 also can't read the loop counter in the last insn of a loop.  */
4949   if (LABEL_P (prev))
4950     output_asm_insn (\"nop%?\", operands);
4951   return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
4953   "&& memory_operand (operands[0], SImode)"
4954   [(pc)]
4956   emit_move_insn (operands[3], operands[0]);
4957   emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
4958   DONE;
4960   [(set_attr "type" "loop_end")
4961    (set (attr "length")
4962         (if_then_else (match_test "LABEL_P (prev_nonnote_insn (insn))")
4963                       (const_int 4) (const_int 0)))]
4966 ; This pattern is generated by arc_reorg when there is no recognizable
4967 ; loop start.
4968 (define_insn "*doloop_fallback"
4969   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
4970                                 (const_int 1))
4971                            (label_ref (match_operand 1 "" ""))
4972                            (pc)))
4973    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
4974    ; avoid fooling the loop optimizer into assuming this is a special insn.
4975   "reload_completed"
4976   "*return get_attr_length (insn) == 8
4977    ? \"brne.d %0,1,%1\;sub %0,%0,1\"
4978    : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
4979   [(set (attr "length")
4980         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
4981                            (le (minus (match_dup 1) (pc)) (const_int 244)))
4982                       (const_int 8) (const_int 12)))
4983    (set_attr "type" "brcc_no_delay_slot")
4984    (set_attr "cond" "nocond")]
4987 ; reload can't make output reloads for jump insns, so we have to do this by hand.
4988 (define_insn "doloop_fallback_m"
4989   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
4990                                 (const_int 1))
4991                            (label_ref (match_operand 1 "" ""))
4992                            (pc)))
4993    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
4994    (set (match_operand:SI 2 "memory_operand" "=m")
4995         (plus:SI (match_dup 0) (const_int -1)))]
4996    ; avoid fooling the loop optimizer into assuming this is a special insn.
4997   "reload_completed"
4998   "*return get_attr_length (insn) == 12
4999    ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5000    : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5001   [(set (attr "length")
5002         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5003                            (le (minus (match_dup 1) (pc)) (const_int 244)))
5004                       (const_int 12) (const_int 16)))
5005    (set_attr "type" "brcc_no_delay_slot")
5006    (set_attr "cond" "nocond")]
5009 (define_expand "movmemsi"
5010   [(match_operand:BLK 0 "" "")
5011    (match_operand:BLK 1 "" "")
5012    (match_operand:SI 2 "nonmemory_operand" "")
5013    (match_operand 3 "immediate_operand" "")]
5014   ""
5015   "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5017 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5018 ;; to the point that we can generate cmove instructions.
5019 (define_expand "cbranch<mode>4"
5020   [(set (reg:CC CC_REG)
5021         (compare:CC (match_operand:SDF 1 "register_operand" "")
5022                     (match_operand:SDF 2 "register_operand" "")))
5023    (set (pc)
5024         (if_then_else
5025               (match_operator 0 "comparison_operator" [(reg CC_REG)
5026                                                        (const_int 0)])
5027               (label_ref (match_operand 3 "" ""))
5028               (pc)))]
5030   "TARGET_OPTFPE"
5032   gcc_assert (XEXP (operands[0], 0) == operands[1]);
5033   gcc_assert (XEXP (operands[0], 1) == operands[2]);
5034   operands[0] = gen_compare_reg (operands[0], VOIDmode);
5035   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5036   DONE;
5039 (define_expand "cmp_float"
5040   [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5041               (clobber (reg:SI RETURN_ADDR_REGNUM))
5042               (clobber (reg:SI R12_REG))])]
5043   ""
5044   "")
5046 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5047 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5048                        (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5050 (define_insn "*cmpsf_<cmp>"
5051   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5052    (clobber (reg:SI RETURN_ADDR_REGNUM))
5053    (clobber (reg:SI R12_REG))]
5054   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5055    && SFUNC_CHECK_PREDICABLE"
5056   "*return arc_output_libcall (\"__<cmp>sf2\");"
5057   [(set_attr "is_sfunc" "yes")
5058    (set_attr "predicable" "yes")])
5060 ;; N.B. for "*cmpdf_ord":
5061 ;; double precision fpx sets bit 31 for NaNs.  We need bit 51 set
5062 ;; for the floating point emulation to recognize the NaN.
5063 (define_insn "*cmpdf_<cmp>"
5064   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5065    (clobber (reg:SI RETURN_ADDR_REGNUM))
5066    (clobber (reg:SI R12_REG))]
5067   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5068    && SFUNC_CHECK_PREDICABLE"
5069   "*return arc_output_libcall (\"__<cmp>df2\");"
5070   [(set_attr "is_sfunc" "yes")
5071    (set_attr "predicable" "yes")])
5073 (define_insn "abssf2"
5074   [(set (match_operand:SF 0 "dest_reg_operand"    "=Rcq#q,Rcw,w")
5075         (abs:SF (match_operand:SF 1 "register_operand" "0,  0,c")))]
5076   ""
5077   "bclr%? %0,%1,31%&"
5078   [(set_attr "type" "unary")
5079    (set_attr "iscompact" "maybe,false,false")
5080    (set_attr "length" "2,4,4")
5081    (set_attr "predicable" "no,yes,no")])
5083 (define_insn "negsf2"
5084   [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5085         (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5086   ""
5087   "bxor%? %0,%1,31"
5088   [(set_attr "type" "unary")
5089    (set_attr "predicable" "yes,no")])
5091 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5092 (define_insn "*millicode_thunk_st"
5093   [(match_parallel 0 "millicode_store_operation"
5094      [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5095   ""
5097   output_asm_insn ("bl%* __st_r13_to_%0",
5098                    &SET_SRC (XVECEXP (operands[0], 0,
5099                                       XVECLEN (operands[0], 0) - 2)));
5100   return "";
5102   [(set_attr "type" "call")])
5104 (define_insn "*millicode_thunk_ld"
5105   [(match_parallel 0 "millicode_load_clob_operation"
5106      [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5107   ""
5109   output_asm_insn ("bl%* __ld_r13_to_%0",
5110                    &SET_DEST (XVECEXP (operands[0], 0,
5111                                        XVECLEN (operands[0], 0) - 2)));
5112   return "";
5114   [(set_attr "type" "call")])
5116 ; the sibthunk restores blink, so we use the return rtx.
5117 (define_insn "*millicode_sibthunk_ld"
5118   [(match_parallel 0 "millicode_load_operation"
5119      [(return)
5120       (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5121       (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5122   ""
5124   output_asm_insn ("b%* __ld_r13_to_%0_ret",
5125                    &SET_DEST (XVECEXP (operands[0], 0,
5126                                        XVECLEN (operands[0], 0) - 1)));
5127   return "";
5129   [(set_attr "type" "call")
5130    (set_attr "is_SIBCALL" "yes")])
5132 ;; If hardware floating point is available, don't define a negdf pattern;
5133 ;; it would be something like:
5134 ;;(define_insn "negdf2"
5135 ;;  [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5136 ;;      (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5137 ;;   (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5138 ;;  ""
5139 ;;  "@
5140 ;;   bxor%? %H0,%H1,31
5141 ;;   bxor %H0,%H1,31 ` mov %L0,%L1
5142 ;;   drsubh%F0%F1 0,0,0
5143 ;;   drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5144 ;;  [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5145 ;;   (set_attr "iscompact" "false,false,false,false")
5146 ;;   (set_attr "length" "4,4,8,12")
5147 ;;   (set_attr "cond" "canuse,nocond,nocond,nocond")])
5148 ;; and this suffers from always requiring a long immediate when using
5149 ;; the floating point hardware.
5150 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5151 ;; constant zero efficiently into a register when we want to do the
5152 ;; computation using the floating point hardware.  There should be a special
5153 ;; subdf alternative that matches a zero operand 1, which then can allow
5154 ;; to use bxor to flip the high bit of an integer register.
5155 ;; ??? we actually can't use the floating point hardware for neg, because
5156 ;; this would not work right for -0.  OTOH optabs.c has already code
5157 ;; to synthesyze negate by flipping the sign bit.
5160 ;; include the arc-FPX instructions
5161 (include "fpx.md")
5163 (include "simdext.md")