Fix post-reload predicate mismatch ICE during qt build:
[official-gcc.git] / gcc / config / arc / arc.md
blob80f6e338a1092d84d519996300b6e8ff100bd821
1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2014 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]), REGNO (operands[0]) + 1,
956                              operands [1], 0))
957         return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
958       else switch (GET_CODE (XEXP(operands[1], 0)))
959         {
960         case POST_MODIFY: case POST_INC: case POST_DEC:
961           return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\";
962         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
963           return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\";
964         default:
965           return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\";
966         }
967     case 3 :
968       switch (GET_CODE (XEXP(operands[0], 0)))
969         {
970         case POST_MODIFY: case POST_INC: case POST_DEC:
971           return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\";
972         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
973           return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\";
974         default:
975           return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\";
976         }
977     }
979   "&& reload_completed && optimize"
980   [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
981   "arc_split_move (operands);"
982   [(set_attr "type" "move,move,load,store")
983    ;; ??? The ld/st values could be 4 if it's [reg,bignum].
984    (set_attr "length" "8,16,16,16")])
987 ;; Floating point move insns.
989 (define_expand "movsf"
990   [(set (match_operand:SF 0 "general_operand" "")
991         (match_operand:SF 1 "general_operand" ""))]
992   ""
993   "if (prepare_move_operands (operands, SFmode)) DONE;")
995 (define_insn "*movsf_insn"
996   [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m")
997         (match_operand:SF 1 "move_src_operand" "c,E,m,c"))]
998   "register_operand (operands[0], SFmode)
999    || register_operand (operands[1], SFmode)"
1000   "@
1001    mov%? %0,%1
1002    mov%? %0,%1 ; %A1
1003    ld%U1%V1 %0,%1
1004    st%U0%V0 %1,%0"
1005   [(set_attr "type" "move,move,load,store")
1006    (set_attr "predicable" "yes,yes,no,no")])
1008 (define_expand "movdf"
1009   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1010         (match_operand:DF 1 "general_operand" ""))]
1011   ""
1012   "if (prepare_move_operands (operands, DFmode)) DONE;")
1014 (define_insn "*movdf_insn"
1015   [(set (match_operand:DF 0 "move_dest_operand"      "=D,r,c,c,r,m")
1016         (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1017   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1018   "#"
1019   [(set_attr "type" "move,move,move,move,load,store")
1020    (set_attr "predicable" "no,no,yes,yes,no,no")
1021    ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1022    (set_attr "length" "4,16,8,16,16,16")])
1024 (define_split
1025   [(set (match_operand:DF 0 "move_dest_operand" "")
1026         (match_operand:DF 1 "move_double_src_operand" ""))]
1027   "reload_completed"
1028   [(match_dup 2)]
1029   "operands[2] = arc_split_move (operands);")
1031 (define_insn_and_split "*movdf_insn_nolrsr"
1032   [(set (match_operand:DF 0 "register_operand"       "=r")
1033         (match_operand:DF 1 "arc_double_register_operand" "D"))
1034    (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1035    ]
1036   "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1037   "#"
1038   "&& 1"
1039   [
1040     ; mov r0, 0
1041     (set (match_dup 0) (match_dup 3))
1043     ; daddh?? r1, r0, r0
1044     (parallel [
1045         (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1046         (use (const_int 1))
1047         (use (const_int 1))
1048         (use (match_dup 0)) ; used to block can_combine_p
1049         (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1050     ])
1052     ; We have to do this twice, once to read the value into R0 and
1053     ; second time to put back the contents which the first DEXCLx
1054     ; will have overwritten
1055     ; dexcl2 r0, r1, r0
1056     (set (match_dup 4) ; aka r0result
1057          ; aka DF, r1, r0
1058          (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_DEXCL ))
1059     ; Generate the second, which makes sure operand5 and operand4 values
1060     ; are put back in the Dx register properly.
1061     (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_DEXCL_NORES )
1063     ; Note: we cannot use a (clobber (match_scratch)) here because
1064     ; the combine pass will end up replacing uses of it with 0
1065   ]
1066   "operands[3] = CONST0_RTX (DFmode);
1067    operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1068    operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1069   [(set_attr "type" "move")])
1071 ;; Load/Store with update instructions.
1073 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1074 ;; hardware can also do cases where the increment is not the size of the
1075 ;; object.
1077 ;; In all these cases, we use operands 0 and 1 for the register being
1078 ;; incremented because those are the operands that local-alloc will
1079 ;; tie and these are the pair most likely to be tieable (and the ones
1080 ;; that will benefit the most).
1082 ;; We use match_operator here because we need to know whether the memory
1083 ;; object is volatile or not.
1086 ;; Note: loadqi_update has no 16-bit variant
1087 (define_insn "*loadqi_update"
1088   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1089         (match_operator:QI 4 "load_update_operand"
1090          [(match_operand:SI 1 "register_operand" "0,0")
1091           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1092    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1093         (plus:SI (match_dup 1) (match_dup 2)))]
1094   ""
1095   "ldb.a%V4 %3,[%0,%S2]"
1096   [(set_attr "type" "load,load")
1097    (set_attr "length" "4,8")])
1099 (define_insn "*load_zeroextendqisi_update"
1100   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1101         (zero_extend:SI (match_operator:QI 4 "load_update_operand"
1102                          [(match_operand:SI 1 "register_operand" "0,0")
1103                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1104    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1105         (plus:SI (match_dup 1) (match_dup 2)))]
1106   ""
1107   "ldb.a%V4 %3,[%0,%S2]"
1108   [(set_attr "type" "load,load")
1109    (set_attr "length" "4,8")])
1111 (define_insn "*load_signextendqisi_update"
1112   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1113         (sign_extend:SI (match_operator:QI 4 "load_update_operand"
1114                          [(match_operand:SI 1 "register_operand" "0,0")
1115                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1116    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1117         (plus:SI (match_dup 1) (match_dup 2)))]
1118   ""
1119   "ldb.x.a%V4 %3,[%0,%S2]"
1120   [(set_attr "type" "load,load")
1121    (set_attr "length" "4,8")])
1123 (define_insn "*storeqi_update"
1124   [(set (match_operator:QI 4 "store_update_operand"
1125          [(match_operand:SI 1 "register_operand" "0")
1126           (match_operand:SI 2 "short_immediate_operand" "I")])
1127         (match_operand:QI 3 "register_operand" "c"))
1128    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1129         (plus:SI (match_dup 1) (match_dup 2)))]
1130   ""
1131   "stb.a%V4 %3,[%0,%2]"
1132   [(set_attr "type" "store")
1133    (set_attr "length" "4")])
1135 ;; ??? pattern may have to be re-written
1136 ;; Note: no 16-bit variant for this pattern
1137 (define_insn "*loadhi_update"
1138   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1139         (match_operator:HI 4 "load_update_operand"
1140          [(match_operand:SI 1 "register_operand" "0,0")
1141           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1142    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1143         (plus:SI (match_dup 1) (match_dup 2)))]
1144   ""
1145   "ldw.a%V4 %3,[%0,%S2]"
1146   [(set_attr "type" "load,load")
1147    (set_attr "length" "4,8")])
1149 (define_insn "*load_zeroextendhisi_update"
1150   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1151         (zero_extend:SI (match_operator:HI 4 "load_update_operand"
1152                          [(match_operand:SI 1 "register_operand" "0,0")
1153                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1154    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1155         (plus:SI (match_dup 1) (match_dup 2)))]
1156   ""
1157   "ldw.a%V4 %3,[%0,%S2]"
1158   [(set_attr "type" "load,load")
1159    (set_attr "length" "4,8")])
1161 ;; Note: no 16-bit variant for this instruction
1162 (define_insn "*load_signextendhisi_update"
1163   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1164         (sign_extend:SI (match_operator:HI 4 "load_update_operand"
1165                          [(match_operand:SI 1 "register_operand" "0,0")
1166                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1167    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1168         (plus:SI (match_dup 1) (match_dup 2)))]
1169   ""
1170   "ldw.x.a%V4 %3,[%0,%S2]"
1171   [(set_attr "type" "load,load")
1172    (set_attr "length" "4,8")])
1174 (define_insn "*storehi_update"
1175   [(set (match_operator:HI 4 "store_update_operand"
1176          [(match_operand:SI 1 "register_operand" "0")
1177           (match_operand:SI 2 "short_immediate_operand" "I")])
1178         (match_operand:HI 3 "register_operand" "c"))
1179    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1180         (plus:SI (match_dup 1) (match_dup 2)))]
1181   ""
1182   "stw.a%V4 %3,[%0,%2]"
1183   [(set_attr "type" "store")
1184    (set_attr "length" "4")])
1186 ;; No 16-bit variant for this instruction pattern
1187 (define_insn "*loadsi_update"
1188   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1189         (match_operator:SI 4 "load_update_operand"
1190          [(match_operand:SI 1 "register_operand" "0,0")
1191           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1192    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1193         (plus:SI (match_dup 1) (match_dup 2)))]
1194   ""
1195   "ld.a%V4 %3,[%0,%S2]"
1196   [(set_attr "type" "load,load")
1197    (set_attr "length" "4,8")])
1199 (define_insn "*storesi_update"
1200   [(set (match_operator:SI 4 "store_update_operand"
1201          [(match_operand:SI 1 "register_operand" "0")
1202           (match_operand:SI 2 "short_immediate_operand" "I")])
1203         (match_operand:SI 3 "register_operand" "c"))
1204    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1205         (plus:SI (match_dup 1) (match_dup 2)))]
1206   ""
1207   "st.a%V4 %3,[%0,%2]"
1208   [(set_attr "type" "store")
1209    (set_attr "length" "4")])
1211 (define_insn "*loadsf_update"
1212   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1213         (match_operator:SF 4 "load_update_operand"
1214          [(match_operand:SI 1 "register_operand" "0,0")
1215           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1216    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1217         (plus:SI (match_dup 1) (match_dup 2)))]
1218   ""
1219   "ld.a%V4 %3,[%0,%S2]"
1220   [(set_attr "type" "load,load")
1221    (set_attr "length" "4,8")])
1223 (define_insn "*storesf_update"
1224   [(set (match_operator:SF 4 "store_update_operand"
1225          [(match_operand:SI 1 "register_operand" "0")
1226           (match_operand:SI 2 "short_immediate_operand" "I")])
1227         (match_operand:SF 3 "register_operand" "c"))
1228    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1229         (plus:SI (match_dup 1) (match_dup 2)))]
1230   ""
1231   "st.a%V4 %3,[%0,%2]"
1232   [(set_attr "type" "store")
1233    (set_attr "length" "4")])
1235 ;; Conditional move instructions.
1237 (define_expand "movsicc"
1238   [(set (match_operand:SI 0 "dest_reg_operand" "")
1239         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1240                          (match_operand:SI 2 "nonmemory_operand" "")
1241                          (match_operand:SI 3 "register_operand" "")))]
1242   ""
1243   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1246 (define_expand "movdicc"
1247   [(set (match_operand:DI 0 "dest_reg_operand" "")
1248         (if_then_else:DI(match_operand 1 "comparison_operator" "")
1249                         (match_operand:DI 2 "nonmemory_operand" "")
1250                         (match_operand:DI 3 "register_operand" "")))]
1251   ""
1252   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1255 (define_expand "movsfcc"
1256   [(set (match_operand:SF 0 "dest_reg_operand" "")
1257         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1258                       (match_operand:SF 2 "nonmemory_operand" "")
1259                       (match_operand:SF 3 "register_operand" "")))]
1260   ""
1261   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1263 (define_expand "movdfcc"
1264   [(set (match_operand:DF 0 "dest_reg_operand" "")
1265         (if_then_else:DF (match_operand 1 "comparison_operator" "")
1266                       (match_operand:DF 2 "nonmemory_operand" "")
1267                       (match_operand:DF 3 "register_operand" "")))]
1268   ""
1269   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1271 (define_insn "*movsicc_insn"
1272   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1273         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1274                        [(match_operand 4 "cc_register" "") (const_int 0)])
1275                       (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1276                       (match_operand:SI 2 "register_operand" "0,0")))]
1277   ""
1279   if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1280       && satisfies_constraint_Rcq (operands[0]))
1281     return "sub%?.ne %0,%0,%0";
1282   /* ??? might be good for speed on ARC600 too, *if* properly scheduled.  */
1283   if ((TARGET_ARC700 || optimize_size)
1284       && rtx_equal_p (operands[1], constm1_rtx)
1285       && GET_CODE (operands[3]) == LTU)
1286     return "sbc.cs %0,%0,%0";
1287   return "mov.%d3 %0,%S1";
1289   [(set_attr "type" "cmove,cmove")
1290    (set_attr "length" "4,8")])
1292 ; Try to generate more short moves, and/or less limms, by substituting a
1293 ; conditional move with a conditional sub.
1294 (define_peephole2
1295   [(set (match_operand:SI 0 "compact_register_operand")
1296         (match_operand:SI 1 "const_int_operand"))
1297    (set (match_dup 0)
1298         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1299                            [(match_operand 4 "cc_register" "") (const_int 0)])
1300                             (match_operand:SI 2 "const_int_operand" "")
1301                       (match_dup 0)))]
1302   "!satisfies_constraint_P (operands[1])
1303    && satisfies_constraint_P (operands[2])
1304    && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1305   [(set (match_dup 0) (match_dup 2))
1306    (cond_exec
1307      (match_dup 3)
1308      (set (match_dup 0)
1309           (plus:SI (match_dup 0) (match_dup 1))))]
1310   "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1311                                                     GET_MODE (operands[4])),
1312                                  VOIDmode, operands[4], const0_rtx);
1313    operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1315 (define_insn "*movdicc_insn"
1316   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1317         (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1318                         [(match_operand 4 "cc_register" "") (const_int 0)])
1319                       (match_operand:DI 1 "nonmemory_operand" "c,i")
1320                       (match_operand:DI 2 "register_operand" "0,0")))]
1321    ""
1322    "*
1324    switch (which_alternative)
1325      {
1326      default:
1327      case 0 :
1328        /* We normally copy the low-numbered register first.  However, if
1329          the first register operand 0 is the same as the second register of
1330          operand 1, we must copy in the opposite order.  */
1331        if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1332         return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1333        else
1334         return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1335      case 1 :
1336         return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1339      }
1341   [(set_attr "type" "cmove,cmove")
1342    (set_attr "length" "8,16")])
1345 (define_insn "*movsfcc_insn"
1346   [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1347         (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1348                        [(match_operand 4 "cc_register" "") (const_int 0)])
1349                       (match_operand:SF 1 "nonmemory_operand" "c,E")
1350                       (match_operand:SF 2 "register_operand" "0,0")))]
1351   ""
1352   "@
1353    mov.%d3 %0,%1
1354    mov.%d3 %0,%1 ; %A1"
1355   [(set_attr "type" "cmove,cmove")])
1357 (define_insn "*movdfcc_insn"
1358   [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1359         (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1360                  [(match_operand 4 "cc_register" "") (const_int 0)])
1361                       (match_operand:DF 2 "nonmemory_operand" "c,E")
1362                       (match_operand:DF 3 "register_operand" "0,0")))]
1363   ""
1364   "*
1366   switch (which_alternative)
1367     {
1368     default:
1369     case 0 :
1370       /* We normally copy the low-numbered register first.  However, if
1371          the first register operand 0 is the same as the second register of
1372          operand 1, we must copy in the opposite order.  */
1373       if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1374         return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1375       else
1376         return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1377     case 1 :
1378               return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1380     }
1382   [(set_attr "type" "cmove,cmove")
1383    (set_attr "length" "8,16")])
1386 (define_insn "*zero_extendqihi2_i"
1387   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
1388         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
1389   ""
1390   "@
1391    extb%? %0,%1%&
1392    extb%? %0,%1%&
1393    bmsk%? %0,%1,7
1394    extb %0,%1
1395    ldb%U1 %0,%1"
1396   [(set_attr "type" "unary,unary,unary,unary,load")
1397    (set_attr "iscompact" "maybe,true,false,false,false")
1398    (set_attr "predicable" "no,no,yes,no,no")])
1400 (define_expand "zero_extendqihi2"
1401   [(set (match_operand:HI 0 "dest_reg_operand" "")
1402         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1403   ""
1404   "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1407 (define_insn "*zero_extendqisi2_ac"
1408   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
1409         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
1410   ""
1411   "@
1412    extb%? %0,%1%&
1413    extb%? %0,%1%&
1414    bmsk%? %0,%1,7
1415    extb %0,%1
1416    ldb%? %0,%1%&
1417    ldb%? %0,%1%&
1418    ldb%U1 %0,%1"
1419   [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1420    (set_attr "iscompact" "maybe,true,false,false,true,true,false")
1421    (set_attr "predicable" "no,no,yes,no,no,no,no")])
1423 (define_expand "zero_extendqisi2"
1424   [(set (match_operand:SI 0 "dest_reg_operand" "")
1425         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1426   ""
1427   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1430 (define_insn "*zero_extendhisi2_i"
1431   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
1432         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
1433   ""
1434   "@
1435    extw%? %0,%1%&
1436    extw%? %0,%1%&
1437    bmsk%? %0,%1,15
1438    extw %0,%1
1439    ldw%? %0,%1%&
1440    ldw%U1 %0,%1
1441    ldw%U1%V1 %0,%1"
1442   [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1443    (set_attr "iscompact" "maybe,true,false,false,true,false,false")
1444    (set_attr "predicable" "no,no,yes,no,no,no,no")])
1447 (define_expand "zero_extendhisi2"
1448   [(set (match_operand:SI 0 "dest_reg_operand" "")
1449         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1450   ""
1451   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1454 ;; Sign extension instructions.
1456 (define_insn "*extendqihi2_i"
1457   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
1458         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
1459   ""
1460   "@
1461    sexb%? %0,%1%&
1462    sexb %0,%1
1463    ldb.x%U1 %0,%1"
1464   [(set_attr "type" "unary,unary,load")
1465    (set_attr "iscompact" "true,false,false")])
1468 (define_expand "extendqihi2"
1469   [(set (match_operand:HI 0 "dest_reg_operand" "")
1470         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1471   ""
1472   "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1475 (define_insn "*extendqisi2_ac"
1476   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1477         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1478   ""
1479   "@
1480    sexb%? %0,%1%&
1481    sexb %0,%1
1482    ldb.x%U1 %0,%1"
1483   [(set_attr "type" "unary,unary,load")
1484    (set_attr "iscompact" "true,false,false")])
1486 (define_expand "extendqisi2"
1487   [(set (match_operand:SI 0 "dest_reg_operand" "")
1488         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1489   ""
1490   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1493 (define_insn "*extendhisi2_i"
1494   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1495         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1496   ""
1497   "@
1498    sexw%? %0,%1%&
1499    sexw %0,%1
1500    ldw.x%U1%V1 %0,%1"
1501   [(set_attr "type" "unary,unary,load")
1502    (set_attr "iscompact" "true,false,false")])
1504 (define_expand "extendhisi2"
1505   [(set (match_operand:SI 0 "dest_reg_operand" "")
1506         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1507   ""
1508   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1511 ;; Unary arithmetic insns
1513 ;; We allow constant operands to enable late constant propagation, but it is
1514 ;; not worth while to have more than one dedicated alternative to output them -
1515 ;; if we are really worried about getting these the maximum benefit of all
1516 ;; the available alternatives, we should add an extra pass to fold such
1517 ;; operations to movsi.
1519 ;; Absolute instructions
1521 (define_insn "*abssi2_mixed"
1522   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1523         (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1524   "TARGET_MIXED_CODE"
1525   "abs%? %0,%1%&"
1526   [(set_attr "type" "two_cycle_core")
1527    (set_attr "iscompact" "true")])
1529 (define_insn "abssi2"
1530   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1531         (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1532   ""
1533   "abs%? %0,%1%&"
1534   [(set_attr "type" "two_cycle_core")
1535    (set_attr "length" "*,4,8")
1536    (set_attr "iscompact" "true,false,false")])
1538 ;; Maximum and minimum insns
1540 (define_insn "smaxsi3"
1541    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1542          (smax:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1543                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1544   ""
1545   "max%? %0,%1,%2"
1546   [(set_attr "type" "two_cycle_core")
1547    (set_attr "length" "4,4,8")
1548    (set_attr "predicable" "yes,no,no")]
1551 (define_insn "sminsi3"
1552    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1553          (smin:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1554                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1555   ""
1556   "min%? %0,%1,%2"
1557   [(set_attr "type" "two_cycle_core")
1558    (set_attr "length" "4,4,8")
1559    (set_attr "predicable" "yes,no,no")]
1562 ;; Arithmetic instructions.
1564 ; We say an insn can be conditionalized if this doesn't introduce a long
1565 ; immediate.  We set the type such that we still have good scheduling if the
1566 ; insn is conditionalized.
1567 ; ??? It would make sense to allow introduction of long immediates, but
1568 ;     we'd need to communicate to the ccfsm machinery the extra cost.
1569 ; The alternatives in the constraints still serve three purposes:
1570 ; - estimate insn size assuming conditional execution
1571 ; - guide reload to re-order the second and third operand to get a better fit.
1572 ; - give tentative insn type to guide scheduling
1573 ;   N.B. "%" for commutativity doesn't help when there is another matching
1574 ;   (but longer) alternative.
1575 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1576 ;  register class 'W' instead of 'w'.
1577 (define_insn_and_split "*addsi3_mixed"
1578   ;;                                                      0       1   2   3   4   5   6    7     8    9     a   b c   d    e   f  10
1579   [(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")
1580         (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")
1581                  (match_operand:SI 2 "nonmemory_operand" "cL,     0, cL,  0,CL2,Csp,CM4,cCca,RcqqK,  cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1582   ""
1584   arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1585   return "";
1587   "&& reload_completed && get_attr_length (insn) == 8
1588    && satisfies_constraint_I (operands[2])
1589    && GET_CODE (PATTERN (insn)) != COND_EXEC"
1590   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1591   "split_addsi (operands);"
1592   [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*")
1593    (set (attr "iscompact")
1594         (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1595                (const_string "false")
1596                (match_operand 2 "long_immediate_operand" "")
1597                (const_string "maybe_limm")]
1598               (const_string "maybe")))
1599    (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8")
1600    (set_attr "predicable" "no,no,yes,yes,no,no,no,yes,no,no,no,no,no,no,no,yes,no")
1601    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1604 ;; ARC700/ARC600 multiply
1605 ;; SI <- SI * SI
1607 (define_expand "mulsi3"
1608  [(set (match_operand:SI 0 "nonimmediate_operand"            "")
1609         (mult:SI (match_operand:SI 1 "register_operand"  "")
1610                  (match_operand:SI 2 "nonmemory_operand" "")))]
1611   ""
1613   if (TARGET_ARC700 && !TARGET_NOMPY_SET)
1614     {
1615       if (!register_operand (operands[0], SImode))
1616         {
1617           rtx result = gen_reg_rtx (SImode);
1619           emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1620           emit_move_insn (operands[0], result);
1621           DONE;
1622         }
1623     }
1624   else if (TARGET_MUL64_SET)
1625     {
1626       emit_insn (gen_mulsi_600 (operands[1], operands[2],
1627                                 gen_mlo (), gen_mhi ()));
1628       emit_move_insn (operands[0], gen_mlo ());
1629       DONE;
1630     }
1631   else if (TARGET_MULMAC_32BY16_SET)
1632     {
1633       if (immediate_operand (operands[2], SImode)
1634           && INTVAL (operands[2]) >= 0
1635           && INTVAL (operands[2]) <= 65535)
1636         {
1637           emit_insn (gen_umul_600 (operands[1], operands[2],
1638                                      gen_acc2 (), gen_acc1 ()));
1639           emit_move_insn (operands[0], gen_acc2 ());
1640           DONE;
1641         }
1642       operands[2] = force_reg (SImode, operands[2]);
1643       emit_insn (gen_umul_600 (operands[1], operands[2],
1644                                gen_acc2 (), gen_acc1 ()));
1645       emit_insn (gen_mac_600 (operands[1], operands[2],
1646                                gen_acc2 (), gen_acc1 ()));
1647       emit_move_insn (operands[0], gen_acc2 ());
1648       DONE;
1649     }
1650   else
1651     {
1652       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1653       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1654       emit_insn (gen_mulsi3_600_lib ());
1655       emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1656       DONE;
1657     }
1660 ; mululw conditional execution without a LIMM clobbers an input register;
1661 ; we'd need a different pattern to describe this.
1662 ; To make the conditional execution valid for the LIMM alternative, we
1663 ; have to emit the LIMM before the register operand.
1664 (define_insn "umul_600"
1665   [(set (match_operand:SI 2 "acc2_operand" "")
1666         (mult:SI (match_operand:SI 0 "register_operand"  "c,c,c")
1667                  (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
1668                                                          "c,L,Cal")
1669                                   (const_int 16)
1670                                   (const_int 0))))
1671    (clobber (match_operand:SI 3 "acc1_operand" ""))]
1672   "TARGET_MULMAC_32BY16_SET"
1673   "@mululw 0, %0, %1
1674     mululw 0, %0, %1
1675     mululw%? 0, %1, %0"
1676   [(set_attr "length" "4,4,8")
1677    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1678    (set_attr "predicable" "no, no, yes")
1679    (set_attr "cond" "nocond, canuse_limm, canuse")])
1681 (define_insn "mac_600"
1682   [(set (match_operand:SI 2 "acc2_operand" "")
1683         (plus:SI
1684           (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1685                    (ashift:SI
1686                      (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
1687                                       (const_int 16)
1688                                       (const_int 16))
1689                      (const_int 16)))
1690           (match_dup 2)))
1691    (clobber (match_operand:SI 3 "acc1_operand" ""))]
1692   "TARGET_MULMAC_32BY16_SET"
1693   "machlw%? 0, %0, %1"
1694   [(set_attr "length" "4,4,8")
1695    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1696    (set_attr "predicable" "no, no, yes")
1697    (set_attr "cond" "nocond, canuse_limm, canuse")])
1699 (define_insn "mulsi_600"
1700   [(set (match_operand:SI 2 "mlo_operand" "")
1701         (mult:SI (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c")
1702                  (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
1703    (clobber (match_operand:SI 3 "mhi_operand" ""))]
1704   "TARGET_MUL64_SET"
1705 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
1706 ; using a machine code pattern that only allows "L" constraint constants.
1707 ;  "mul64%? \t0, %0, %1%&"
1709   if (satisfies_constraint_I (operands[1])
1710       && !satisfies_constraint_L (operands[1]))
1711     {
1712       /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS  */
1713       int n = true_regnum (operands[0]);
1714       int i = INTVAL (operands[1]);
1715       asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
1716       asm_fprintf (asm_out_file, "\t.short %d`",
1717                    ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
1718       return "; mul64%? \t0, %0, %1%&";
1719     }
1720   return "mul64%? \t0, %0, %1%&";
1722   [(set_attr "length" "*,4,4,8")
1723    (set_attr "iscompact" "maybe,false,false,false")
1724    (set_attr "type" "multi,multi,multi,multi")
1725    (set_attr "predicable" "yes,yes,no,yes")
1726    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1728 ; If we compile without an mul option enabled, but link with libraries
1729 ; for a mul option, we'll see clobbers of multiplier output registers.
1730 ; There is also an implementation using norm that clobbers the loop registers.
1731 (define_insn "mulsi3_600_lib"
1732   [(set (reg:SI R0_REG)
1733         (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
1734    (clobber (reg:SI RETURN_ADDR_REGNUM))
1735    (clobber (reg:SI R1_REG))
1736    (clobber (reg:SI R2_REG))
1737    (clobber (reg:SI R3_REG))
1738    (clobber (reg:DI MUL64_OUT_REG))
1739    (clobber (reg:SI LP_COUNT))
1740    (clobber (reg:SI LP_START))
1741    (clobber (reg:SI LP_END))
1742    (clobber (reg:CC CC_REG))]
1743   "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
1744    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
1745    && SFUNC_CHECK_PREDICABLE"
1746   "*return arc_output_libcall (\"__mulsi3\");"
1747   [(set_attr "is_sfunc" "yes")
1748    (set_attr "predicable" "yes")])
1750 (define_insn "mulsidi_600"
1751   [(set (reg:DI MUL64_OUT_REG)
1752         (mult:DI (sign_extend:DI
1753                    (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c"))
1754                  (sign_extend:DI
1755 ; assembler issue for "I", see mulsi_600
1756 ;                  (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,Cal"))))]
1757                    (match_operand:SI 1 "register_operand" "Rcq#q,cL,L,C32"))))]
1758   "TARGET_MUL64_SET"
1759   "mul64%? \t0, %0, %1%&"
1760   [(set_attr "length" "*,4,4,8")
1761    (set_attr "iscompact" "maybe,false,false,false")
1762    (set_attr "type" "multi,multi,multi,multi")
1763    (set_attr "predicable" "yes,yes,no,yes")
1764    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1766 (define_insn "umulsidi_600"
1767   [(set (reg:DI MUL64_OUT_REG)
1768         (mult:DI (zero_extend:DI
1769                    (match_operand:SI 0 "register_operand"  "c,c,%c"))
1770                  (sign_extend:DI
1771 ; assembler issue for "I", see mulsi_600
1772 ;                  (match_operand:SI 1 "register_operand" "cL,I,Cal"))))]
1773                    (match_operand:SI 1 "register_operand" "cL,L,C32"))))]
1774   "TARGET_MUL64_SET"
1775   "mulu64%? \t0, %0, %1%&"
1776   [(set_attr "length" "4,4,8")
1777    (set_attr "iscompact" "false")
1778    (set_attr "type" "umulti")
1779    (set_attr "predicable" "yes,no,yes")
1780    (set_attr "cond" "canuse,canuse_limm,canuse")])
1782 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
1783 ; may not be used as destination constraint.
1785 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
1786 ; but mpyu is faster for the standard multiplier.
1787 ; Note: we must make sure LP_COUNT is not one of the destination
1788 ; registers, since it cannot be the destination of a multi-cycle insn
1789 ; like MPY or MPYU.
1790 (define_insn "mulsi3_700"
1791  [(set (match_operand:SI 0 "mpy_dest_reg_operand"        "=Rcr,r,r,Rcr,r")
1792         (mult:SI (match_operand:SI 1 "register_operand"  " 0,c,0,0,c")
1793                  (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
1794 "TARGET_ARC700 && !TARGET_NOMPY_SET"
1795   "mpyu%? %0,%1,%2"
1796   [(set_attr "length" "4,4,4,8,8")
1797    (set_attr "type" "umulti")
1798    (set_attr "predicable" "yes,no,no,yes,no")
1799    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
1801 (define_expand "mulsidi3"
1802   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1803         (mult:DI (sign_extend:DI(match_operand:SI 1 "register_operand" ""))
1804                  (sign_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
1805   "(TARGET_ARC700 && !TARGET_NOMPY_SET)
1806    || TARGET_MUL64_SET
1807    || TARGET_MULMAC_32BY16_SET"
1810   if (TARGET_ARC700 && !TARGET_NOMPY_SET)
1811     {
1812       operands[2] = force_reg (SImode, operands[2]);
1813       if (!register_operand (operands[0], DImode))
1814         {
1815           rtx result = gen_reg_rtx (DImode);
1817           operands[2] = force_reg (SImode, operands[2]);
1818           emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
1819           emit_move_insn (operands[0], result);
1820           DONE;
1821         }
1822     }
1823   else if (TARGET_MUL64_SET)
1824     {
1825       operands[2] = force_reg (SImode, operands[2]);
1826       emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
1827       emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
1828       DONE;
1829     }
1830   else if (TARGET_MULMAC_32BY16_SET)
1831     {
1832       rtx result_hi = gen_highpart(SImode, operands[0]);
1833       rtx result_low = gen_lowpart(SImode, operands[0]);
1835       emit_insn (gen_mul64_600 (operands[1], operands[2]));
1836       emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
1837       emit_move_insn (result_low, gen_acc2 ());
1838       DONE;
1839     }
1842 (define_insn "mul64_600"
1843   [(set (reg:DI 56)
1844         (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
1845                                   "c,c,c"))
1846                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
1847                                   "c,L,Cal")
1848                                   (const_int 16)
1849                                   (const_int 0))))
1850   ]
1851   "TARGET_MULMAC_32BY16_SET"
1852   "mullw%? 0, %0, %1"
1853   [(set_attr "length" "4,4,8")
1854    (set_attr "type" "mulmac_600")
1855    (set_attr "predicable" "no,no,yes")
1856    (set_attr "cond" "nocond, canuse_limm, canuse")])
1859 ;; ??? check if this is canonical rtl
1860 (define_insn "mac64_600"
1861   [(set (reg:DI 56)
1862         (plus:DI
1863           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
1864                    (ashift:DI
1865                      (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
1866                                       (const_int 16) (const_int 16))
1867                      (const_int 16)))
1868           (reg:DI 56)))
1869    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1870         (zero_extract:SI
1871           (plus:DI
1872             (mult:DI (sign_extend:DI (match_dup 1))
1873                      (ashift:DI
1874                        (sign_extract:DI (match_dup 2)
1875                                         (const_int 16) (const_int 16))
1876                           (const_int 16)))
1877             (reg:DI 56))
1878           (const_int 32) (const_int 32)))]
1879   "TARGET_MULMAC_32BY16_SET"
1880   "machlw%? %0, %1, %2"
1881   [(set_attr "length" "4,4,8")
1882    (set_attr "type" "mulmac_600")
1883    (set_attr "predicable" "no,no,yes")
1884    (set_attr "cond" "nocond, canuse_limm, canuse")])
1887 ;; DI <- DI(signed SI) * DI(signed SI)
1888 (define_insn_and_split "mulsidi3_700"
1889   [(set (match_operand:DI 0 "register_operand" "=&r")
1890         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
1891                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
1892   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1893   "#"
1894   "&& reload_completed"
1895   [(const_int 0)]
1897   int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1898   int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1899   rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
1900   rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
1901   emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
1902   emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
1903   DONE;
1905   [(set_attr "type" "multi")
1906    (set_attr "length" "8")])
1908 (define_insn "mulsi3_highpart"
1909   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
1910         (truncate:SI
1911          (lshiftrt:DI
1912           (mult:DI
1913            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
1914            (sign_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
1915           (const_int 32))))]
1916   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1917   "mpyh%? %0,%1,%2"
1918   [(set_attr "length" "4,4,8,8")
1919    (set_attr "type" "multi")
1920    (set_attr "predicable" "yes,no,yes,no")
1921    (set_attr "cond" "canuse,nocond,canuse,nocond")])
1923 ; Note that mpyhu has the same latency as mpy / mpyh,
1924 ; thus we use the type multi.
1925 (define_insn "*umulsi3_highpart_i"
1926   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
1927         (truncate:SI
1928          (lshiftrt:DI
1929           (mult:DI
1930            (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
1931            (zero_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
1932           (const_int 32))))]
1933   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1934   "mpyhu%? %0,%1,%2"
1935   [(set_attr "length" "4,4,8,8")
1936    (set_attr "type" "multi")
1937    (set_attr "predicable" "yes,no,yes,no")
1938    (set_attr "cond" "canuse,nocond,canuse,nocond")])
1940 ; Implementations include additional labels for umulsidi3, so we got all
1941 ; the same clobbers - plus one for the result low part.  */
1942 (define_insn "umulsi3_highpart_600_lib_le"
1943   [(set (reg:SI R1_REG)
1944         (truncate:SI
1945          (lshiftrt:DI
1946           (mult:DI (zero_extend:DI (reg:SI R0_REG))
1947                    (zero_extend:DI (reg:SI R1_REG)))
1948           (const_int 32))))
1949    (clobber (reg:SI RETURN_ADDR_REGNUM))
1950    (clobber (reg:SI R0_REG))
1951    (clobber (reg:DI R2_REG))
1952    (clobber (reg:SI R12_REG))
1953    (clobber (reg:DI MUL64_OUT_REG))
1954    (clobber (reg:CC CC_REG))]
1955   "!TARGET_BIG_ENDIAN
1956    && !TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
1957    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
1958    && SFUNC_CHECK_PREDICABLE"
1959   "*return arc_output_libcall (\"__umulsi3_highpart\");"
1960   [(set_attr "is_sfunc" "yes")
1961    (set_attr "predicable" "yes")])
1963 (define_insn "umulsi3_highpart_600_lib_be"
1964   [(set (reg:SI R0_REG)
1965         (truncate:SI
1966          (lshiftrt:DI
1967           (mult:DI (zero_extend:DI (reg:SI R0_REG))
1968                    (zero_extend:DI (reg:SI R1_REG)))
1969           (const_int 32))))
1970    (clobber (reg:SI RETURN_ADDR_REGNUM))
1971    (clobber (reg:SI R1_REG))
1972    (clobber (reg:DI R2_REG))
1973    (clobber (reg:SI R12_REG))
1974    (clobber (reg:DI MUL64_OUT_REG))
1975    (clobber (reg:CC CC_REG))]
1976   "TARGET_BIG_ENDIAN
1977    && !TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
1978    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
1979    && SFUNC_CHECK_PREDICABLE"
1980   "*return arc_output_libcall (\"__umulsi3_highpart\");"
1981   [(set_attr "is_sfunc" "yes")
1982    (set_attr "predicable" "yes")])
1984 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
1985 ;; need a separate pattern for immediates
1986 ;; ??? This is fine for combine, but not for reload.
1987 (define_insn "umulsi3_highpart_int"
1988   [(set (match_operand:SI 0 "register_operand"            "=Rcr, r, r,Rcr,  r")
1989         (truncate:SI
1990          (lshiftrt:DI
1991           (mult:DI
1992            (zero_extend:DI (match_operand:SI 1 "register_operand"  " 0, c, 0,  0,  c"))
1993            (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
1994           (const_int 32))))]
1995   "TARGET_ARC700 && !TARGET_NOMPY_SET"
1996   "mpyhu%? %0,%1,%2"
1997   [(set_attr "length" "4,4,4,8,8")
1998    (set_attr "type" "multi")
1999    (set_attr "predicable" "yes,no,no,yes,no")
2000    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2002 (define_expand "umulsi3_highpart"
2003   [(set (match_operand:SI 0 "general_operand"  "")
2004         (truncate:SI
2005          (lshiftrt:DI
2006           (mult:DI
2007            (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2008            (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2009           (const_int 32))))]
2010   "TARGET_ARC700 || (!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET)"
2011   "
2013   rtx target = operands[0];
2015   if (!TARGET_ARC700 || TARGET_NOMPY_SET)
2016     {
2017       emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2018       emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2019       if (TARGET_BIG_ENDIAN)
2020         emit_insn (gen_umulsi3_highpart_600_lib_be ());
2021       else
2022         emit_insn (gen_umulsi3_highpart_600_lib_le ());
2023       emit_move_insn (target, gen_rtx_REG (SImode, 0));
2024       DONE;
2025     }
2027   if (!register_operand (target, SImode))
2028     target = gen_reg_rtx (SImode);
2030   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2031     operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2032                                                   operands[2], SImode);
2033   else if (!immediate_operand (operands[2], SImode))
2034     operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2035   emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2036   if (target != operands[0])
2037     emit_move_insn (operands[0], target);
2038   DONE;
2041 (define_expand "umulsidi3"
2042   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043         (mult:DI (zero_extend:DI(match_operand:SI 1 "register_operand" ""))
2044                  (zero_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2045   ""
2047   if (TARGET_ARC700 && !TARGET_NOMPY_SET)
2048     {
2049       operands[2] = force_reg (SImode, operands[2]);
2050       if (!register_operand (operands[0], DImode))
2051         {
2052           rtx result = gen_reg_rtx (DImode);
2054           emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2055           emit_move_insn (operands[0], result);
2056           DONE;
2057         }
2058     }
2059   else if (TARGET_MUL64_SET)
2060     {
2061       operands[2] = force_reg (SImode, operands[2]);
2062       emit_insn (gen_umulsidi_600 (operands[1], operands[2]));
2063       emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2064       DONE;
2065     }
2066   else if (TARGET_MULMAC_32BY16_SET)
2067     {
2068       rtx result_hi = gen_reg_rtx (SImode);
2069       rtx result_low = gen_reg_rtx (SImode);
2071       result_hi = gen_highpart(SImode , operands[0]);
2072       result_low = gen_lowpart(SImode , operands[0]);
2074       emit_insn (gen_umul64_600 (operands[1], operands[2]));
2075       emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2076       emit_move_insn (result_low, gen_acc2 ());
2077       DONE;
2078     }
2079   else
2080     {
2081       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2082       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2083       emit_insn (gen_umulsidi3_600_lib ());
2084       emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2085       DONE;
2086     }
2089 (define_insn "umul64_600"
2090   [(set (reg:DI 56)
2091         (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2092                                   "c,c,c"))
2093                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2094                                   "c,L,Cal")
2095                                   (const_int 16)
2096                                   (const_int 0))))
2097   ]
2098   "TARGET_MULMAC_32BY16_SET"
2099   "@mululw 0, %0, %1
2100     mululw 0, %0, %1
2101     mululw%? 0, %1, %0"
2102   [(set_attr "length" "4,4,8")
2103    (set_attr "type" "mulmac_600")
2104    (set_attr "predicable" "no,no,yes")
2105    (set_attr "cond" "nocond, canuse_limm, canuse")])
2108 (define_insn "umac64_600"
2109   [(set (reg:DI 56)
2110         (plus:DI
2111           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2112                    (ashift:DI
2113                      (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2114                                       (const_int 16) (const_int 16))
2115                      (const_int 16)))
2116           (reg:DI 56)))
2117    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2118         (zero_extract:SI
2119           (plus:DI
2120             (mult:DI (zero_extend:DI (match_dup 1))
2121                      (ashift:DI
2122                        (zero_extract:DI (match_dup 2)
2123                                         (const_int 16) (const_int 16))
2124                           (const_int 16)))
2125             (reg:DI 56))
2126           (const_int 32) (const_int 32)))]
2127   "TARGET_MULMAC_32BY16_SET"
2128   "machulw%? %0, %1, %2"
2129   [(set_attr "length" "4,4,8")
2130    (set_attr "type" "mulmac_600")
2131    (set_attr "predicable" "no,no,yes")
2132    (set_attr "cond" "nocond, canuse_limm, canuse")])
2136 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2137 (define_insn_and_split "umulsidi3_700"
2138   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2139         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2140                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2141   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2142   "#"
2143   "reload_completed"
2144   [(const_int 0)]
2146   int hi = !TARGET_BIG_ENDIAN;
2147   int lo = !hi;
2148   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2149   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2150   emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2151   emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
2152   DONE;
2154   [(set_attr "type" "umulti")
2155   (set_attr "length" "8")])
2157 (define_insn "umulsidi3_600_lib"
2158   [(set (reg:DI R0_REG)
2159         (mult:DI (zero_extend:DI (reg:SI R0_REG))
2160                  (zero_extend:DI (reg:SI R1_REG))))
2161    (clobber (reg:SI RETURN_ADDR_REGNUM))
2162    (clobber (reg:DI R2_REG))
2163    (clobber (reg:SI R12_REG))
2164    (clobber (reg:DI MUL64_OUT_REG))
2165    (clobber (reg:CC CC_REG))]
2166    "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
2167    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
2168    && SFUNC_CHECK_PREDICABLE"
2169   "*return arc_output_libcall (\"__umulsidi3\");"
2170   [(set_attr "is_sfunc" "yes")
2171    (set_attr "predicable" "yes")])
2173 (define_peephole2
2174   [(parallel
2175      [(set (reg:DI R0_REG)
2176            (mult:DI (zero_extend:DI (reg:SI R0_REG))
2177                     (zero_extend:DI (reg:SI R1_REG))))
2178       (clobber (reg:SI RETURN_ADDR_REGNUM))
2179       (clobber (reg:DI R2_REG))
2180       (clobber (reg:SI R12_REG))
2181       (clobber (reg:DI MUL64_OUT_REG))
2182       (clobber (reg:CC CC_REG))])]
2183   "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET
2184    && (!TARGET_ARC700 || TARGET_NOMPY_SET)
2185    && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2186   [(pc)]
2188   if (TARGET_BIG_ENDIAN)
2189     emit_insn (gen_umulsi3_highpart_600_lib_be ());
2190   else
2191     emit_insn (gen_umulsi3_highpart_600_lib_le ());
2192   DONE;
2195 (define_expand "addsi3"
2196   [(set (match_operand:SI 0 "dest_reg_operand" "")
2197         (plus:SI (match_operand:SI 1 "register_operand" "")
2198                  (match_operand:SI 2 "nonmemory_operand" "")))]
2199   ""
2200   "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2201      {
2202        operands[2]=force_reg(SImode, operands[2]);
2203      }
2204   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2205    {
2206       operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2207    }
2209   ")
2211 (define_expand "adddi3"
2212   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2213                    (plus:DI (match_operand:DI 1 "register_operand" "")
2214                             (match_operand:DI 2 "nonmemory_operand" "")))
2215               (clobber (reg:CC CC_REG))])]
2216   ""
2218   if (TARGET_EXPAND_ADDDI)
2219     {
2220       rtx l0 = gen_lowpart (SImode, operands[0]);
2221       rtx h0 = disi_highpart (operands[0]);
2222       rtx l1 = gen_lowpart (SImode, operands[1]);
2223       rtx h1 = disi_highpart (operands[1]);
2224       rtx l2 = gen_lowpart (SImode, operands[2]);
2225       rtx h2 = disi_highpart (operands[2]);
2226       rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2228       if (CONST_INT_P (h2) && INTVAL (h2) < 0 && SIGNED_INT12 (INTVAL (h2)))
2229         {
2230           emit_insn (gen_sub_f (l0, l1, gen_int_mode (-INTVAL (l2), SImode)));
2231           emit_insn (gen_sbc (h0, h1,
2232                               gen_int_mode (-INTVAL (h2) - (l1 != 0), SImode),
2233                               cc_c));
2234           DONE;
2235         }
2236       emit_insn (gen_add_f (l0, l1, l2));
2237       emit_insn (gen_adc (h0, h1, h2));
2238       DONE;
2239     }
2242 ; This assumes that there can be no strictly partial overlap between
2243 ; operands[1] and operands[2].
2244 (define_insn_and_split "*adddi3_i"
2245   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2246         (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2247                  (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2248    (clobber (reg:CC CC_REG))]
2249   ""
2250   "#"
2251   "reload_completed"
2252   [(const_int 0)]
2254   int hi = !TARGET_BIG_ENDIAN;
2255   int lo = !hi;
2256   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2257   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2258   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2259   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2260   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2261   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2264   if (l2 == const0_rtx)
2265     {
2266       if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2267         emit_move_insn (l0, l1);
2268       emit_insn (gen_addsi3 (h0, h1, h2));
2269       if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2270         emit_move_insn (l0, l1);
2271       DONE;
2272     }
2273   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2274       && INTVAL (operands[2]) >= -0x7fffffff)
2275     {
2276       emit_insn (gen_subdi3_i (operands[0], operands[1],
2277                  GEN_INT (-INTVAL (operands[2]))));
2278       DONE;
2279     }
2280   if (rtx_equal_p (l0, h1))
2281     {
2282       if (h2 != const0_rtx)
2283         emit_insn (gen_addsi3 (h0, h1, h2));
2284       else if (!rtx_equal_p (h0, h1))
2285         emit_move_insn (h0, h1);
2286       emit_insn (gen_add_f (l0, l1, l2));
2287       emit_insn
2288         (gen_rtx_COND_EXEC
2289           (VOIDmode,
2290            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2291            gen_rtx_SET (VOIDmode, h0, plus_constant (SImode, h0, 1))));
2292       DONE;
2293     }
2294   emit_insn (gen_add_f (l0, l1, l2));
2295   emit_insn (gen_adc (h0, h1, h2));
2296   DONE;
2298   [(set_attr "cond" "clob")
2299    (set_attr "type" "binary")
2300    (set_attr "length" "16,16,20")])
2302 (define_insn "add_f"
2303   [(set (reg:CC_C CC_REG)
2304         (compare:CC_C
2305           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2306                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2307           (match_dup 1)))
2308    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2309         (plus:SI (match_dup 1) (match_dup 2)))]
2310   ""
2311   "add.f %0,%1,%2"
2312   [(set_attr "cond" "set")
2313    (set_attr "type" "compare")
2314    (set_attr "length" "4,4,8")])
2316 (define_insn "*add_f_2"
2317   [(set (reg:CC_C CC_REG)
2318         (compare:CC_C
2319           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2320                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2321           (match_dup 2)))
2322    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2323         (plus:SI (match_dup 1) (match_dup 2)))]
2324   ""
2325   "add.f %0,%1,%2"
2326   [(set_attr "cond" "set")
2327    (set_attr "type" "compare")
2328    (set_attr "length" "4,4,8")])
2330 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2331 ; needlessly prioritizing the matching constraint.
2332 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2333 ; execution is used where possible.
2334 (define_insn_and_split "adc"
2335   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2336         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2337                           (match_operand:SI 1 "nonmemory_operand"
2338                                                          "%c,0,c,0,cCal"))
2339                  (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2340   "register_operand (operands[1], SImode)
2341    || register_operand (operands[2], SImode)"
2342   "@
2343         adc %0,%1,%2
2344         add.cs %0,%1,1
2345         adc %0,%1,%2
2346         adc %0,%1,%2
2347         adc %0,%1,%2"
2348   ; if we have a bad schedule after sched2, split.
2349   "reload_completed
2350    && !optimize_size && TARGET_ARC700
2351    && arc_scheduling_not_expected ()
2352    && arc_sets_cc_p (prev_nonnote_insn (insn))
2353    /* If next comes a return or other insn that needs a delay slot,
2354       expect the adc to get into the delay slot.  */
2355    && next_nonnote_insn (insn)
2356    && !arc_need_delay (next_nonnote_insn (insn))
2357    /* Restore operands before emitting.  */
2358    && (extract_insn_cached (insn), 1)"
2359   [(set (match_dup 0) (match_dup 3))
2360    (cond_exec
2361      (ltu (reg:CC_C CC_REG) (const_int 0))
2362      (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2363   "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2364   [(set_attr "cond" "use")
2365    (set_attr "type" "cc_arith")
2366    (set_attr "length" "4,4,4,4,8")])
2368 ; combiner-splitter cmp / scc -> cmp / adc
2369 (define_split
2370   [(set (match_operand:SI 0 "dest_reg_operand" "")
2371         (gtu:SI (match_operand:SI 1 "register_operand" "")
2372                 (match_operand:SI 2 "register_operand" "")))
2373    (clobber (reg CC_REG))]
2374   ""
2375   [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2376    (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2378 ; combine won't work when an intermediate result is used later...
2379 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2380 (define_peephole2
2381   [(set (match_operand:SI 0 "dest_reg_operand" "")
2382         (plus:SI (match_operand:SI 1 "register_operand" "")
2383                  (match_operand:SI 2 "nonmemory_operand" "")))
2384    (set (reg:CC_C CC_REG)
2385         (compare:CC_C (match_dup 0)
2386                       (match_operand:SI 3 "nonmemory_operand" "")))]
2387   "rtx_equal_p (operands[1], operands[3])
2388    || rtx_equal_p (operands[2], operands[3])"
2389   [(parallel
2390      [(set (reg:CC_C CC_REG)
2391            (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2392       (set (match_dup 0)
2393            (plus:SI (match_dup 1) (match_dup 2)))])])
2395 ; ??? need to delve into combine to find out why this is not useful.
2396 ; We'd like to be able to grok various C idioms for carry bit usage.
2397 ;(define_insn "*adc_0"
2398 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2399 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2400 ;                (match_operand:SI 1 "register_operand" "c")))]
2401 ;  ""
2402 ;  "adc %0,%1,0"
2403 ;  [(set_attr "cond" "use")
2404 ;   (set_attr "type" "cc_arith")
2405 ;   (set_attr "length" "4")])
2407 ;(define_split
2408 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2409 ;       (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2410 ;                        (match_operand:SI 2 "register_operand" "c"))
2411 ;                (match_operand:SI 3 "register_operand" "c")))
2412 ;   (clobber (reg CC_REG))]
2413 ;  ""
2414 ;  [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2415 ;   (set (match_dup 0)
2416 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2417 ;                (match_dup 3)))])
2419 (define_expand "subsi3"
2420   [(set (match_operand:SI 0 "dest_reg_operand" "")
2421         (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2422                  (match_operand:SI 2 "nonmemory_operand" "")))]
2423   ""
2424   "
2426   int c = 1;
2428   if (!register_operand (operands[2], SImode))
2429     {
2430       operands[1] = force_reg (SImode, operands[1]);
2431       c = 2;
2432     }
2433   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2434     operands[c] = force_reg (SImode, operands[c]);
2435   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2436       operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2439 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2440 ; combine should make such an insn go away.
2441 (define_insn_and_split "subsi3_insn"
2442   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcw,Rcw,w,w,w,  w,  w,  w")
2443         (minus:SI (match_operand:SI 1 "nonmemory_operand"   "0,  0, cL,c,L,I,Cal,Cal,  c")
2444                   (match_operand:SI 2 "nonmemory_operand" "Rcqq, c,  0,c,c,0,  0,  c,Cal")))]
2445   "register_operand (operands[1], SImode)
2446    || register_operand (operands[2], SImode)"
2447   "@
2448     sub%? %0,%1,%2%&
2449     sub%? %0,%1,%2
2450     rsub%? %0,%2,%1
2451     sub %0,%1,%2
2452     rsub %0,%2,%1
2453     rsub %0,%2,%1
2454     rsub%? %0,%2,%1
2455     rsub %0,%2,%1
2456     sub %0,%1,%2"
2457   "reload_completed && get_attr_length (insn) == 8
2458    && satisfies_constraint_I (operands[1])
2459    && GET_CODE (PATTERN (insn)) != COND_EXEC"
2460   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2461   "split_subsi (operands);"
2462   [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false")
2463   (set_attr "length" "*,4,4,4,4,4,8,8,8")
2464   (set_attr "predicable" "yes,yes,yes,no,no,no,yes,no,no")
2465   (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2467 (define_expand "subdi3"
2468   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2469                    (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2470                              (match_operand:DI 2 "nonmemory_operand" "")))
2471               (clobber (reg:CC CC_REG))])]
2472   ""
2474   if (!register_operand (operands[2], DImode))
2475     operands[1] = force_reg (DImode, operands[1]);
2476   if (TARGET_EXPAND_ADDDI)
2477     {
2478       rtx l0 = gen_lowpart (SImode, operands[0]);
2479       rtx h0 = disi_highpart (operands[0]);
2480       rtx l1 = gen_lowpart (SImode, operands[1]);
2481       rtx h1 = disi_highpart (operands[1]);
2482       rtx l2 = gen_lowpart (SImode, operands[2]);
2483       rtx h2 = disi_highpart (operands[2]);
2484       rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2486       emit_insn (gen_sub_f (l0, l1, l2));
2487       emit_insn (gen_sbc (h0, h1, h2, cc_c));
2488       DONE;
2489     }
2492 (define_insn_and_split "subdi3_i"
2493   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2494         (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2495                   (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2496    (clobber (reg:CC CC_REG))]
2497   "register_operand (operands[1], DImode)
2498    || register_operand (operands[2], DImode)"
2499   "#"
2500   "reload_completed"
2501   [(const_int 0)]
2503   int hi = !TARGET_BIG_ENDIAN;
2504   int lo = !hi;
2505   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2506   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2507   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2508   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2509   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2510   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2512   if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2513     {
2514       h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2515       if (!rtx_equal_p (h0, h1))
2516         emit_insn (gen_rtx_SET (VOIDmode, h0, h1));
2517       emit_insn (gen_sub_f (l0, l1, l2));
2518       emit_insn
2519         (gen_rtx_COND_EXEC
2520           (VOIDmode,
2521            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2522            gen_rtx_SET (VOIDmode, h0, plus_constant (SImode, h0, -1))));
2523       DONE;
2524     }
2525   emit_insn (gen_sub_f (l0, l1, l2));
2526   emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2527   DONE;
2529   [(set_attr "cond" "clob")
2530    (set_attr "length" "16,16,16,20,20")])
2532 (define_insn "*sbc_0"
2533   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2534         (minus:SI (match_operand:SI 1 "register_operand" "c")
2535                   (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2536                           (const_int 0))))]
2537   ""
2538   "sbc %0,%1,0"
2539   [(set_attr "cond" "use")
2540    (set_attr "type" "cc_arith")
2541    (set_attr "length" "4")])
2543 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2544 ; needlessly prioritizing the matching constraint.
2545 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2546 ; is used where possible.
2547 (define_insn_and_split "sbc"
2548   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2549         (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2550                                                 "c,0,c,0,cCal")
2551                             (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2552                                     (const_int 0)))
2553                   (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2554   "register_operand (operands[1], SImode)
2555    || register_operand (operands[2], SImode)"
2556   "@
2557         sbc %0,%1,%2
2558         sub.cs %0,%1,1
2559         sbc %0,%1,%2
2560         sbc %0,%1,%2
2561         sbc %0,%1,%2"
2562   ; if we have a bad schedule after sched2, split.
2563   "reload_completed
2564    && !optimize_size && TARGET_ARC700
2565    && arc_scheduling_not_expected ()
2566    && arc_sets_cc_p (prev_nonnote_insn (insn))
2567    /* If next comes a return or other insn that needs a delay slot,
2568       expect the adc to get into the delay slot.  */
2569    && next_nonnote_insn (insn)
2570    && !arc_need_delay (next_nonnote_insn (insn))
2571    /* Restore operands before emitting.  */
2572    && (extract_insn_cached (insn), 1)"
2573   [(set (match_dup 0) (match_dup 4))
2574    (cond_exec
2575      (ltu (reg:CC_C CC_REG) (const_int 0))
2576      (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2577   "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2578   [(set_attr "cond" "use")
2579    (set_attr "type" "cc_arith")
2580    (set_attr "length" "4,4,4,4,8")])
2582 (define_insn "sub_f"
2583   [(set (reg:CC CC_REG)
2584         (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2585                     (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2586    (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2587         (minus:SI (match_dup 1) (match_dup 2)))]
2588   "register_operand (operands[1], SImode)
2589    || register_operand (operands[2], SImode)"
2590   "@
2591         sub.f %0,%1,%2
2592         rsub.f %0,%2,%1
2593         sub.f %0,%1,%2
2594         rsub.f %0,%2,%1
2595         sub.f %0,%1,%2
2596         sub.f %0,%1,%2"
2597   [(set_attr "type" "compare")
2598    (set_attr "length" "4,4,4,4,8,8")])
2600 ; combine won't work when an intermediate result is used later...
2601 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2602 (define_peephole2
2603   [(set (reg:CC CC_REG)
2604         (compare:CC (match_operand:SI 1 "register_operand" "")
2605                     (match_operand:SI 2 "nonmemory_operand" "")))
2606    (set (match_operand:SI 0 "dest_reg_operand" "")
2607         (minus:SI (match_dup 1) (match_dup 2)))]
2608   ""
2609   [(parallel
2610      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2611       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
2613 (define_peephole2
2614   [(set (reg:CC CC_REG)
2615         (compare:CC (match_operand:SI 1 "register_operand" "")
2616                     (match_operand:SI 2 "nonmemory_operand" "")))
2617    (set (match_operand 3 "" "") (match_operand 4 "" ""))
2618    (set (match_operand:SI 0 "dest_reg_operand" "")
2619         (minus:SI (match_dup 1) (match_dup 2)))]
2620   "!reg_overlap_mentioned_p (operands[3], operands[1])
2621    && !reg_overlap_mentioned_p (operands[3], operands[2])
2622    && !reg_overlap_mentioned_p (operands[0], operands[4])
2623    && !reg_overlap_mentioned_p (operands[0], operands[3])"
2624   [(parallel
2625      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2626       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2627    (set (match_dup 3) (match_dup 4))])
2629 (define_insn "*add_n"
2630   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
2631         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
2632                           (match_operand:SI 2 "_2_4_8_operand" ""))
2633                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
2634   ""
2635   "add%z2%? %0,%3,%1%&"
2636   [(set_attr "type" "shift")
2637    (set_attr "length" "*,4,4,8,4,8")
2638    (set_attr "predicable" "yes,yes,no,no,no,no")
2639    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
2640    (set_attr "iscompact" "maybe,false,false,false,false,false")])
2642 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
2643 ;; what synth_mult likes.
2644 (define_insn "*sub_n"
2645   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2646         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
2647                   (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
2648                            (match_operand:SI 3 "_2_4_8_operand" ""))))]
2649   ""
2650   "sub%z3%? %0,%1,%2"
2651   [(set_attr "type" "shift")
2652    (set_attr "length" "4,4,8")
2653    (set_attr "predicable" "yes,no,no")
2654    (set_attr "cond" "canuse,nocond,nocond")
2655    (set_attr "iscompact" "false")])
2657 ; ??? check if combine matches this.
2658 (define_insn "*bset"
2659   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2660         (ior:SI (ashift:SI (const_int 1)
2661                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2662                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2663   ""
2664   "bset%? %0,%2,%1"
2665   [(set_attr "length" "4,4,8")
2666    (set_attr "predicable" "yes,no,no")
2667    (set_attr "cond" "canuse,nocond,nocond")]
2670 ; ??? check if combine matches this.
2671 (define_insn "*bxor"
2672   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2673         (xor:SI (ashift:SI (const_int 1)
2674                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2675                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2676   ""
2677   "bxor%? %0,%2,%1"
2678   [(set_attr "length" "4,4,8")
2679    (set_attr "predicable" "yes,no,no")
2680    (set_attr "cond" "canuse,nocond,nocond")]
2683 ; ??? check if combine matches this.
2684 (define_insn "*bclr"
2685   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2686         (and:SI (not:SI (ashift:SI (const_int 1)
2687                                    (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
2688                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2689   ""
2690   "bclr%? %0,%2,%1"
2691   [(set_attr "length" "4,4,8")
2692    (set_attr "predicable" "yes,no,no")
2693    (set_attr "cond" "canuse,nocond,nocond")]
2696 ; ??? FIXME: find combine patterns for bmsk.
2698 ;;Following are the define_insns added for the purpose of peephole2's
2700 ; see also iorsi3 for use with constant bit number.
2701 (define_insn "*bset_insn"
2702   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2703         (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2704                 (ashift:SI (const_int 1)
2705                            (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2706   ""
2707   "@
2708      bset%? %0,%1,%2 ;;peep2, constr 1
2709      bset %0,%1,%2 ;;peep2, constr 2
2710      bset %0,%S1,%2 ;;peep2, constr 3"
2711   [(set_attr "length" "4,4,8")
2712    (set_attr "predicable" "yes,no,no")
2713    (set_attr "cond" "canuse,nocond,nocond")]
2716 ; see also xorsi3 for use with constant bit number.
2717 (define_insn "*bxor_insn"
2718   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2719         (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2720                 (ashift:SI (const_int 1)
2721                         (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2722   ""
2723   "@
2724      bxor%? %0,%1,%2
2725      bxor %0,%1,%2
2726      bxor %0,%S1,%2"
2727   [(set_attr "length" "4,4,8")
2728    (set_attr "predicable" "yes,no,no")
2729    (set_attr "cond" "canuse,nocond,nocond")]
2732 ; see also andsi3 for use with constant bit number.
2733 (define_insn "*bclr_insn"
2734   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2735         (and:SI (not:SI (ashift:SI (const_int 1)
2736                                    (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
2737                 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
2738   ""
2739   "@
2740      bclr%? %0,%1,%2
2741      bclr %0,%1,%2
2742      bclr %0,%S1,%2"
2743   [(set_attr "length" "4,4,8")
2744    (set_attr "predicable" "yes,no,no")
2745    (set_attr "cond" "canuse,nocond,nocond")]
2748 ; see also andsi3 for use with constant bit number.
2749 (define_insn "*bmsk_insn"
2750   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2751         (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2752                 (plus:SI (ashift:SI (const_int 1)
2753                                     (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
2754                                              (const_int 1)))
2755                          (const_int -1))))]
2756   ""
2757   "@
2758      bmsk%? %0,%S1,%2
2759      bmsk %0,%1,%2
2760      bmsk %0,%S1,%2"
2761   [(set_attr "length" "4,4,8")
2762    (set_attr "predicable" "yes,no,no")
2763    (set_attr "cond" "canuse,nocond,nocond")]
2766 ;;Instructions added for peephole2s end
2768 ;; Boolean instructions.
2770 (define_expand "andsi3"
2771   [(set (match_operand:SI 0 "dest_reg_operand" "")
2772         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2773                 (match_operand:SI 2 "nonmemory_operand" "")))]
2774   ""
2775   "if (!satisfies_constraint_Cux (operands[2]))
2776      operands[1] = force_reg (SImode, operands[1]);
2777    else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
2778      operands[1] = arc_rewrite_small_data (operands[1]);")
2780 (define_insn "andsi3_i"
2781   [(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")
2782         (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")
2783                 (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")))]
2784   "(register_operand (operands[1], SImode)
2785     && nonmemory_operand (operands[2], SImode))
2786    || (memory_operand (operands[1], SImode)
2787        && satisfies_constraint_Cux (operands[2]))"
2788   "*
2790   switch (which_alternative)
2791     {
2792     case 0: case 5: case 10: case 11: case 15: case 16: case 17:
2793       return \"and%? %0,%1,%2%&\";
2794     case 1: case 6:
2795       return \"and%? %0,%2,%1%&\";
2796     case 2: case 7: case 12:
2797       return \"bmsk%? %0,%1,%Z2%&\";
2798     case 3: case 8: case 13:
2799       return \"bclr%? %0,%1,%M2%&\";
2800     case 4:
2801       return (INTVAL (operands[2]) == 0xff
2802               ? \"extb%? %0,%1%&\" : \"extw%? %0,%1%&\");
2803     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
2804     case 18:
2805       if (TARGET_BIG_ENDIAN)
2806         {
2807           rtx xop[2];
2809           xop[0] = operands[0];
2810           xop[1] = adjust_address (operands[1], QImode,
2811                                    INTVAL (operands[2]) == 0xff ? 3 : 2);
2812           output_asm_insn (INTVAL (operands[2]) == 0xff
2813                            ? \"ldb %0,%1\" : \"ldw %0,%1\",
2814                            xop);
2815           return \"\";
2816         }
2817       return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ldw %0,%1\";
2818     default:
2819       gcc_unreachable ();
2820     }
2822   [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
2823    (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
2824    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
2825    (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no")
2826    (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2828 ; combiner splitter, pattern found in ldtoa.c .
2829 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
2830 (define_split
2831   [(set (reg:CC_Z CC_REG)
2832         (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
2833                               (match_operand 1 "const_int_operand" ""))
2834                       (match_operand 2 "const_int_operand" "")))
2835    (clobber (match_operand:SI 3 "register_operand" ""))]
2836   "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
2837   [(set (match_dup 3)
2838         (plus:SI (match_dup 0) (match_dup 4)))
2839    (set (reg:CC_Z CC_REG)
2840         (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
2841                       (const_int 0)))]
2842   "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
2844 ;;bic define_insn that allows limm to be the first operand
2845 (define_insn "*bicsi3_insn"
2846    [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
2847         (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
2848                 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
2849   ""
2850   "@
2851    bic%? %0, %2, %1%& ;;constraint 0
2852    bic%? %0,%2,%1  ;;constraint 1
2853    bic %0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
2854    bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
2855    bic %0,%2,%1    ;;constraint 4
2856    bic %0,%2,%S1   ;;constraint 5, FIXME: will it ever get generated ???
2857    bic %0,%S2,%1   ;;constraint 6"
2858   [(set_attr "length" "*,4,4,8,4,8,8")
2859   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
2860   (set_attr "predicable" "no,yes,no,yes,no,no,no")
2861   (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
2863 (define_insn "iorsi3"
2864   [(set (match_operand:SI 0 "dest_reg_operand"        "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w,  w,w,Rcw,  w")
2865         (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq,   0,  0,  c,  0, 0, c,  c,0,  0,  c")
2866                 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL,  0,C0p, I,cL,C0p,I,Cal,Cal")))]
2867   ""
2868   "*
2869   switch (which_alternative)
2870     {
2871     case 0: case 3: case 6: case 7: case 9: case 10: case 11:
2872       return \"or%? %0,%1,%2%&\";
2873     case 1: case 4:
2874       return \"or%? %0,%2,%1%&\";
2875     case 2: case 5: case 8:
2876       return \"bset%? %0,%1,%z2%&\";
2877     default:
2878       gcc_unreachable ();
2879     }"
2880   [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
2881    (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
2882    (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
2883    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
2885 (define_insn "xorsi3"
2886   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w,  w,w,  w,  w")
2887         (xor:SI (match_operand:SI 1 "register_operand"  "%0,   Rcq,  0,  c,  0,  0, c,  c,0,  0,  c")
2888                 (match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, cL,  0,C0p,  I,cL,C0p,I,Cal,Cal")))]
2889   ""
2890   "*
2891   switch (which_alternative)
2892     {
2893     case 0: case 2: case 5: case 6: case 8: case 9: case 10:
2894       return \"xor%? %0,%1,%2%&\";
2895     case 1: case 3:
2896       return \"xor%? %0,%2,%1%&\";
2897     case 4: case 7:
2898       return \"bxor%? %0,%1,%z2\";
2899     default:
2900       gcc_unreachable ();
2901     }
2902   "
2903   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
2904    (set_attr "type" "binary")
2905    (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
2906    (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
2907    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
2909 (define_insn "negsi2"
2910   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
2911         (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
2912   ""
2913   "neg%? %0,%1%&"
2914   [(set_attr "type" "unary")
2915    (set_attr "iscompact" "maybe,true,false,false")
2916    (set_attr "predicable" "no,no,yes,no")])
2918 (define_insn "one_cmplsi2"
2919   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
2920         (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
2921   ""
2922   "not%? %0,%1%&"
2923   [(set_attr "type" "unary,unary")
2924    (set_attr "iscompact" "true,false")])
2926 (define_insn_and_split "one_cmpldi2"
2927   [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
2928         (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
2929   ""
2930   "#"
2931   "&& reload_completed"
2932   [(set (match_dup 2) (not:SI (match_dup 3)))
2933    (set (match_dup 4) (not:SI (match_dup 5)))]
2935   int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
2937   operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
2938   operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
2939   operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
2940   operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
2942   [(set_attr "type" "unary,unary")
2943    (set_attr "cond" "nocond,nocond")
2944    (set_attr "length" "4,8")])
2946 ;; Shift instructions.
2948 (define_expand "ashlsi3"
2949   [(set (match_operand:SI 0 "dest_reg_operand" "")
2950         (ashift:SI (match_operand:SI 1 "register_operand" "")
2951                    (match_operand:SI 2 "nonmemory_operand" "")))]
2952   ""
2953   "
2955   if (!TARGET_BARREL_SHIFTER)
2956     {
2957       emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
2958       DONE;
2959     }
2962 (define_expand "ashrsi3"
2963   [(set (match_operand:SI 0 "dest_reg_operand" "")
2964         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2965                      (match_operand:SI 2 "nonmemory_operand" "")))]
2966   ""
2967   "
2969   if (!TARGET_BARREL_SHIFTER)
2970     {
2971       emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
2972       DONE;
2973     }
2976 (define_expand "lshrsi3"
2977   [(set (match_operand:SI 0 "dest_reg_operand" "")
2978         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2979                      (match_operand:SI 2 "nonmemory_operand" "")))]
2980   ""
2981   "
2983   if (!TARGET_BARREL_SHIFTER)
2984     {
2985       emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
2986       DONE;
2987     }
2990 (define_insn "shift_si3"
2991   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
2992         (match_operator:SI 3 "shift4_operator"
2993                            [(match_operand:SI 1 "register_operand" "0")
2994                             (match_operand:SI 2 "const_int_operand" "n")]))
2995    (clobber (match_scratch:SI 4 "=&r"))
2996    (clobber (reg:CC CC_REG))
2997   ]
2998   "!TARGET_BARREL_SHIFTER"
2999   "* return output_shift (operands);"
3000   [(set_attr "type" "shift")
3001    (set_attr "length" "16")])
3003 (define_insn "shift_si3_loop"
3004   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3005         (match_operator:SI 3 "shift_operator"
3006                            [(match_operand:SI 1 "register_operand" "0,0")
3007                             (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3008    (clobber (match_scratch:SI 4 "=X,X"))
3009    (clobber (reg:SI LP_COUNT))
3010    (clobber (reg:SI LP_START))
3011    (clobber (reg:SI LP_END))
3012    (clobber (reg:CC CC_REG))
3013   ]
3014   "!TARGET_BARREL_SHIFTER"
3015   "* return output_shift (operands);"
3016   [(set_attr "type" "shift")
3017    (set_attr "length" "16,20")])
3019 ; asl, asr, lsr patterns:
3020 ; There is no point in including an 'I' alternative since only the lowest 5
3021 ; bits are used for the shift.  OTOH Cal can be useful if the shift amount
3022 ; is defined in an external symbol, as we don't have special relocations
3023 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3024 ; provide one alternatice for this, without condexec support.
3025 (define_insn "*ashlsi3_insn"
3026   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3027         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3028                    (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3029   "TARGET_BARREL_SHIFTER
3030    && (register_operand (operands[1], SImode)
3031        || register_operand (operands[2], SImode))"
3032   "asl%? %0,%1,%2%&"
3033   [(set_attr "type" "shift")
3034    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3035    (set_attr "predicable" "no,no,no,yes,no,no")
3036    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3038 (define_insn "*ashrsi3_insn"
3039   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3040         (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3041                      (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3042   "TARGET_BARREL_SHIFTER
3043    && (register_operand (operands[1], SImode)
3044        || register_operand (operands[2], SImode))"
3045   "asr%? %0,%1,%2%&"
3046   [(set_attr "type" "shift")
3047    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3048    (set_attr "predicable" "no,no,no,yes,no,no")
3049    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3051 (define_insn "*lshrsi3_insn"
3052   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3053         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3054                      (match_operand:SI 2 "nonmemory_operand"  "N,  N,RcqqM, cL,cL,cCal")))]
3055   "TARGET_BARREL_SHIFTER
3056    && (register_operand (operands[1], SImode)
3057        || register_operand (operands[2], SImode))"
3058   "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3059             ?  \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3060   [(set_attr "type" "shift")
3061    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3062    (set_attr "predicable" "no,no,no,yes,no,no")
3063    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3065 (define_insn "rotrsi3"
3066   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
3067         (rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCal")
3068                      (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3069   "TARGET_BARREL_SHIFTER"
3070   "ror%? %0,%1,%2"
3071   [(set_attr "type" "shift,shift,shift")
3072    (set_attr "predicable" "yes,no,no")
3073    (set_attr "length" "4,4,8")])
3075 ;; Compare / branch instructions.
3077 (define_expand "cbranchsi4"
3078   [(set (reg:CC CC_REG)
3079         (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3080                     (match_operand:SI 2 "nonmemory_operand" "")))
3081    (set (pc)
3082         (if_then_else
3083               (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3084                                                                (const_int 0)])
3085               (label_ref (match_operand 3 "" ""))
3086               (pc)))]
3087   ""
3089   gcc_assert (XEXP (operands[0], 0) == operands[1]);
3090   gcc_assert (XEXP (operands[0], 1) == operands[2]);
3091   operands[0] = gen_compare_reg (operands[0], VOIDmode);
3092   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3093   DONE;
3096 ;; ??? Could add a peephole to generate compare with swapped operands and
3097 ;; modifed cc user if second, but not first operand is a compact register.
3098 (define_insn "cmpsi_cc_insn_mixed"
3099   [(set (reg:CC CC_REG)
3100         (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,c,c, qRcq, c")
3101                     (match_operand:SI 1 "nonmemory_operand" "cO,cI,cL,  Cal, Cal")))]
3102   ""
3103   "cmp%? %0,%B1%&"
3104   [(set_attr "type" "compare")
3105    (set_attr "iscompact" "true,false,false,true_limm,false")
3106    (set_attr "predicable" "no,no,yes,no,yes")
3107    (set_attr "cond" "set")
3108    (set_attr "length" "*,4,4,*,8")])
3110 (define_insn "*cmpsi_cc_zn_insn"
3111   [(set (reg:CC_ZN CC_REG)
3112         (compare:CC_ZN (match_operand:SI 0 "register_operand"  "qRcq,c")
3113                        (const_int 0)))]
3114   ""
3115   "tst%? %0,%0%&"
3116   [(set_attr "type" "compare,compare")
3117    (set_attr "iscompact" "true,false")
3118    (set_attr "predicable" "no,yes")
3119    (set_attr "cond" "set_zn")
3120    (set_attr "length" "*,4")])
3122 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3123 (define_insn "*btst"
3124   [(set (reg:CC_ZN CC_REG)
3125         (compare:CC_ZN
3126           (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3127                            (const_int 1)
3128                            (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3129           (const_int 0)))]
3130   ""
3131   "btst%? %0,%1"
3132   [(set_attr "iscompact" "true,false")
3133    (set_attr "predicable" "no,yes")
3134    (set_attr "cond" "set")
3135    (set_attr "type" "compare")
3136    (set_attr "length" "*,4")])
3138 ; combine suffers from 'simplifications' that replace a one-bit zero
3139 ; extract with a shift if it can prove that the upper bits are zero.
3140 ; arc_reorg sees the code after sched2, which can have caused our
3141 ; inputs to be clobbered even if they were not clobbered before.
3142 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3143 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3144 ; bbit (i.e. bad scheduling) and missed conditional execution,
3145 ; so make this an option.
3146 (define_peephole2
3147   [(set (reg:CC_ZN CC_REG)
3148         (compare:CC_ZN
3149           (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3150                            (const_int 1)
3151                            (match_operand:SI 1 "nonmemory_operand" ""))
3152           (const_int 0)))
3153    (set (pc)
3154         (if_then_else (match_operator 3 "equality_comparison_operator"
3155                                       [(reg:CC_ZN CC_REG) (const_int 0)])
3156                       (label_ref (match_operand 2 "" ""))
3157                       (pc)))]
3158   "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3159   [(parallel [(set (pc)
3160                    (if_then_else
3161                      (match_op_dup 3
3162                        [(zero_extract:SI (match_dup 0)
3163                                          (const_int 1) (match_dup 1))
3164                         (const_int 0)])
3165                      (label_ref (match_dup 2))
3166                      (pc)))
3167               (clobber (reg:CC_ZN CC_REG))])])
3169 (define_insn "*cmpsi_cc_z_insn"
3170   [(set (reg:CC_Z CC_REG)
3171         (compare:CC_Z (match_operand:SI 0 "register_operand"  "qRcq,c")
3172                       (match_operand:SI 1 "p2_immediate_operand"  "O,n")))]
3173   ""
3174   "@
3175         cmp%? %0,%1%&
3176         bxor.f 0,%0,%z1"
3177   [(set_attr "type" "compare,compare")
3178    (set_attr "iscompact" "true,false")
3179    (set_attr "cond" "set,set_zn")
3180    (set_attr "length" "*,4")])
3182 (define_insn "*cmpsi_cc_c_insn"
3183   [(set (reg:CC_C CC_REG)
3184         (compare:CC_C (match_operand:SI 0 "register_operand"  "Rcqq, c,Rcqq,  c")
3185                       (match_operand:SI 1 "nonmemory_operand" "cO,  cI, Cal,Cal")))]
3186   ""
3187   "cmp%? %0,%S1%&"
3188   [(set_attr "type" "compare")
3189    (set_attr "iscompact" "true,false,true_limm,false")
3190    (set_attr "cond" "set")
3191    (set_attr "length" "*,4,*,8")])
3193 ;; Next come the scc insns.
3195 (define_expand "cstoresi4"
3196   [(set (reg:CC CC_REG)
3197         (compare:CC (match_operand:SI 2 "nonmemory_operand" "")
3198                     (match_operand:SI 3 "nonmemory_operand" "")))
3199    (set (match_operand:SI 0 "dest_reg_operand" "")
3200         (match_operator:SI 1 "ordered_comparison_operator" [(reg CC_REG)
3201                                                             (const_int 0)]))]
3202   ""
3204   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3205   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3206   operands[1] = gen_compare_reg (operands[1], SImode);
3207   emit_insn (gen_scc_insn (operands[0], operands[1]));
3208   DONE;
3211 (define_mode_iterator SDF [SF DF])
3213 (define_expand "cstore<mode>4"
3214   [(set (reg:CC CC_REG)
3215         (compare:CC (match_operand:SDF 2 "register_operand" "")
3216                     (match_operand:SDF 3 "register_operand" "")))
3217    (set (match_operand:SI 0 "dest_reg_operand" "")
3218         (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3219                                                     (const_int 0)]))]
3221   "TARGET_OPTFPE"
3223   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3224   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3225   operands[1] = gen_compare_reg (operands[1], SImode);
3226   emit_insn (gen_scc_insn (operands[0], operands[1]));
3227   DONE;
3230 ; We need a separate expander for this lest we loose the mode of CC_REG
3231 ; when match_operator substitutes the literal operand into the comparison.
3232 (define_expand "scc_insn"
3233   [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3235 (define_insn_and_split "*scc_insn"
3236   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3237         (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3238   ""
3239   "#"
3240   "reload_completed"
3241   [(set (match_dup 0) (const_int 1))
3242    (cond_exec
3243      (match_dup 1)
3244      (set (match_dup 0) (const_int 0)))]
3246   operands[1]
3247     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3248                                          GET_MODE (XEXP (operands[1], 0))),
3249                       VOIDmode,
3250                       XEXP (operands[1], 0), XEXP (operands[1], 1));
3252   [(set_attr "type" "unary")])
3254 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3255 ;; that is one lower if the carry flag is set.
3257 ;; ??? Look up negscc insn.  See pa.md for example.
3258 (define_insn "*neg_scc_insn"
3259   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3260         (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3261                  [(reg CC_REG) (const_int 0)])))]
3262   ""
3263   "mov %0,-1\;sub.%D1 %0,%0,%0"
3264   [(set_attr "type" "unary")
3265    (set_attr "length" "8")])
3267 (define_insn "*not_scc_insn"
3268   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3269         (not:SI (match_operator:SI 1 "proper_comparison_operator"
3270                  [(reg CC_REG) (const_int 0)])))]
3271   ""
3272   "mov %0,1\;sub.%d1 %0,%0,%0"
3273   [(set_attr "type" "unary")
3274    (set_attr "length" "8")])
3276 ; cond_exec patterns
3277 (define_insn "*movsi_ne"
3278   [(cond_exec
3279      (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc") (const_int 0))
3280      (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
3281           (match_operand:SI 1 "nonmemory_operand" "C_0,Lc,?Cal")))]
3282   ""
3283   "@
3284         * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3285         mov.ne %0,%1
3286         mov.ne %0,%S1"
3287   [(set_attr "type" "cmove,cmove,cmove")
3288    (set_attr "iscompact" "true,false,false")
3289    (set_attr "length" "2,4,8")])
3291 (define_insn "*movsi_cond_exec"
3292   [(cond_exec
3293      (match_operator 3 "proper_comparison_operator"
3294        [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3295      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3296           (match_operand:SI 1 "nonmemory_operand" "Lc,?Cal")))]
3297   ""
3298   "mov.%d3 %0,%S1"
3299   [(set_attr "type" "cmove")
3300    (set_attr "length" "4,8")])
3302 (define_insn "*commutative_cond_exec"
3303   [(cond_exec
3304      (match_operator 5 "proper_comparison_operator"
3305        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3306      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3307           (match_operator:SI 3 "commutative_operator"
3308             [(match_operand:SI 1 "register_operand" "%0,0")
3309              (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3310   ""
3312   arc_output_commutative_cond_exec (operands, true);
3313   return "";
3315   [(set_attr "cond" "use")
3316    (set_attr "type" "cmove")
3317    (set_attr_alternative "length"
3318      [(const_int 4)
3319       (cond
3320         [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3321              (const_int 4))
3322          (const_int 4)]
3323         (const_int 8))])])
3325 (define_insn "*sub_cond_exec"
3326   [(cond_exec
3327      (match_operator 4 "proper_comparison_operator"
3328        [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3329      (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3330           (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3331                     (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3332   ""
3333   "@
3334         sub.%d4 %0,%1,%2
3335         rsub.%d4 %0,%2,%1
3336         rsub.%d4 %0,%2,%1"
3337   [(set_attr "cond" "use")
3338    (set_attr "type" "cmove")
3339    (set_attr "length" "4,4,8")])
3341 (define_insn "*noncommutative_cond_exec"
3342   [(cond_exec
3343      (match_operator 5 "proper_comparison_operator"
3344        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3345      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3346           (match_operator:SI 3 "noncommutative_operator"
3347             [(match_operand:SI 1 "register_operand" "0,0")
3348              (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3349   ""
3350   "%O3.%d5 %0,%1,%2"
3351   [(set_attr "cond" "use")
3352    (set_attr "type" "cmove")
3353    (set_attr "length" "4,8")])
3355 ;; These control RTL generation for conditional jump insns
3356 ;; Match both normal and inverted jump.
3358 ; We need a separate expander for this lest we loose the mode of CC_REG
3359 ; when match_operator substitutes the literal operand into the comparison.
3360 (define_expand "branch_insn"
3361   [(set (pc)
3362         (if_then_else (match_operand 1 "" "")
3363                       (label_ref (match_operand 0 "" ""))
3364                       (pc)))])
3366 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3367 ; are three reasons why we need to consider branches to be length 6:
3368 ; - annull-false delay slot insns are implemented using conditional execution,
3369 ;   thus preventing short insn formation where used.
3370 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3371 ;   using conditional execution, preventing short insn formation where used.
3372 ; - for ARC700: likely or somewhat likely taken branches are made long and
3373 ;   unaligned if possible to avoid branch penalty.
3374 (define_insn "*branch_insn"
3375   [(set (pc)
3376         (if_then_else (match_operator 1 "proper_comparison_operator"
3377                                       [(reg CC_REG) (const_int 0)])
3378                       (label_ref (match_operand 0 "" ""))
3379                       (pc)))]
3380   ""
3381   "*
3383   if (arc_ccfsm_branch_deleted_p ())
3384     {
3385       arc_ccfsm_record_branch_deleted ();
3386       return \"; branch deleted, next insns conditionalized\";
3387     }
3388   else
3389     {
3390       arc_ccfsm_record_condition (operands[1], false, insn, 0);
3391       if (get_attr_length (insn) == 2)
3392          return \"b%d1%? %^%l0%&\";
3393       else
3394          return \"b%d1%# %^%l0\";
3395     }
3397   [(set_attr "type" "branch")
3398    (set
3399      (attr "length")
3400      (cond [
3401        (eq_attr "delay_slot_filled" "yes")
3402        (const_int 4)
3404        (ne
3405          (if_then_else
3406            (match_operand 1 "equality_comparison_operator" "")
3407            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3408                 (gt (minus (match_dup 0) (pc))
3409                     (minus (const_int 506)
3410                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3411            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3412                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3413                 (gt (minus (match_dup 0) (pc))
3414                     (minus (const_int 58)
3415                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3416          (const_int 0))
3417        (const_int 4)]
3418       (const_int 2)))
3420    (set (attr "iscompact")
3421         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3422               (const_string "false")))])
3424 (define_insn "*rev_branch_insn"
3425   [(set (pc)
3426         (if_then_else (match_operator 1 "proper_comparison_operator"
3427                                       [(reg CC_REG) (const_int 0)])
3428                       (pc)
3429                       (label_ref (match_operand 0 "" ""))))]
3430   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3431   "*
3433   if (arc_ccfsm_branch_deleted_p ())
3434     {
3435       arc_ccfsm_record_branch_deleted ();
3436       return \"; branch deleted, next insns conditionalized\";
3437     }
3438   else
3439     {
3440       arc_ccfsm_record_condition (operands[1], true, insn, 0);
3441       if (get_attr_length (insn) == 2)
3442          return \"b%D1%? %^%l0\";
3443       else
3444          return \"b%D1%# %^%l0\";
3445     }
3447   [(set_attr "type" "branch")
3448    (set
3449      (attr "length")
3450      (cond [
3451        (eq_attr "delay_slot_filled" "yes")
3452        (const_int 4)
3454        (ne
3455          (if_then_else
3456            (match_operand 1 "equality_comparison_operator" "")
3457            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3458                 (gt (minus (match_dup 0) (pc))
3459                     (minus (const_int 506)
3460                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3461            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3462                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3463                 (gt (minus (match_dup 0) (pc))
3464                     (minus (const_int 58)
3465                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3466          (const_int 0))
3467        (const_int 4)]
3468       (const_int 2)))
3470    (set (attr "iscompact")
3471         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3472               (const_string "false")))])
3474 ;; Unconditional and other jump instructions.
3476 (define_expand "jump"
3477   [(set (pc) (label_ref (match_operand 0 "" "")))]
3478   ""
3479   "")
3481 (define_insn "jump_i"
3482   [(set (pc) (label_ref (match_operand 0 "" "")))]
3483   "!TARGET_LONG_CALLS_SET || !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
3484   "b%!%* %^%l0%&"
3485   [(set_attr "type" "uncond_branch")
3486    (set (attr "iscompact")
3487         (if_then_else (match_test "get_attr_length (insn) == 2")
3488                       (const_string "true") (const_string "false")))
3489    (set_attr "cond" "canuse")
3490    (set (attr "length")
3491         (cond [
3492           ; In arc_reorg we just guesstimate; might be more or less than 4.
3493           (match_test "arc_branch_size_unknown_p ()")
3494           (const_int 4)
3496           (eq_attr "delay_slot_filled" "yes")
3497           (const_int 4)
3499           (match_test "find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)")
3500           (const_int 4)
3502           (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3503                (gt (minus (match_dup 0) (pc))
3504                    (minus (const_int 506)
3505                           (symbol_ref "get_attr_delay_slot_length (insn)"))))
3506           (const_int 4)]
3507          (const_int 2)))])
3509 (define_insn "indirect_jump"
3510   [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3511   ""
3512   "j%!%* [%0]%&"
3513   [(set_attr "type" "jump")
3514    (set_attr "iscompact" "false,false,false,maybe,false")
3515    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3517 ;; Implement a switch statement.
3519 (define_expand "casesi"
3520   [(set (match_dup 5)
3521         (minus:SI (match_operand:SI 0 "register_operand" "")
3522                   (match_operand:SI 1 "nonmemory_operand" "")))
3523    (set (reg:CC CC_REG)
3524         (compare:CC (match_dup 5)
3525                     (match_operand:SI 2 "nonmemory_operand" "")))
3526    (set (pc)
3527         (if_then_else (gtu (reg:CC CC_REG)
3528                            (const_int 0))
3529                       (label_ref (match_operand 4 "" ""))
3530                       (pc)))
3531    (set (match_dup 6)
3532         (unspec:SI [(match_operand 3 "" "")
3533                     (match_dup 5) (match_dup 7)] UNSPEC_CASESI))
3534    (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
3535   ""
3536   "
3538   rtx x;
3540   operands[5] = gen_reg_rtx (SImode);
3541   operands[6] = gen_reg_rtx (SImode);
3542   operands[7] = operands[3];
3543   emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
3544   emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
3545   x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
3546   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
3547                             gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
3548   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
3549   if (TARGET_COMPACT_CASESI)
3550     {
3551       emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
3552     }
3553   else
3554     {
3555       operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3556       if (flag_pic || !cse_not_expected)
3557         operands[3] = force_reg (Pmode, operands[3]);
3558       emit_insn (gen_casesi_load (operands[6],
3559                                   operands[3], operands[5], operands[7]));
3560       if (CASE_VECTOR_PC_RELATIVE || flag_pic)
3561         emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
3562       emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
3563     }
3564   DONE;
3567 (define_insn "casesi_load"
3568   [(set (match_operand:SI 0 "register_operand"             "=Rcq,r,r")
3569         (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
3570                     (match_operand:SI 2 "register_operand"  "Rcq,c,c")
3571                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))]
3572   ""
3573   "*
3575   rtx diff_vec = PATTERN (next_nonnote_insn (operands[3]));
3577   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
3578     {
3579       gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
3580       gcc_assert (GET_MODE (diff_vec) == SImode);
3581       gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
3582     }
3584   switch (GET_MODE (diff_vec))
3585     {
3586     case SImode:
3587       return \"ld.as %0,[%1,%2]%&\";
3588     case HImode:
3589       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3590         return \"ldw.as %0,[%1,%2]\";
3591       return \"ldw.x.as %0,[%1,%2]\";
3592     case QImode:
3593       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3594         return \"ldb%? %0,[%1,%2]%&\";
3595       return \"ldb.x %0,[%1,%2]\";
3596     default:
3597       gcc_unreachable ();
3598     }
3600   [(set_attr "type" "load")
3601    (set_attr_alternative "iscompact"
3602      [(cond
3603         [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn (operands[3])))")
3604              (symbol_ref "QImode"))
3605          (const_string "false")
3606          (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn (operands[3]))).offset_unsigned")
3607          (const_string "false")]
3608         (const_string "true"))
3609       (const_string "false")
3610       (const_string "false")])
3611    (set_attr_alternative "length"
3612      [(cond
3613         [(eq_attr "iscompact" "false") (const_int 4)
3614         ; We have to mention (match_dup 3) to convince genattrtab.c that this
3615         ; is a varying length insn.
3616          (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
3617          (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
3618         (const_int 2))
3619       (const_int 4)
3620       (const_int 8)])])
3622 ; Unlike the canonical tablejump, this pattern always uses a jump address,
3623 ; even for CASE_VECTOR_PC_RELATIVE.
3624 (define_insn "casesi_jump"
3625   [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
3626    (use (label_ref (match_operand 1 "" "")))]
3627   ""
3628   "j%!%* [%0]%&"
3629   [(set_attr "type" "jump")
3630    (set_attr "iscompact" "false,maybe,false")
3631    (set_attr "cond" "canuse")])
3633 (define_insn "casesi_compact_jump"
3634   [(set (pc)
3635         (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
3636                    UNSPEC_CASESI))
3637    (use (label_ref (match_operand 1 "" "")))
3638    (clobber (match_scratch:SI 2 "=q,0"))]
3639   "TARGET_COMPACT_CASESI"
3640   "*
3642   rtx diff_vec = PATTERN (next_nonnote_insn (operands[1]));
3643   int unalign = arc_get_unalign ();
3644   rtx xop[3];
3645   const char *s;
3647   xop[0] = operands[0];
3648   xop[2] = operands[2];
3649   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
3651   switch (GET_MODE (diff_vec))
3652     {
3653     case SImode:
3654       /* Max length can be 12 in this case, but this is OK because
3655          2 of these are for alignment, and are anticipated in the length
3656          of the ADDR_DIFF_VEC.  */
3657       if (unalign && !satisfies_constraint_Rcq (xop[0]))
3658         s = \"add2 %2,pcl,%0\n\tld_s%2,[%2,12]\";
3659       else if (unalign)
3660         s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
3661       else
3662         s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
3663       arc_clear_unalign ();
3664       break;
3665     case HImode:
3666       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3667         {
3668           if (satisfies_constraint_Rcq (xop[0]))
3669             {
3670               s = \"add_s %2,%0,%1\n\tldw.as %2,[pcl,%2]\";
3671               xop[1] = GEN_INT ((10 - unalign) / 2U);
3672             }
3673           else
3674             {
3675               s = \"add1 %2,pcl,%0\n\tldw_s %2,[%2,%1]\";
3676               xop[1] = GEN_INT (10 + unalign);
3677             }
3678         }
3679       else
3680         {
3681           if (satisfies_constraint_Rcq (xop[0]))
3682             {
3683               s = \"add_s %2,%0,%1\n\tldw.x.as %2,[pcl,%2]\";
3684               xop[1] = GEN_INT ((10 - unalign) / 2U);
3685             }
3686           else
3687             {
3688               s = \"add1 %2,pcl,%0\n\tldw_s.x %2,[%2,%1]\";
3689               xop[1] = GEN_INT (10 + unalign);
3690             }
3691         }
3692       arc_toggle_unalign ();
3693       break;
3694     case QImode:
3695       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3696         {
3697           if ((rtx_equal_p (xop[2], xop[0])
3698                || find_reg_note (insn, REG_DEAD, xop[0]))
3699               && satisfies_constraint_Rcq (xop[0]))
3700             {
3701               s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
3702               xop[1] = GEN_INT (8 + unalign);
3703             }
3704           else
3705             {
3706               s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
3707               xop[1] = GEN_INT (10 + unalign);
3708               arc_toggle_unalign ();
3709             }
3710         }
3711       else if ((rtx_equal_p (xop[0], xop[2])
3712                 || find_reg_note (insn, REG_DEAD, xop[0]))
3713                && satisfies_constraint_Rcq (xop[0]))
3714         {
3715           s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
3716           xop[1] = GEN_INT (10 - unalign);
3717           arc_toggle_unalign ();
3718         }
3719       else
3720         {
3721           /* ??? Length is 12.  */
3722           s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
3723           xop[1] = GEN_INT (8 + unalign);
3724         }
3725       break;
3726     default:
3727       gcc_unreachable ();
3728     }
3729   output_asm_insn (s, xop);
3730   return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
3732   [(set_attr "length" "10")
3733    (set_attr "type" "jump")
3734    (set_attr "iscompact" "true")
3735    (set_attr "cond" "nocond")])
3737 (define_expand "call"
3738   ;; operands[1] is stack_size_rtx
3739   ;; operands[2] is next_arg_register
3740   [(parallel [(call (match_operand:SI 0 "call_operand" "")
3741                     (match_operand 1 "" ""))
3742              (clobber (reg:SI 31))])]
3743   ""
3744   "{
3745     rtx callee;
3747     gcc_assert (MEM_P (operands[0]));
3748     callee  = XEXP (operands[0], 0);
3749     if (crtl->profile && arc_profile_call (callee))
3750       {
3751         emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
3752                                                            \"_mcount_call\"),
3753                                        operands[1]));
3754         DONE;
3755       }
3756     /* This is to decide if we should generate indirect calls by loading the
3757        32 bit address of the callee into a register before performing the
3758        branch and link - this exposes cse opportunities.
3759        Also, in weird cases like compile/20010107-1.c, we may get a PLUS.  */
3760     if (GET_CODE (callee) != REG
3761         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
3762       XEXP (operands[0], 0) = force_reg (Pmode, callee);
3763   }
3767 ; Rcq, which is used in alternative 0, checks for conditional execution.
3768 ; At instruction output time, if it doesn't match and we end up with
3769 ; alternative 1 ("q"), that means that we can't use the short form.
3770 (define_insn "*call_i"
3771   [(call (mem:SI (match_operand:SI 0
3772                   "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
3773          (match_operand 1 "" ""))
3774    (clobber (reg:SI 31))]
3775   ""
3776   "@
3777    jl%!%* [%0]%&
3778    jl%!%* [%0]%&
3779    jl%!%* [%0]
3780    bl%!%* %P0
3781    bl%!%* %P0
3782    jl%!%* %S0
3783    jl%* %S0
3784    jl%! %S0"
3785   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
3786    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
3787    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
3788    (set_attr "length" "*,*,4,4,4,4,4,8")])
3790 (define_insn "call_prof"
3791   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal"))
3792          (match_operand 1 "" ""))
3793    (clobber (reg:SI 31))
3794    (use (reg:SI 8))
3795    (use (reg:SI 9))]
3796    ""
3797   "@
3798    bl%!%* %P0;2
3799    jl%! %^%S0"
3800   [(set_attr "type" "call,call_no_delay_slot")
3801    (set_attr "predicable" "yes,yes")
3802    (set_attr "length" "4,8")])
3804 (define_expand "call_value"
3805   ;; operand 2 is stack_size_rtx
3806   ;; operand 3 is next_arg_register
3807   [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
3808                    (call (match_operand:SI 1 "call_operand" "")
3809                          (match_operand 2 "" "")))
3810              (clobber (reg:SI 31))])]
3811   ""
3812   "
3813   {
3814     rtx callee;
3816     gcc_assert (MEM_P (operands[1]));
3817     callee = XEXP (operands[1], 0);
3818     if (crtl->profile && arc_profile_call (callee))
3819       {
3820         emit_call_insn (gen_call_value_prof (operands[0],
3821                                              gen_rtx_SYMBOL_REF (Pmode,
3822                                                             \"_mcount_call\"),
3823                                              operands[2]));
3824         DONE;
3825       }
3826      /* See the comment in define_expand \"call\".  */
3827     if (GET_CODE (callee) != REG
3828         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
3829       XEXP (operands[1], 0) = force_reg (Pmode, callee);
3830   }")
3833 ; Rcq, which is used in alternative 0, checks for conditional execution.
3834 ; At instruction output time, if it doesn't match and we end up with
3835 ; alternative 1 ("q"), that means that we can't use the short form.
3836 (define_insn "*call_value_i"
3837   [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,w,w,  w")
3838         (call (mem:SI (match_operand:SI 1
3839                        "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
3840               (match_operand 2 "" "")))
3841    (clobber (reg:SI 31))]
3842   ""
3843   "@
3844    jl%!%* [%1]%&
3845    jl%!%* [%1]%&
3846    jl%!%* [%1]
3847    bl%!%* %P1;1
3848    bl%!%* %P1;1
3849    jl%!%* %S1
3850    jl%* %S1
3851    jl%! %S1"
3852   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
3853    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
3854    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
3855    (set_attr "length" "*,*,4,4,4,4,4,8")])
3857 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
3858 ; use it for lack of inter-procedural branch shortening.
3859 ; Link-time relaxation would help...
3862 (define_insn "call_value_prof"
3863   [(set (match_operand 0 "dest_reg_operand" "=r,r")
3864         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal"))
3865               (match_operand 2 "" "")))
3866    (clobber (reg:SI 31))
3867    (use (reg:SI 8))
3868    (use (reg:SI 9))]
3869    ""
3870   "@
3871    bl%!%* %P1;1
3872    jl%! %^%S1"
3873   [(set_attr "type" "call,call_no_delay_slot")
3874    (set_attr "predicable" "yes,yes")
3875    (set_attr "length" "4,8")])
3877 (define_insn "nop"
3878   [(const_int 0)]
3879   ""
3880   "nop%?"
3881   [(set_attr "type" "misc")
3882    (set_attr "iscompact" "true")
3883    (set_attr "cond" "canuse")
3884    (set_attr "length" "2")])
3886 ;; Special pattern to flush the icache.
3887 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
3889 (define_insn "flush_icache"
3890   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
3891   ""
3892   "* return \"\";"
3893   [(set_attr "type" "misc")])
3895 ;; Split up troublesome insns for better scheduling.
3897 ;; Peepholes go at the end.
3898 ;;asl followed by add can be replaced by an add{1,2,3}
3899 ;; Three define_peepholes have been added for this optimization
3900 ;; ??? This used to target non-canonical rtl.  Now we use add_n, which
3901 ;; can be generated by combine.  Check if these peepholes still provide
3902 ;; any benefit.
3904 ;; -------------------------------------------------------------
3905 ;; Pattern 1 : r0 = r1 << {i}
3906 ;;             r3 = r4/INT + r0     ;;and commutative
3907 ;;                 ||
3908 ;;                 \/
3909 ;;             add{i} r3,r4/INT,r1
3910 ;; -------------------------------------------------------------
3911 ;; ??? This should be covered by combine, alas, at times combine gets
3912 ;; too clever for it's own good: when the shifted input is known to be
3913 ;; either 0 or 1, the operation will be made into an if-then-else, and
3914 ;; thus fail to match the add_n pattern.  Example: _mktm_r, line 85 in
3915 ;; newlib/libc/time/mktm_r.c .
3917 (define_peephole2
3918   [(set (match_operand:SI 0 "dest_reg_operand" "")
3919         (ashift:SI (match_operand:SI 1 "register_operand" "")
3920                    (match_operand:SI 2 "const_int_operand" "")))
3921   (set (match_operand:SI 3 "dest_reg_operand" "")
3922        (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
3923                 (match_operand:SI 5 "nonmemory_operand" "")))]
3924   "(INTVAL (operands[2]) == 1
3925     || INTVAL (operands[2]) == 2
3926     || INTVAL (operands[2]) == 3)
3927    && (true_regnum (operands[4]) == true_regnum (operands[0])
3928        || true_regnum (operands[5]) == true_regnum (operands[0]))
3929    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
3930  ;; the preparation statements take care to put proper operand in operands[4]
3931  ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
3932   [(set (match_dup 3)
3933         (plus:SI (mult:SI (match_dup 1)
3934                           (match_dup 2))
3935                  (match_dup 4)))]
3936   "if (true_regnum (operands[4]) == true_regnum (operands[0]))
3937       operands[4] = operands[5];
3938    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
3941 ;; -------------------------------------------------------------
3942 ;; Pattern 1 : r0 = r1 << {i}
3943 ;;             r3 = r4 - r0
3944 ;;                 ||
3945 ;;                 \/
3946 ;;             sub{i} r3,r4,r1
3947 ;; -------------------------------------------------------------
3948 ;; ??? This should be covered by combine, alas, at times combine gets
3949 ;; too clever for it's own good: when the shifted input is known to be
3950 ;; either 0 or 1, the operation will be made into an if-then-else, and
3951 ;; thus fail to match the sub_n pattern.  Example: __ieee754_yn, line 239 in
3952 ;; newlib/libm/math/e_jn.c .
3954 (define_peephole2
3955   [(set (match_operand:SI 0 "dest_reg_operand" "")
3956         (ashift:SI (match_operand:SI 1 "register_operand" "")
3957                    (match_operand:SI 2 "const_int_operand" "")))
3958    (set (match_operand:SI 3 "dest_reg_operand" "")
3959         (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
3960                   (match_dup 0)))]
3961   "(INTVAL (operands[2]) == 1
3962     || INTVAL (operands[2]) == 2
3963     || INTVAL (operands[2]) == 3)
3964    && (peep2_reg_dead_p (2, operands[0])
3965        || (true_regnum (operands[3]) == true_regnum (operands[0])))"
3966   [(set (match_dup 3)
3967         (minus:SI (match_dup 4)
3968                   (mult:SI (match_dup 1)
3969                            (match_dup 2))))]
3970   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
3975 ; When using the high single bit, the result of a multiply is either
3976 ; the original number or zero.  But MPY costs 4 cycles, which we
3977 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
3978 (define_peephole2
3979   [(set (match_operand:SI 0 "dest_reg_operand" "")
3980         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3981                      (const_int 31)))
3982    (set (match_operand:SI 4 "register_operand" "")
3983         (mult:SI (match_operand:SI 2 "register_operand")
3984                  (match_operand:SI 3 "nonmemory_operand" "")))]
3985   "TARGET_ARC700 && !TARGET_NOMPY_SET
3986    && (rtx_equal_p (operands[0], operands[2])
3987        || rtx_equal_p (operands[0], operands[3]))
3988    && peep2_regno_dead_p (0, CC_REG)
3989    && (rtx_equal_p (operands[0], operands[4])
3990        || (peep2_reg_dead_p (2, operands[0])
3991           && peep2_reg_dead_p (1, operands[4])))"
3992   [(parallel [(set (reg:CC_Z CC_REG)
3993                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
3994                                  (const_int 0)))
3995               (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
3996    (cond_exec
3997      (ne (reg:CC_Z CC_REG) (const_int 0))
3998      (set (match_dup 4) (match_dup 5)))]
4000   if (!rtx_equal_p (operands[0], operands[2]))
4001     operands[5] = operands[2];
4002   else if (!rtx_equal_p (operands[0], operands[3]))
4003     operands[5] = operands[3];
4004   else
4005     operands[5] = operands[4]; /* Actually a no-op... presumably rare.  */
4008 (define_peephole2
4009   [(set (match_operand:SI 0 "dest_reg_operand" "")
4010         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4011                      (const_int 31)))
4012    (set (match_operand:SI 4 "register_operand" "")
4013         (mult:SI (match_operand:SI 2 "register_operand")
4014                  (match_operand:SI 3 "nonmemory_operand" "")))]
4015   "TARGET_ARC700 && !TARGET_NOMPY_SET
4016    && (rtx_equal_p (operands[0], operands[2])
4017        || rtx_equal_p (operands[0], operands[3]))
4018    && peep2_regno_dead_p (2, CC_REG)"
4019   [(parallel [(set (reg:CC_Z CC_REG)
4020                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4021                                  (const_int 0)))
4022               (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4023    (set (match_dup 4) (match_dup 5))
4024    (cond_exec
4025      (eq (reg:CC_Z CC_REG) (const_int 0))
4026      (set (match_dup 4) (const_int 0)))]
4027  "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4029 ;; Instructions generated through builtins
4031 (define_insn "clrsbsi2"
4032   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4033         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4034   "TARGET_NORM"
4035   "@
4036    norm \t%0, %1
4037    norm \t%0, %S1"
4038   [(set_attr "length" "4,8")
4039    (set_attr "type" "two_cycle_core,two_cycle_core")])
4041 (define_insn "norm_f"
4042   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4043         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4044    (set (reg:CC_ZN CC_REG)
4045         (compare:CC_ZN (match_dup 1) (const_int 0)))]
4046   "TARGET_NORM"
4047   "@
4048    norm.f\t%0, %1
4049    norm.f\t%0, %S1"
4050   [(set_attr "length" "4,8")
4051    (set_attr "type" "two_cycle_core,two_cycle_core")])
4053 (define_insn_and_split "clrsbhi2"
4054   [(set (match_operand:HI  0 "dest_reg_operand" "=w,w")
4055         (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4056   "TARGET_NORM"
4057   "#"
4058   "reload_completed"
4059   [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4060   "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4062 (define_insn "normw"
4063   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4064         (zero_extend:SI
4065           (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4066   "TARGET_NORM"
4067   "@
4068    normw \t%0, %1
4069    normw \t%0, %S1"
4070   [(set_attr "length" "4,8")
4071    (set_attr "type" "two_cycle_core,two_cycle_core")])
4073 (define_expand "clzsi2"
4074   [(set (match_operand:SI 0 "dest_reg_operand" "")
4075         (clz:SI (match_operand:SI 1 "register_operand" "")))]
4076   "TARGET_NORM"
4078   emit_insn (gen_norm_f (operands[0], operands[1]));
4079   emit_insn
4080     (gen_rtx_COND_EXEC
4081       (VOIDmode,
4082        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4083        gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
4084   emit_insn
4085     (gen_rtx_COND_EXEC
4086       (VOIDmode,
4087        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4088        gen_rtx_SET (VOIDmode, operands[0],
4089                     plus_constant (SImode, operands[0], 1))));
4090   DONE;
4093 (define_expand "ctzsi2"
4094   [(set (match_operand:SI 0 "register_operand" "")
4095         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
4096   "TARGET_NORM"
4098   rtx temp = operands[0];
4100   if (reg_overlap_mentioned_p (temp, operands[1])
4101       || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4102           && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4103                                  REGNO (temp))))
4104     temp = gen_reg_rtx (SImode);
4105   emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4106   emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4107   emit_insn (gen_clrsbsi2 (temp, temp));
4108   emit_insn
4109     (gen_rtx_COND_EXEC
4110       (VOIDmode,
4111        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4112        gen_rtx_SET (VOIDmode, operands[0], GEN_INT (32))));
4113   emit_insn
4114     (gen_rtx_COND_EXEC
4115       (VOIDmode,
4116        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4117        gen_rtx_SET (VOIDmode, operands[0],
4118                     gen_rtx_MINUS (SImode, GEN_INT (31), temp))));
4119   DONE;
4123 (define_insn "swap"
4124   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
4125         (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4126                             UNSPEC_SWAP))]
4127   "TARGET_SWAP"
4128   "@
4129    swap \t%0, %1
4130    swap \t%0, %S1
4131    swap \t%0, %1"
4132   [(set_attr "length" "4,8,4")
4133    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4135 ;; FIXME: an intrinsic for multiply is daft.  Can we remove this?
4136 (define_insn "mul64"
4137   [(unspec [(match_operand:SI 0 "general_operand" "q,r,r,%r")
4138                      (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
4139                    UNSPEC_MUL64)]
4140   "TARGET_MUL64_SET"
4141   "@
4142    mul64%? \t0, %0, %1%&
4143    mul64%? \t0, %0, %1
4144    mul64 \t0, %0, %1
4145    mul64%? \t0, %0, %S1"
4146   [(set_attr "length" "2,4,4,8")
4147   (set_attr "iscompact" "true,false,false,false")
4148   (set_attr "type" "binary,binary,binary,binary")
4149   (set_attr "cond" "canuse,canuse, nocond, canuse")])
4151 (define_insn "mulu64"
4152   [(unspec [(match_operand:SI 0 "general_operand" "%r,r,r,r")
4153                      (match_operand:SI 1 "general_operand" "rL,I,r,Cal")]
4154                    UNSPEC_MULU64)]
4155   "TARGET_MUL64_SET"
4156   "@
4157    mulu64%? \t0, %0, %1
4158    mulu64 \t0, %0, %1
4159    mulu64 \t0, %0, %1
4160    mulu64%? \t0, %0, %S1"
4161   [(set_attr "length" "4,4,4,8")
4162    (set_attr "type" "binary,binary,binary,binary")
4163    (set_attr "cond" "canuse,nocond,nocond,canuse")])
4165 (define_insn "divaw"
4166   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4167                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4168                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4169                                            UNSPEC_DIVAW))]
4170   "TARGET_ARC700 || TARGET_EA_SET"
4171   "@
4172    divaw \t%0, %1, %2
4173    divaw \t%0, %S1, %2
4174    divaw \t%0, %1, %S2"
4175   [(set_attr "length" "4,8,8")
4176    (set_attr "type" "divaw,divaw,divaw")])
4178 (define_insn "flag"
4179   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4180                    VUNSPEC_FLAG)]
4181   ""
4182   "@
4183     flag%? %0
4184     flag %0
4185     flag%? %S0"
4186   [(set_attr "length" "4,4,8")
4187    (set_attr "type" "misc,misc,misc")
4188    (set_attr "predicable" "yes,no,yes")
4189    (set_attr "cond" "clob,clob,clob")])
4191 (define_insn "brk"
4192   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4193                    VUNSPEC_BRK)]
4194   ""
4195   "brk"
4196   [(set_attr "length" "4")
4197   (set_attr "type" "misc")])
4199 (define_insn "rtie"
4200   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4201                    VUNSPEC_RTIE)]
4202   ""
4203   "rtie"
4204   [(set_attr "length" "4")
4205   (set_attr "type" "misc")
4206   (set_attr "cond" "clob")])
4208 (define_insn "sync"
4209   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4210                    VUNSPEC_SYNC)]
4211   ""
4212   "sync"
4213   [(set_attr "length" "4")
4214   (set_attr "type" "misc")])
4216 (define_insn "swi"
4217   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4218                    VUNSPEC_SWI)]
4219   ""
4220   "*
4222     if(TARGET_ARC700)
4223         return \"trap0\";
4224     else
4225         return \"swi\";
4227   [(set_attr "length" "4")
4228   (set_attr "type" "misc")])
4231 (define_insn "sleep"
4232   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4233                    VUNSPEC_SLEEP)]
4234   "check_if_valid_sleep_operand(operands,0)"
4235   "sleep %0"
4236   [(set_attr "length" "4")
4237   (set_attr "type" "misc")])
4239 (define_insn "core_read"
4240   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4241         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4242                             VUNSPEC_CORE_READ))]
4243   ""
4244   "*
4245     if (check_if_valid_regno_const (operands, 1))
4246       return \"mov \t%0, r%1\";
4247     return \"mov \t%0, r%1\";
4248   "
4249   [(set_attr "length" "4")
4250    (set_attr "type" "unary")])
4252 (define_insn "core_write"
4253   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4254                      (match_operand:SI 1 "general_operand" "Hn,!r")]
4255                    VUNSPEC_CORE_WRITE)]
4256   ""
4257   "*
4258     if (check_if_valid_regno_const (operands, 1))
4259       return \"mov \tr%1, %0\";
4260     return \"mov \tr%1, %0\";
4261   "
4262   [(set_attr "length" "4")
4263    (set_attr "type" "unary")])
4265 (define_insn "lr"
4266   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
4267         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4268                             VUNSPEC_LR))]
4269   ""
4270   "lr\t%0, [%1]"
4271   [(set_attr "length" "4,8,4,8")
4272    (set_attr "type" "lr,lr,lr,lr")])
4274 (define_insn "sr"
4275   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4276                      (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4277                    VUNSPEC_SR)]
4278   ""
4279   "sr\t%S0, [%1]"
4280   [(set_attr "length" "8,4,8,4")
4281    (set_attr "type" "sr,sr,sr,sr")])
4283 (define_insn "trap_s"
4284   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4285                    VUNSPEC_TRAP_S)]
4286   "TARGET_ARC700"
4288   if (which_alternative == 0)
4289     {
4290       arc_toggle_unalign ();
4291       return \"trap_s %0\";
4292     }
4294   /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4295      because *.md files do not get scanned by exgettext.  */
4296   fatal_error (\"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     && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
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   "!find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
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   "!find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
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 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 (GET_CODE (PATTERN (scan)) == SEQUENCE)
4816         scan = XVECEXP (PATTERN (scan), 0, 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 = 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")