Always pass explicit location to fatal_error.
[official-gcc.git] / gcc / config / arc / arc.md
blobd66441f326b150dbdd3c028e1a72f9a413ac30f3
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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, operands[0],
4088                     plus_constant (SImode, operands[0], 1))));
4089   DONE;
4092 (define_expand "ctzsi2"
4093   [(set (match_operand:SI 0 "register_operand" "")
4094         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
4095   "TARGET_NORM"
4097   rtx temp = operands[0];
4099   if (reg_overlap_mentioned_p (temp, operands[1])
4100       || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4101           && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4102                                  REGNO (temp))))
4103     temp = gen_reg_rtx (SImode);
4104   emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4105   emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4106   emit_insn (gen_clrsbsi2 (temp, temp));
4107   emit_insn
4108     (gen_rtx_COND_EXEC
4109       (VOIDmode,
4110        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4111        gen_rtx_SET (VOIDmode, operands[0], GEN_INT (32))));
4112   emit_insn
4113     (gen_rtx_COND_EXEC
4114       (VOIDmode,
4115        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4116        gen_rtx_SET (VOIDmode, operands[0],
4117                     gen_rtx_MINUS (SImode, GEN_INT (31), temp))));
4118   DONE;
4122 (define_insn "swap"
4123   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
4124         (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4125                             UNSPEC_SWAP))]
4126   "TARGET_SWAP"
4127   "@
4128    swap \t%0, %1
4129    swap \t%0, %S1
4130    swap \t%0, %1"
4131   [(set_attr "length" "4,8,4")
4132    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4134 ;; FIXME: an intrinsic for multiply is daft.  Can we remove this?
4135 (define_insn "mul64"
4136   [(unspec [(match_operand:SI 0 "general_operand" "%q,r,r,r")
4137                      (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
4138                    UNSPEC_MUL64)]
4139   "TARGET_MUL64_SET"
4140   "@
4141    mul64%? \t0, %0, %1%&
4142    mul64%? \t0, %0, %1
4143    mul64 \t0, %0, %1
4144    mul64%? \t0, %0, %S1"
4145   [(set_attr "length" "2,4,4,8")
4146   (set_attr "iscompact" "true,false,false,false")
4147   (set_attr "type" "binary,binary,binary,binary")
4148   (set_attr "cond" "canuse,canuse, nocond, canuse")])
4150 (define_insn "mulu64"
4151   [(unspec [(match_operand:SI 0 "general_operand" "%r,r,r,r")
4152                      (match_operand:SI 1 "general_operand" "rL,I,r,Cal")]
4153                    UNSPEC_MULU64)]
4154   "TARGET_MUL64_SET"
4155   "@
4156    mulu64%? \t0, %0, %1
4157    mulu64 \t0, %0, %1
4158    mulu64 \t0, %0, %1
4159    mulu64%? \t0, %0, %S1"
4160   [(set_attr "length" "4,4,4,8")
4161    (set_attr "type" "binary,binary,binary,binary")
4162    (set_attr "cond" "canuse,nocond,nocond,canuse")])
4164 (define_insn "divaw"
4165   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4166                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4167                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4168                                            UNSPEC_DIVAW))]
4169   "TARGET_ARC700 || TARGET_EA_SET"
4170   "@
4171    divaw \t%0, %1, %2
4172    divaw \t%0, %S1, %2
4173    divaw \t%0, %1, %S2"
4174   [(set_attr "length" "4,8,8")
4175    (set_attr "type" "divaw,divaw,divaw")])
4177 (define_insn "flag"
4178   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4179                    VUNSPEC_FLAG)]
4180   ""
4181   "@
4182     flag%? %0
4183     flag %0
4184     flag%? %S0"
4185   [(set_attr "length" "4,4,8")
4186    (set_attr "type" "misc,misc,misc")
4187    (set_attr "predicable" "yes,no,yes")
4188    (set_attr "cond" "clob,clob,clob")])
4190 (define_insn "brk"
4191   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4192                    VUNSPEC_BRK)]
4193   ""
4194   "brk"
4195   [(set_attr "length" "4")
4196   (set_attr "type" "misc")])
4198 (define_insn "rtie"
4199   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4200                    VUNSPEC_RTIE)]
4201   ""
4202   "rtie"
4203   [(set_attr "length" "4")
4204   (set_attr "type" "misc")
4205   (set_attr "cond" "clob")])
4207 (define_insn "sync"
4208   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4209                    VUNSPEC_SYNC)]
4210   ""
4211   "sync"
4212   [(set_attr "length" "4")
4213   (set_attr "type" "misc")])
4215 (define_insn "swi"
4216   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4217                    VUNSPEC_SWI)]
4218   ""
4219   "*
4221     if(TARGET_ARC700)
4222         return \"trap0\";
4223     else
4224         return \"swi\";
4226   [(set_attr "length" "4")
4227   (set_attr "type" "misc")])
4230 (define_insn "sleep"
4231   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4232                    VUNSPEC_SLEEP)]
4233   "check_if_valid_sleep_operand(operands,0)"
4234   "sleep %0"
4235   [(set_attr "length" "4")
4236   (set_attr "type" "misc")])
4238 (define_insn "core_read"
4239   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4240         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4241                             VUNSPEC_CORE_READ))]
4242   ""
4243   "*
4244     if (check_if_valid_regno_const (operands, 1))
4245       return \"mov \t%0, r%1\";
4246     return \"mov \t%0, r%1\";
4247   "
4248   [(set_attr "length" "4")
4249    (set_attr "type" "unary")])
4251 (define_insn "core_write"
4252   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4253                      (match_operand:SI 1 "general_operand" "Hn,!r")]
4254                    VUNSPEC_CORE_WRITE)]
4255   ""
4256   "*
4257     if (check_if_valid_regno_const (operands, 1))
4258       return \"mov \tr%1, %0\";
4259     return \"mov \tr%1, %0\";
4260   "
4261   [(set_attr "length" "4")
4262    (set_attr "type" "unary")])
4264 (define_insn "lr"
4265   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
4266         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4267                             VUNSPEC_LR))]
4268   ""
4269   "lr\t%0, [%1]"
4270   [(set_attr "length" "4,8,4,8")
4271    (set_attr "type" "lr,lr,lr,lr")])
4273 (define_insn "sr"
4274   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4275                      (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4276                    VUNSPEC_SR)]
4277   ""
4278   "sr\t%S0, [%1]"
4279   [(set_attr "length" "8,4,8,4")
4280    (set_attr "type" "sr,sr,sr,sr")])
4282 (define_insn "trap_s"
4283   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4284                    VUNSPEC_TRAP_S)]
4285   "TARGET_ARC700"
4287   if (which_alternative == 0)
4288     {
4289       arc_toggle_unalign ();
4290       return \"trap_s %0\";
4291     }
4293   /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4294      because *.md files do not get scanned by exgettext.  */
4295   fatal_error (input_location,
4296                \"operand to trap_s should be an unsigned 6-bit value\");
4298   [(set_attr "length" "2")
4299   (set_attr "type" "misc")])
4301 (define_insn "unimp_s"
4302   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4303                    VUNSPEC_UNIMP_S)]
4304   "TARGET_ARC700"
4305   "unimp_s"
4306   [(set_attr "length" "4")
4307   (set_attr "type" "misc")])
4309 ;; End of instructions generated through builtins
4311 ; Since the demise of REG_N_SETS as reliable data readily available to the
4312 ; target, it is no longer possible to find out
4313 ; in the prologue / epilogue expanders how many times blink is set.
4314 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4315 ; any explicit use of blink will cause it to be saved; hence we cannot
4316 ; represent the blink use in return / sibcall instructions themselves, and
4317 ; instead have to show it in EPILOGUE_USES and must explicitly
4318 ; forbid instructions that change blink in the return / sibcall delay slot.
4319 (define_expand "sibcall"
4320   [(parallel [(call (match_operand 0 "memory_operand" "")
4321                     (match_operand 1 "general_operand" ""))
4322               (simple_return)
4323               (use (match_operand 2 "" ""))])]
4324   ""
4325   "
4326   {
4327     rtx callee = XEXP (operands[0], 0);
4329     if (operands[2] == NULL_RTX)
4330       operands[2] = const0_rtx;
4331     if (crtl->profile && arc_profile_call (callee))
4332       {
4333         emit_insn (gen_sibcall_prof
4334                     (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4335                      operands[1], operands[2]));
4336         DONE;
4337       }
4338     if (GET_CODE (callee) != REG
4339         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4340       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4341   }"
4344 (define_expand "sibcall_value"
4345   [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4346                    (call (match_operand 1 "memory_operand" "")
4347                          (match_operand 2 "general_operand" "")))
4348               (simple_return)
4349               (use (match_operand 3 "" ""))])]
4350   ""
4351   "
4352   {
4353     rtx callee = XEXP (operands[1], 0);
4355     if (operands[3] == NULL_RTX)
4356       operands[3] = const0_rtx;
4357     if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
4358       {
4359         emit_insn (gen_sibcall_value_prof
4360                     (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4361                      operands[2], operands[3]));
4362         DONE;
4363       }
4364     if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4365       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4366   }"
4369 (define_insn "*sibcall_insn"
4370  [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4371                  "Cbp,Cbr,Rs5,Rsc,Cal"))
4372         (match_operand 1 "" ""))
4373   (simple_return)
4374   (use (match_operand 2 "" ""))]
4375   ""
4376   "@
4377    b%!%* %P0
4378    b%!%* %P0
4379    j%!%* [%0]%&
4380    j%!%* [%0]
4381    j%! %P0"
4382   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4383    (set_attr "predicable" "yes,no,no,yes,yes")
4384    (set_attr "iscompact" "false,false,maybe,false,false")
4385    (set_attr "is_SIBCALL" "yes")]
4388 (define_insn "*sibcall_value_insn"
4389  [(set (match_operand 0 "dest_reg_operand" "")
4390        (call (mem:SI (match_operand:SI 1 "call_address_operand"
4391               "Cbp,Cbr,Rs5,Rsc,Cal"))
4392              (match_operand 2 "" "")))
4393   (simple_return)
4394   (use (match_operand 3 "" ""))]
4395   ""
4396   "@
4397    b%!%* %P1
4398    b%!%* %P1
4399    j%!%* [%1]%&
4400    j%!%* [%1]
4401    j%! %P1"
4402   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4403    (set_attr "predicable" "yes,no,no,yes,yes")
4404    (set_attr "iscompact" "false,false,maybe,false,false")
4405    (set_attr "is_SIBCALL" "yes")]
4408 (define_insn "sibcall_prof"
4409  [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal"))
4410         (match_operand 1 "" ""))
4411   (simple_return)
4412   (use (match_operand 2 "" ""))
4413   (use (reg:SI 8))
4414   (use (reg:SI 9))]
4415   ""
4416   "@
4417    b%!%* %P0;2
4418    j%! %^%S0;2"
4419   [(set_attr "type" "call,call_no_delay_slot")
4420    (set_attr "predicable" "yes")
4421    (set_attr "is_SIBCALL" "yes")]
4424 (define_insn "sibcall_value_prof"
4425  [(set (match_operand 0 "dest_reg_operand" "")
4426        (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal"))
4427              (match_operand 2 "" "")))
4428   (simple_return)
4429   (use (match_operand 3 "" ""))
4430   (use (reg:SI 8))
4431   (use (reg:SI 9))]
4432   ""
4433   "@
4434    b%!%* %P1;1
4435    j%! %^%S1;1"
4436   [(set_attr "type" "call,call_no_delay_slot")
4437    (set_attr "predicable" "yes")
4438    (set_attr "is_SIBCALL" "yes")]
4441 (define_expand "prologue"
4442   [(pc)]
4443   ""
4445   arc_expand_prologue ();
4446   DONE;
4449 (define_expand "epilogue"
4450   [(pc)]
4451   ""
4453   arc_expand_epilogue (0);
4454   DONE;
4457 (define_expand "sibcall_epilogue"
4458   [(pc)]
4459   ""
4461   arc_expand_epilogue (1);
4462   DONE;
4465 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4466 ; in the prologue / epilogue expanders how many times blink is set.
4467 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4468 ; any explicit use of blink will cause it to be saved; hence we cannot
4469 ; represent the blink use in return / sibcall instructions themselves, and
4470 ; instead have to show it in EPILOGUE_USES and must explicitly
4471 ; forbid instructions that change blink in the return / sibcall delay slot.
4472 (define_insn "simple_return"
4473   [(simple_return)]
4474   "reload_completed"
4476   rtx reg
4477     = gen_rtx_REG (Pmode,
4478                    arc_return_address_regs[arc_compute_function_type (cfun)]);
4480   if (TARGET_PAD_RETURN)
4481     arc_pad_return ();
4482   output_asm_insn (\"j%!%* [%0]%&\", &reg);
4483   return \"\";
4485   [(set_attr "type" "return")
4486    ; predicable won't help here since the canonical rtl looks different
4487    ; for branches.
4488    (set_attr "cond" "canuse")
4489    (set (attr "iscompact")
4490         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4491                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4492                (const_string "maybe")]
4493               (const_string "false")))
4494    (set (attr "length")
4495         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4496                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4497                (const_int 4)]
4498               (const_int 2)))])
4500 (define_insn "p_return_i"
4501   [(set (pc)
4502         (if_then_else (match_operator 0 "proper_comparison_operator"
4503                                       [(reg CC_REG) (const_int 0)])
4504                       (simple_return) (pc)))]
4505   "reload_completed"
4507   rtx xop[2];
4508   xop[0] = operands[0];
4509   xop[1]
4510     = gen_rtx_REG (Pmode,
4511                    arc_return_address_regs[arc_compute_function_type (cfun)]);
4513   if (TARGET_PAD_RETURN)
4514     arc_pad_return ();
4515   output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4516   /* record the condition in case there is a delay insn.  */
4517   arc_ccfsm_record_condition (xop[0], false, insn, 0);
4518   return \"\";
4520   [(set_attr "type" "return")
4521    (set_attr "cond" "use")
4522    (set (attr "iscompact")
4523         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4524                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4525                (const_string "maybe")]
4526               (const_string "false")))
4527    (set (attr "length")
4528         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4529                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4530                (const_int 4)
4531                (not (match_operand 0 "equality_comparison_operator" ""))
4532                (const_int 4)
4533                (eq_attr "delay_slot_filled" "yes")
4534                (const_int 4)]
4535               (const_int 2)))])
4537 (define_insn_and_split "eh_return"
4538   [(eh_return)
4539    (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4540    (clobber (match_scratch:SI 1  "=X,r"))
4541    (clobber (match_scratch:SI 2 "=&r,r"))]
4542   ""
4543   "#"
4544   "reload_completed"
4545   [(set (match_dup 2) (match_dup 0))]
4547   int offs = arc_return_slot_offset ();
4549   if (offs < 0)
4550     operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4551   else
4552     {
4553       if (!register_operand (operands[0], Pmode)
4554           && !satisfies_constraint_C32 (operands[0]))
4555         {
4556           emit_move_insn (operands[1], operands[0]);
4557           operands[0] = operands[1];
4558         }
4559       rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4560       if (!strict_memory_address_p (Pmode, addr))
4561         {
4562           emit_move_insn (operands[2], addr);
4563           addr = operands[2];
4564         }
4565       operands[2] = gen_frame_mem (Pmode, addr);
4566     }
4568   [(set_attr "length" "12")])
4570 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4571 ;; non-constant predicate.
4572 (define_expand "return"
4573   [(return)]
4574   "optimize < 0")
4576  ;; Comment in final.c (insn_current_reference_address) says
4577  ;; forward branch addresses are calculated from the next insn after branch
4578  ;; and for backward branches, it is calculated from the branch insn start.
4579  ;; The shortening logic here is tuned to accomodate this behaviour
4580 ;; ??? This should be grokked by the ccfsm machinery.
4581 (define_insn "cbranchsi4_scratch"
4582   [(set (pc)
4583         (if_then_else (match_operator 0 "proper_comparison_operator"
4584                         [(match_operand:SI 1 "register_operand" "c,c, c")
4585                          (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4586                       (label_ref (match_operand 3 "" ""))
4587                       (pc)))
4588    (clobber (match_operand 4 "cc_register" ""))]
4589    "(reload_completed
4590      || (TARGET_EARLY_CBRANCHSI
4591          && brcc_nolimm_operator (operands[0], VOIDmode)))
4592     && !CROSSING_JUMP_P (insn)"
4593    "*
4594      switch (get_attr_length (insn))
4595      {
4596        case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4597        case 4: return \"br%d0%* %1, %B2, %^%l3\";
4598        case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4599                  return \"br%d0%* %1, %B2, %^%l3\";
4600        case 6: case 10:
4601        case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\";
4602        default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4603      }
4604    "
4605   [(set_attr "cond" "clob, clob, clob")
4606    (set (attr "type")
4607         (if_then_else
4608           (match_test "valid_brcc_with_delay_p (operands)")
4609           (const_string "brcc")
4610           (const_string "brcc_no_delay_slot")))
4611    ; For forward branches, we need to account not only for the distance to
4612    ; the target, but also the difference between pcl and pc, the instruction
4613    ; length, and any delay insn, if present.
4614    (set
4615      (attr "length")
4616      (cond ; the outer cond does a test independent of branch shortening.
4617        [(match_operand 0 "brcc_nolimm_operator" "")
4618         (cond
4619           [(and (match_operand:CC_Z 4 "cc_register")
4620                 (eq_attr "delay_slot_filled" "no")
4621                 (ge (minus (match_dup 3) (pc)) (const_int -128))
4622                 (le (minus (match_dup 3) (pc))
4623                     (minus (const_int 122)
4624                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4625            (const_int 2)
4626            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4627                 (le (minus (match_dup 3) (pc))
4628                     (minus (const_int 244)
4629                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4630            (const_int 4)
4631            (match_operand:SI 1 "compact_register_operand" "")
4632            (const_int 6)]
4633           (const_int 8))]
4634          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
4635                      (le (minus (match_dup 3) (pc)) (const_int 244)))
4636                 (const_int 8)
4637                 (match_operand:SI 1 "compact_register_operand" "")
4638                 (const_int 10)]
4639                (const_int 12))))
4640    (set (attr "iscompact")
4641         (if_then_else (match_test "get_attr_length (insn) & 2")
4642                       (const_string "true") (const_string "false")))])
4644 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
4645 (define_insn "*bbit"
4646   [(set (pc)
4647         (if_then_else
4648           (match_operator 3 "equality_comparison_operator"
4649             [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
4650                               (const_int 1)
4651                               (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
4652              (const_int 0)])
4653           (label_ref (match_operand 0 "" ""))
4654           (pc)))
4655    (clobber (reg:CC_ZN CC_REG))]
4656   "!CROSSING_JUMP_P (insn)"
4658   switch (get_attr_length (insn))
4659     {
4660       case 4: return (GET_CODE (operands[3]) == EQ
4661                       ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
4662       case 6:
4663       case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
4664       default: gcc_unreachable ();
4665     }
4667   [(set_attr "type" "brcc")
4668    (set_attr "cond" "clob")
4669    (set (attr "length")
4670         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
4671                     (le (minus (match_dup 0) (pc))
4672                     (minus (const_int 248)
4673                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4674                (const_int 4)
4675                (eq (symbol_ref "which_alternative") (const_int 0))
4676                (const_int 6)]
4677               (const_int 8)))
4678    (set (attr "iscompact")
4679         (if_then_else (match_test "get_attr_length (insn) == 6")
4680                       (const_string "true") (const_string "false")))])
4682 ; ??? When testing a bit from a DImode register, combine creates a
4683 ; zero_extract in DImode.  This goes via an AND with a DImode constant,
4684 ; so can only be observed on 64 bit hosts.
4685 (define_insn_and_split "*bbit_di"
4686   [(set (pc)
4687         (if_then_else
4688           (match_operator 3 "equality_comparison_operator"
4689             [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
4690                               (const_int 1)
4691                               (match_operand 2 "immediate_operand" "L,L"))
4692              (const_int 0)])
4693           (label_ref (match_operand 0 "" ""))
4694           (pc)))
4695    (clobber (reg:CC_ZN CC_REG))]
4696   "!CROSSING_JUMP_P (insn)"
4697   "#"
4698   ""
4699   [(parallel
4700      [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
4701       (clobber (reg:CC_ZN CC_REG))])]
4703   rtx xtr;
4705   xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
4706   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
4707                                 xtr, const0_rtx);
4710 ; operand 0 is the loop count pseudo register
4711 ; operand 1 is the loop end pattern
4712 (define_expand "doloop_begin"
4713   [(use (match_operand 0 "register_operand" ""))
4714    (use (match_operand 1 "" ""))]
4715   ""
4717   /* Using the INSN_UID of the loop end pattern to identify it causes
4718      trouble with -fcompare-debug, so allocate a debug-independent
4719      id instead.  We use negative numbers so that we can use the same
4720      slot in doloop_end_i where we later store a CODE_LABEL_NUMBER, and
4721      still be able to tell what kind of number this is.  */
4722   static HOST_WIDE_INT loop_end_id = 0;
4724   rtx id = GEN_INT (--loop_end_id);
4725   XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
4726   emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
4727                                  const0_rtx, const0_rtx));
4728   DONE;
4731 ; ??? can't describe the insn properly as then the optimizers try to
4732 ; hoist the SETs.
4733 ;(define_insn "doloop_begin_i"
4734 ;  [(set (reg:SI LP_START) (pc))
4735 ;   (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_LP))
4736 ;   (use (match_operand 0 "const_int_operand" "n"))]
4737 ;  ""
4738 ;  "lp .L__GCC__LP%0"
4741 ; The operands of doloop_end_i are also read / written by arc_reorg with
4742 ; XVECEXP (PATTERN (lp, 0, N), so if you want to change the pattern, you
4743 ; might have to adjust arc_reorg.
4744 ; operands 0 / 2 are supplied by the expander, 1, 3 and 4 are filled in
4745 ; by arc_reorg.  arc_reorg might also alter operand 0.
4747 ; N in XVECEXP PATTERN (lp, 0 N)
4748 ;  V              rtl                 purpose
4749 ;  0           unspec UNSPEC_LP     identify pattern
4750 ;  1           clobber LP_START     show LP_START is set
4751 ;  2           clobber LP_END       show LP_END is set
4752 ;  3           use operand0         loop count pseudo register
4753 ;  4           use operand1         before arc_reorg: -id
4754 ;                                   after : CODE_LABEL_NUMBER of loop top label
4755 ;  5           use operand2         INSN_UID of loop end insn
4756 ;  6           use operand3         loop setup not at start (1 above, 2 below)
4757 ;  7           use operand4         LABEL_REF of top label, if not
4758 ;                                   immediately following
4759 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
4760 ; instruction that was not at the start of the loop.
4761 ; There is no point is reloading this insn - then lp_count would still not
4762 ; be available for the loop end.
4763 (define_insn "doloop_begin_i"
4764   [(unspec:SI [(pc)] UNSPEC_LP)
4765    (clobber (reg:SI LP_START))
4766    (clobber (reg:SI LP_END))
4767    (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
4768    (use (match_operand 1 "const_int_operand" "n,n,C_0"))
4769    (use (match_operand 2 "const_int_operand" "n,n,X"))
4770    (use (match_operand 3 "const_int_operand" "C_0,n,X"))
4771    (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
4772   ""
4774   rtx_insn *scan;
4775   int len, size = 0;
4776   int n_insns = 0;
4777   rtx loop_start = operands[4];
4779   if (CONST_INT_P (loop_start))
4780     loop_start = NULL_RTX;
4781   /* Size implications of the alignment will be taken care of by the
4782      alignment inserted at the loop start.  */
4783   if (LOOP_ALIGN (0) && INTVAL (operands[1]))
4784     {
4785       asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
4786       arc_clear_unalign ();
4787     }
4788   if (!INTVAL (operands[1]))
4789     return "; LITTLE LOST LOOP";
4790   if (loop_start && flag_pic)
4791     {
4792       /* ??? Can do better for when a scratch register
4793          is known.  But that would require extra testing.  */
4794       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";
4795     }
4796   /* Check if the loop end is in range to be set by the lp instruction.  */
4797   size = INTVAL (operands[3]) < 2 ? 0 : 2048;
4798   for (scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
4799     {
4800       if (!INSN_P (scan))
4801         continue;
4802       if (recog_memoized (scan) == CODE_FOR_doloop_end_i
4803           && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
4804               == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
4805         break;
4806       len = get_attr_length (scan);
4807       size += len;
4808     }
4809   /* Try to verify that there are at least three instruction fetches
4810      between the loop setup and the first encounter of the loop end.  */
4811   for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
4812     {
4813       if (!INSN_P (scan))
4814         continue;
4815       if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (scan)))
4816         scan = seq->insn (0);
4817       if (JUMP_P (scan))
4818         {
4819           if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
4820             {
4821               n_insns += 2;
4822               if (simplejump_p (scan))
4823                 {
4824                   scan = as_a <rtx_insn *> (XEXP (SET_SRC (PATTERN (scan)), 0));
4825                   continue;
4826                 }
4827               if (JUMP_LABEL (scan)
4828                   /* JUMP_LABEL might be simple_return instead if an insn.  */
4829                   && (!INSN_P (JUMP_LABEL (scan))
4830                       || (!next_active_insn (JUMP_LABEL (scan))
4831                           || (recog_memoized (next_active_insn (JUMP_LABEL (scan)))
4832                               != CODE_FOR_doloop_begin_i)))
4833                   && (!next_active_insn (NEXT_INSN (PREV_INSN (scan)))
4834                       || (recog_memoized
4835                            (next_active_insn (NEXT_INSN (PREV_INSN (scan))))
4836                           != CODE_FOR_doloop_begin_i)))
4837                 n_insns++;
4838             }
4839           break;
4840         }
4841       len = get_attr_length (scan);
4842       /* Size estimation of asms assumes that each line which is nonempty
4843          codes an insn, and that each has a long immediate.  For minimum insn
4844          count, assume merely that a nonempty asm has at least one insn.  */
4845       if (GET_CODE (PATTERN (scan)) == ASM_INPUT
4846           || asm_noperands (PATTERN (scan)) >= 0)
4847         n_insns += (len != 0);
4848       else
4849         n_insns += (len > 4 ? 2 : (len ? 1 : 0));
4850     }
4851   if (LOOP_ALIGN (0))
4852     {
4853       asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
4854       arc_clear_unalign ();
4855     }
4856   gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
4857   if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
4858     {
4859       if (flag_pic)
4860         {
4861           /* ??? Can do better for when a scratch register
4862              is known.  But that would require extra testing.  */
4863           arc_clear_unalign ();
4864           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";
4865         }
4866       output_asm_insn ((size < 2048
4867                         ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
4868                        operands);
4869       output_asm_insn (loop_start
4870                        ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
4871                        operands);
4872       if (TARGET_ARC600 && n_insns < 1)
4873         output_asm_insn ("nop", operands);
4874       return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
4875     }
4876   else if (TARGET_ARC600 && n_insns < 3)
4877     {
4878       /* At least four instructions are needed between the setting of LP_COUNT
4879          and the loop end - but the lp instruction qualifies as one.  */
4880       rtx prev = prev_nonnote_insn (insn);
4882       if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
4883         output_asm_insn ("nop", operands);
4884     }
4885   return "lp .L__GCC__LP%1";
4887   [(set_attr "type" "loop_setup")
4888    (set_attr_alternative "length"
4889 ;     FIXME: length is usually 4, but we need branch shortening
4890 ;     to get this right.
4891 ;     [(if_then_else (match_test "TARGET_ARC600") (const_int 16) (const_int 4))
4892      [(if_then_else (match_test "flag_pic") (const_int 24) (const_int 16))
4893       (if_then_else (match_test "flag_pic") (const_int 28) (const_int 16))
4894       (const_int 0)])]
4895   ;; ??? we should really branch shorten this insn, but then we'd
4896   ;; need a proper label first.  N.B. the end label can not only go out
4897   ;; of range when it is far away, but also when it precedes the loop -
4898   ;; which, unfortunately, it sometimes does, when the loop "optimizer"
4899   ;; messes things up.
4902 ; operand 0 is the loop count pseudo register
4903 ; operand 1 is the label to jump to at the top of the loop
4904 ; Use this for the ARC600 and ARC700.  For ARCtangent-A5, this is unsafe
4905 ; without further checking for nearby branches etc., and without proper
4906 ; annotation of shift patterns that clobber lp_count
4907 ; ??? ARC600 might want to check if the loop has few iteration and only a
4908 ; single insn - loop setup is expensive then.
4909 (define_expand "doloop_end"
4910   [(use (match_operand 0 "register_operand" ""))
4911    (use (label_ref (match_operand 1 "" "")))]
4912   "TARGET_ARC600 || TARGET_ARC700"
4914   /* We could do smaller bivs with biv widening, and wider bivs by having
4915      a high-word counter in an outer loop - but punt on this for now.  */
4916   if (GET_MODE (operands[0]) != SImode)
4917     FAIL;
4918   emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
4919   DONE;
4922 (define_insn_and_split "doloop_end_i"
4923   [(set (pc)
4924         (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
4925                            (const_int 1))
4926                       (label_ref (match_operand 1 "" ""))
4927                       (pc)))
4928    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
4929    (use (reg:SI LP_START))
4930    (use (reg:SI LP_END))
4931    (use (match_operand 2 "const_int_operand" "n,???Cn0,???X"))
4932    (clobber (match_scratch:SI 3 "=X,X,&????r"))]
4933   ""
4934   "*
4936   rtx prev = prev_nonnote_insn (insn);
4938   /* If there is an immediately preceding label, we must output a nop,
4939      lest a branch to that label will fall out of the loop.
4940      ??? We could try to avoid this by claiming to have a delay slot if there
4941      is a preceding label, and outputting the delay slot insn instead, if
4942      present.
4943      Or we could have some optimization that changes the source edge to update
4944      the loop count and jump to the loop start instead.  */
4945   /* For ARC600, we must also prevent jumps inside the loop and jumps where
4946      the loop counter value is live at the target from being directly at the
4947      loop end.  Being sure that the loop counter is dead at the target is
4948      too much hair - we can't rely on data flow information at this point -
4949      so insert a nop for all branches.
4950      The ARC600 also can't read the loop counter in the last insn of a loop.  */
4951   if (LABEL_P (prev))
4952     output_asm_insn (\"nop%?\", operands);
4953   return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
4955   "&& memory_operand (operands[0], SImode)"
4956   [(pc)]
4958   emit_move_insn (operands[3], operands[0]);
4959   emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
4960   DONE;
4962   [(set_attr "type" "loop_end")
4963    (set (attr "length")
4964         (if_then_else (match_test "LABEL_P (prev_nonnote_insn (insn))")
4965                       (const_int 4) (const_int 0)))]
4968 ; This pattern is generated by arc_reorg when there is no recognizable
4969 ; loop start.
4970 (define_insn "*doloop_fallback"
4971   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
4972                                 (const_int 1))
4973                            (label_ref (match_operand 1 "" ""))
4974                            (pc)))
4975    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
4976    ; avoid fooling the loop optimizer into assuming this is a special insn.
4977   "reload_completed"
4978   "*return get_attr_length (insn) == 8
4979    ? \"brne.d %0,1,%1\;sub %0,%0,1\"
4980    : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
4981   [(set (attr "length")
4982         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
4983                            (le (minus (match_dup 1) (pc)) (const_int 244)))
4984                       (const_int 8) (const_int 12)))
4985    (set_attr "type" "brcc_no_delay_slot")
4986    (set_attr "cond" "nocond")]
4989 ; reload can't make output reloads for jump insns, so we have to do this by hand.
4990 (define_insn "doloop_fallback_m"
4991   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
4992                                 (const_int 1))
4993                            (label_ref (match_operand 1 "" ""))
4994                            (pc)))
4995    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
4996    (set (match_operand:SI 2 "memory_operand" "=m")
4997         (plus:SI (match_dup 0) (const_int -1)))]
4998    ; avoid fooling the loop optimizer into assuming this is a special insn.
4999   "reload_completed"
5000   "*return get_attr_length (insn) == 12
5001    ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5002    : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5003   [(set (attr "length")
5004         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5005                            (le (minus (match_dup 1) (pc)) (const_int 244)))
5006                       (const_int 12) (const_int 16)))
5007    (set_attr "type" "brcc_no_delay_slot")
5008    (set_attr "cond" "nocond")]
5011 (define_expand "movmemsi"
5012   [(match_operand:BLK 0 "" "")
5013    (match_operand:BLK 1 "" "")
5014    (match_operand:SI 2 "nonmemory_operand" "")
5015    (match_operand 3 "immediate_operand" "")]
5016   ""
5017   "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5019 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5020 ;; to the point that we can generate cmove instructions.
5021 (define_expand "cbranch<mode>4"
5022   [(set (reg:CC CC_REG)
5023         (compare:CC (match_operand:SDF 1 "register_operand" "")
5024                     (match_operand:SDF 2 "register_operand" "")))
5025    (set (pc)
5026         (if_then_else
5027               (match_operator 0 "comparison_operator" [(reg CC_REG)
5028                                                        (const_int 0)])
5029               (label_ref (match_operand 3 "" ""))
5030               (pc)))]
5032   "TARGET_OPTFPE"
5034   gcc_assert (XEXP (operands[0], 0) == operands[1]);
5035   gcc_assert (XEXP (operands[0], 1) == operands[2]);
5036   operands[0] = gen_compare_reg (operands[0], VOIDmode);
5037   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5038   DONE;
5041 (define_expand "cmp_float"
5042   [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5043               (clobber (reg:SI RETURN_ADDR_REGNUM))
5044               (clobber (reg:SI R12_REG))])]
5045   ""
5046   "")
5048 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5049 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5050                        (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5052 (define_insn "*cmpsf_<cmp>"
5053   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5054    (clobber (reg:SI RETURN_ADDR_REGNUM))
5055    (clobber (reg:SI R12_REG))]
5056   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5057    && SFUNC_CHECK_PREDICABLE"
5058   "*return arc_output_libcall (\"__<cmp>sf2\");"
5059   [(set_attr "is_sfunc" "yes")
5060    (set_attr "predicable" "yes")])
5062 ;; N.B. for "*cmpdf_ord":
5063 ;; double precision fpx sets bit 31 for NaNs.  We need bit 51 set
5064 ;; for the floating point emulation to recognize the NaN.
5065 (define_insn "*cmpdf_<cmp>"
5066   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5067    (clobber (reg:SI RETURN_ADDR_REGNUM))
5068    (clobber (reg:SI R12_REG))]
5069   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5070    && SFUNC_CHECK_PREDICABLE"
5071   "*return arc_output_libcall (\"__<cmp>df2\");"
5072   [(set_attr "is_sfunc" "yes")
5073    (set_attr "predicable" "yes")])
5075 (define_insn "abssf2"
5076   [(set (match_operand:SF 0 "dest_reg_operand"    "=Rcq#q,Rcw,w")
5077         (abs:SF (match_operand:SF 1 "register_operand" "0,  0,c")))]
5078   ""
5079   "bclr%? %0,%1,31%&"
5080   [(set_attr "type" "unary")
5081    (set_attr "iscompact" "maybe,false,false")
5082    (set_attr "length" "2,4,4")
5083    (set_attr "predicable" "no,yes,no")])
5085 (define_insn "negsf2"
5086   [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5087         (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5088   ""
5089   "bxor%? %0,%1,31"
5090   [(set_attr "type" "unary")
5091    (set_attr "predicable" "yes,no")])
5093 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5094 (define_insn "*millicode_thunk_st"
5095   [(match_parallel 0 "millicode_store_operation"
5096      [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5097   ""
5099   output_asm_insn ("bl%* __st_r13_to_%0",
5100                    &SET_SRC (XVECEXP (operands[0], 0,
5101                                       XVECLEN (operands[0], 0) - 2)));
5102   return "";
5104   [(set_attr "type" "call")])
5106 (define_insn "*millicode_thunk_ld"
5107   [(match_parallel 0 "millicode_load_clob_operation"
5108      [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5109   ""
5111   output_asm_insn ("bl%* __ld_r13_to_%0",
5112                    &SET_DEST (XVECEXP (operands[0], 0,
5113                                        XVECLEN (operands[0], 0) - 2)));
5114   return "";
5116   [(set_attr "type" "call")])
5118 ; the sibthunk restores blink, so we use the return rtx.
5119 (define_insn "*millicode_sibthunk_ld"
5120   [(match_parallel 0 "millicode_load_operation"
5121      [(return)
5122       (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5123       (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5124   ""
5126   output_asm_insn ("b%* __ld_r13_to_%0_ret",
5127                    &SET_DEST (XVECEXP (operands[0], 0,
5128                                        XVECLEN (operands[0], 0) - 1)));
5129   return "";
5131   [(set_attr "type" "call")
5132    (set_attr "is_SIBCALL" "yes")])
5134 ;; If hardware floating point is available, don't define a negdf pattern;
5135 ;; it would be something like:
5136 ;;(define_insn "negdf2"
5137 ;;  [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5138 ;;      (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5139 ;;   (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5140 ;;  ""
5141 ;;  "@
5142 ;;   bxor%? %H0,%H1,31
5143 ;;   bxor %H0,%H1,31 ` mov %L0,%L1
5144 ;;   drsubh%F0%F1 0,0,0
5145 ;;   drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5146 ;;  [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5147 ;;   (set_attr "iscompact" "false,false,false,false")
5148 ;;   (set_attr "length" "4,4,8,12")
5149 ;;   (set_attr "cond" "canuse,nocond,nocond,nocond")])
5150 ;; and this suffers from always requiring a long immediate when using
5151 ;; the floating point hardware.
5152 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5153 ;; constant zero efficiently into a register when we want to do the
5154 ;; computation using the floating point hardware.  There should be a special
5155 ;; subdf alternative that matches a zero operand 1, which then can allow
5156 ;; to use bxor to flip the high bit of an integer register.
5157 ;; ??? we actually can't use the floating point hardware for neg, because
5158 ;; this would not work right for -0.  OTOH optabs.c has already code
5159 ;; to synthesyze negate by flipping the sign bit.
5162 ;; include the arc-FPX instructions
5163 (include "fpx.md")
5165 (include "simdext.md")