merge selected patches from milepost-integration:
[official-gcc.git] / gcc / config / arc / arc.md
blobea0147ee019cf41b248ece32168e841dbfccaafa
1 ;; Machine description of the ARC ARCompact cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1999, 2006, 2007, 2008, 2009
3 ;; Free Software Foundation, Inc.
5 ;;    Sources derived from work done by Sankhya Technologies (www.sankhya.com)
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@arc.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             [IJKLMNOP]
46 ;;   register_operand      register                       [rq]
47 ;;   general_operand       register, memory, constant     [rqmIJKLMNOP]
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 ;;      signed 9-bit immediate (for ARCtangent-A4)
72 ;;   J  long immediate (signed 32-bit immediate)
73 ;;   K  unsigned 3-bit immediate (for ARCompact)
74 ;;   L  unsigned 6-bit immediate (for ARCompact)
75 ;;   M  unsinged 5-bit immediate (for ARCompact)
76 ;;   O  unsinged 7-bit immediate (for ARCompact)
77 ;;   P  unsinged 8-bit immediate (for ARCompact)
78 ;;   N  constant '1' (for ARCompact)
81 ;;  ashwin : include options.h from build dir
82 ;; (include "arc.c")
85 ;; TODO:
86 ;; -> Supporting arith/logic insns which update the status flag based on the
87 ;;    operation result (i.e <op>.f type insns).
88 ;; -> conditional jump Jcc
89 ;; -> prefetch instruction
90 ;; -> rsub insn
92 ;;  -----------------------------------------------------------------------------
94 ;; Include DFA scheduluers
95 (include ("arc600.md"))
96 (include ("arc700.md"))
98 ;; Predicates
100 (include ("predicates.md"))
101 (include ("constraints.md"))
102 ;;  -----------------------------------------------------------------------------
104 ;; UNSPEC Usage:
105 ;; ~~~~~~~~~~~~
106 ;;  -----------------------------------------------------------------------------
107 ;;  Symbolic name  Value              Desc.
108 ;;  -----------------------------------------------------------------------------
109 ;;  UNSPEC_PLT       3        symbol to be referenced through the PLT
110 ;;  UNSPEC_GOT       4        symbol to be rerenced through the GOT
111 ;;  UNSPEC_GOTOFF    5        Local symbol.To be referenced relative to the
112 ;;                            GOTBASE.(Referenced as @GOTOFF)
113 ;;  ----------------------------------------------------------------------------
116 (define_constants
117   [(UNSPEC_NORM 11) ; norm generation through builtins. candidate for scheduling
118    (UNSPEC_NORMW 12) ; normw generation through builtins. candidate for scheduling
119    (UNSPEC_SWAP 13) ; swap generation through builtins. candidate for scheduling
120    (UNSPEC_MUL64 14) ; mul64 generation through builtins. candidate for scheduling
121    (UNSPEC_MULU64 15) ; mulu64 generation through builtins. candidate for scheduling
122    (UNSPEC_DIVAW 16) ; divaw generation through builtins. candidate for scheduling
123    (UNSPEC_DIRECT 17)
124    (UNSPEC_PROF 18) ; profile callgraph counter
125    (UNSPEC_LP 19) ; to set LP_END
126    (UNSPEC_CASESI 20)
127    (VUNSPEC_RTIE 17) ; blockage insn for rtie generation
128    (VUNSPEC_SYNC 18) ; blockage insn for sync generation
129    (VUNSPEC_BRK 19) ; blockage insn for brk generation
130    (VUNSPEC_FLAG 20) ; blockage insn for flag generation
131    (VUNSPEC_SLEEP 21) ; blockage insn for sleep generation
132    (VUNSPEC_SWI 22) ; blockage insn for swi generation
133    (VUNSPEC_CORE_READ 23) ; blockage insn for reading a core register 
134    (VUNSPEC_CORE_WRITE 24) ; blockage insn for writing to a core register 
135    (VUNSPEC_LR 25) ; blockage insn for reading an auxillary register 
136    (VUNSPEC_SR 26) ; blockage insn for writing to an auxillary register 
137    (VUNSPEC_TRAP_S 27) ; blockage insn for trap_s generation
138    (VUNSPEC_UNIMP_S 28) ; blockage insn for unimp_s generation
140    (SP_REG 28)
141    (ILINK1_REGNUM 29)
142    (ILINK2_REGNUM 30)
143    (RETURN_ADDR_REGNUM 31)
144    (LP_COUNT 60)
145    (CC_REG 61)
146    (LP_START 144)
147    (LP_END 145)
148   ]
151 (define_attr "is_sfunc" "no,yes" (const_string "no"))
153 ;; Insn type.  Used to default other attribute values.
155 (define_attr "type"
156   "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
157    brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
158    multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
159    misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
160    simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
161    simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle, 
162    simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
163    simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
164    simd_valign, simd_valign_with_acc, simd_vcontrol,
165    simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma"
166   (cond [(eq_attr "is_sfunc" "yes")
167          (cond [(eq (symbol_ref "TARGET_LONG_CALLS_SET") (const_int 0))
168                 (const_string "call")
169                 (ne (symbol_ref "flag_pic") (const_int 0))
170                 (const_string "sfunc")]
171                (const_string "call_no_delay_slot"))]
172         (const_string "binary")))
174 ;; The following three attributes are mixed case so that they can be
175 ;; used conveniently with the CALL_ATTR macro.
176 (define_attr "is_CALL" "no,yes"
177   (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
178          (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
179         (const_string "no")))
181 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
183 (define_attr "is_NON_SIBCALL" "no,yes"
184   (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
185          (eq_attr "is_CALL" "yes") (const_string "yes")]
186         (const_string "no")))
187   
189 ;; Attribute describing the processor
190 (define_attr "cpu" "A4,A5,ARC600,ARC700"
191   (const (symbol_ref "arc_cpu_attr")))
193 ;; true for compact instructions (those with _s suffix)
194 ;; "maybe" means compact unless we conditionalize the insn.
195 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
196   (cond [(eq_attr "type" "sfunc")
197          (const_string "maybe")]
198         (const_string "false")))
201 ;; Condition codes: this one is used by final_prescan_insn to speed up
202 ;; conditionalizing instructions.  It saves having to scan the rtl to see if
203 ;; it uses or alters the condition codes.
205 ;; USE: This insn uses the condition codes (eg: a conditional branch).
206 ;; CANUSE: This insn can use the condition codes (for conditional execution).
207 ;; SET: All condition codes are set by this insn.
208 ;; SET_ZN: the Z and N flags are set by this insn.
209 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
210 ;; CLOB: The condition codes are set to unknown values by this insn.
211 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
213 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
214   (if_then_else (eq_attr "cpu" "A4")
215       (cond [(and (eq_attr "type" "unary,move")
216                   (match_operand 1 "register_operand" ""))
217              (const_string "canuse")
219              (and (eq_attr "type" "binary")
220                   (match_operand 2 "register_operand" ""))
221              (const_string "canuse")
223              (eq_attr "type" "compare")
224              (const_string "set")
226              (eq_attr "type" "cmove,branch")
227              (const_string "use")
229              (eq_attr "type" "multi,misc,shift")
230              (const_string "clob")
231             ]
233             (const_string "nocond"))
235       (if_then_else (eq_attr "iscompact" "maybe,false")
236           (cond [(eq_attr "type" "unary,move")
237                  (if_then_else
238                     (ior (match_operand 1 "u6_immediate_operand" "")
239                          (match_operand 1 "long_immediate_operand" ""))
240                     (const_string "canuse")
241                     (const_string "nocond"))
243                  (eq_attr "type" "binary")
244                  (cond [(ne (symbol_ref "REGNO (operands[0])")
245                             (symbol_ref "REGNO (operands[1])"))
246                         (const_string "nocond")
247                         (match_operand 2 "register_operand" "")
248                         (const_string "canuse")
249                         (match_operand 2 "u6_immediate_operand" "")
250                         (const_string "canuse")
251                         (match_operand 2 "long_immediate_operand" "")
252                         (const_string "canuse")
253                         (match_operand 2 "const_int_operand" "")
254                         (const_string "canuse_limm")]
255                        (const_string "nocond"))
257                  (eq_attr "type" "compare")
258                  (const_string "set")
260                  (eq_attr "type" "cmove,branch")
261                  (const_string "use")
263                  (eq_attr "is_sfunc" "yes")
264                  (cond [(ne (symbol_ref "(TARGET_MEDIUM_CALLS
265                                           && !TARGET_LONG_CALLS_SET
266                                           && flag_pic)")
267                             (const_int 0))
268                         (const_string "canuse_limm_add")
269                         (ne (symbol_ref "(TARGET_MEDIUM_CALLS
270                                           && !TARGET_LONG_CALLS_SET)")
271                             (const_int 0))
272                         (const_string "canuse_limm")]
273                        (const_string "canuse"))
275                 ]
277                 (const_string "nocond"))
279           (cond [(eq_attr "type" "compare")
280                  (const_string "set")
282                  (eq_attr "type" "cmove,branch")
283                  (const_string "use")
285                 ]
287                 (const_string "nocond")))))
289 (define_attr "verify_short" "no,yes"
290   (if_then_else
291     (ne (symbol_ref "arc_verify_short (insn, insn_current_address & 2, 0)")
292         (const_int 0))
293     (const_string "yes") (const_string "no")))
295 ; Is there an instruction that we are actually putting into the delay slot?
296 (define_attr "delay_slot_filled" "no,yes"
297   (cond [(ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) == insn") (const_int 0))
298          (const_string "no")
299          (ne (symbol_ref "!TARGET_AT_DBR_CONDEXEC
300                           && INSN_ANNULLED_BRANCH_P (insn)
301                           && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
302              (const_int 0))
303          (const_string "no")]
304         (const_string "yes")))
306 ; Is a delay slot present for purposes of shorten_branches?
307 ; We have to take the length of this insn into account for forward branches
308 ; even if we don't put the insn actually into a delay slot.
309 (define_attr "delay_slot_present" "no,yes"
310   (cond [(ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) == insn") (const_int 0))
311          (const_string "no")]
312         (const_string "yes")))
314 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
315 ; length of a different insn with the same uid.
316 (define_attr "delay_slot_length" ""
317   (cond [(ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) == insn") (const_int 0))
318          (const_int 0)]
319         (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
320                      - get_attr_length (insn)")))
323 ;; The length variations of ARCompact can't be expressed with the traditional
324 ;; mechanisms in a way that avoids infinite looping in shorten_branches.
325 ;; Given a set of potentially short insns, we could express the effect of
326 ;; arc_verify_short returing zero as an alignment of the current or the
327 ;; following insn, depending on alignment.
328 ;; However, which branch / jump insns are potentially short in turn depends
329 ;; on instruction length.
330 (define_attr "lock_length" "" (const_int 0))
332 ;; Length (in # of bytes, long immediate constants counted too).
333 ;; ??? There's a nasty interaction between the conditional execution fsm
334 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
335 (define_attr "length" ""
336   (cond
337    [(eq_attr "lock_length" "!0") (const_int 2)
338     (eq_attr "cpu" "A4")
339       (cond [(eq_attr "type" "load")
340              (if_then_else
341                  (match_operand 1 "long_immediate_loadstore_operand" "")
342                  (const_int 8) (const_int 4))
344              (eq_attr "type" "store")
345              (if_then_else
346                  (match_operand 0 "long_immediate_loadstore_operand" "")
347                  (const_int 8) (const_int 4))
349              (eq_attr "type" "move,unary,compare")
350              (if_then_else (match_operand 1 "long_immediate_operand" "")
351                            (const_int 8) (const_int 4))
353              (eq_attr "type" "binary")
354              (if_then_else (match_operand 2 "long_immediate_operand" "")
355                            (const_int 8) (const_int 4))
357              (eq_attr "type" "cmove")
358              (if_then_else (match_operand 1 "register_operand" "")
359                            (const_int 4) (const_int 8)) 
361              (eq_attr "type" "multi") (const_int 8)
362                      (eq_attr "cond" "set,set_zn,clob") (const_int 8)
363             ]
365             (const_int 4))
367     (eq_attr "iscompact" "true,maybe")
368     ; The length can vary because of ADJUST_INSN_LENGTH.
369     ; make sure that variable_length_p will be true.
370     (cond
371       [(and (ne (symbol_ref "0") (const_int 0)) (eq (match_dup 0) (pc)))
372        (const_int 4)
373        (eq_attr "verify_short" "yes")
374        (const_int 2)]
375       (const_int 4))
376   
377     (eq_attr "iscompact" "true_limm,maybe_limm")
378     (cond
379       [(and (ne (symbol_ref "0") (const_int 0)) (eq (match_dup 0) (pc)))
380        (const_int 8)
381        (eq_attr "verify_short" "yes")
382        (const_int 6)]
383       (const_int 8))
386           (cond [(eq_attr "type" "load")
387                  (if_then_else
388                     (match_operand 1 "long_immediate_loadstore_operand" "")
389                     (const_int 8) (const_int 4))
391                  (eq_attr "type" "store")
392                  (if_then_else
393                    (ior (match_operand 0 "long_immediate_loadstore_operand" "")
394                         (match_operand 1 "immediate_operand" ""))
395                    (const_int 8) (const_int 4))
397                  (eq_attr "type" "move,unary")
398                  (if_then_else (match_operand 1 "long_immediate_operand" "")
399                                (const_int 8) (const_int 4))
401 ;; Added this for adjusting length of nops, for bbit offset calculation to be correct
403                  (eq_attr "type" "compare")
404                  (if_then_else (match_operand 1 "long_immediate_operand" "")
405                                (if_then_else (eq_attr "cpu" "ARC700") 
406                                              (const_int 8) (const_int 12))
407 ;                              (const_int 8) 
408                                (if_then_else (eq_attr "cpu" "ARC700") 
409                                             (const_int 4) (const_int 8)))
412                  (and (eq_attr "type" "shift")
413                       (match_operand 1 "immediate_operand"))
414                  (const_int 8)
415                  (eq_attr "type" "binary,shift")
416                  (if_then_else
417                     (ior (match_operand 2 "long_immediate_operand" "")
418                          (and (ne (symbol_ref "REGNO(operands[0])")
419                                   (symbol_ref "REGNO(operands[1])"))
420                               (eq (match_operand 2 "u6_immediate_operand" "")
421                                   (const_int 0))))
422                             
423                     (const_int 8) (const_int 4))
425                  (eq_attr "type" "cmove")
426                     (if_then_else (match_operand 1 "register_operand" "")
427                                   (const_int 4) (const_int 8)) 
429                  (eq_attr "type" "call_no_delay_slot") (const_int 8)
430                 ]
432                 (const_int 4))
435 ;; The length here is the length of a single asm.  Unfortunately it might be
436 ;; 4 or 8 so we must allow for 8.  That's ok though.  How often will users
437 ;; lament asm's not being put in delay slots?
439 (define_asm_attributes
440   [(set_attr "length" "8")
441    (set_attr "type" "multi")
442    (set_attr "cond" "clob") ])
444 ;; Delay slots.
445 ;; The first two cond clauses and the default are necessary for correctness;
446 ;; the remaining cond clause is mainly an optimization, as otherwise nops
447 ;; would be inserted; however, if we didn't do this optimization, we would
448 ;; have to be more conservative in our length calculations.
450 (define_attr "in_delay_slot" "false,true"
451   (cond [(eq_attr "type" "uncond_branch,jump,branch,
452                           call,sfunc,call_no_delay_slot, 
453                           brcc, brcc_no_delay_slot,loop_setup,loop_end")
454          (const_string "false")
455          (ne (symbol_ref "arc_write_ext_corereg (insn)") (const_int 0))
456          (const_string "false")
457          (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
458                                       next_active_insn (insn))")
459              (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
460                            + arc_hazard (insn, next_active_insn (insn)))"))
461          (const_string "false")
462          ]
464          (if_then_else (eq_attr "length" "2,4")
465                        (const_string "true")
466                        (const_string "false"))))
468 ; must not put an insn inside that refers to blink.
469 (define_attr "in_call_delay_slot" "false,true"
470   (cond [(eq_attr "in_delay_slot" "false")
471          (const_string "false")
472          (ne (symbol_ref "arc_regno_use_in (RETURN_ADDR_REGNUM,
473                                             PATTERN (insn))")
474              (const_int 0))
475          (const_string "false")]
476         (const_string "true")))
478 (define_attr "in_sfunc_delay_slot" "false,true"
479   (cond [(eq_attr "in_call_delay_slot" "false")
480          (const_string "false")
481          (ne (symbol_ref "arc_regno_use_in (12, PATTERN (insn))")
482              (const_int 0))
483          (const_string "false")]
484         (const_string "true")))
486 ;; Instructions that we can put into a delay slot and conditionalize.
487 (define_attr "cond_delay_insn" "no,yes"
488   (cond [(eq_attr "cond" "!canuse") (const_string "no")
489          (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
490          (const_string "no")
491          (eq_attr "length" "2,4") (const_string "yes")]
492         (const_string "no")))
494 (define_attr "in_ret_delay_slot" "no,yes"
495   (cond [(eq_attr "in_delay_slot" "false")
496          (const_string "no")
497          (ne (symbol_ref "regno_clobbered_p
498                             (arc_return_address_regs
499                               [arc_compute_function_type (cfun)],
500                              insn, SImode, 1)")
501              (const_int 0))
502          (const_string "no")]
503         (const_string "yes")))
505 (define_attr "cond_ret_delay_insn" "no,yes"
506   (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
507          (eq_attr "cond_delay_insn" "no") (const_string "no")]
508         (const_string "yes")))
511 (define_delay (and (eq_attr "type" "call,branch,uncond_branch,jump")
512                    (ne (symbol_ref "TARGET_A4") (const_int 0)))
513   [(eq_attr "in_delay_slot" "true")
514    (eq_attr "in_delay_slot" "true")
515    (eq_attr "in_delay_slot" "true")])
517 ;; Delay slot definition for ARCompact ISA
518 ;; ??? FIXME:
519 ;; When outputting an annul-true insn elegible for cond-exec
520 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
521 ;; for ARC600; we could also use this for ARC700 if the branch can't be
522 ;; unaligned and is at least somewhat likely (add parameter for this).
524 ;; (define_delay (and (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
525 ;;                    (ne (symbol_ref "TARGET_ARCOMPACT") (const_int 0)))
526 ;;   [(eq_attr "in_delay_slot" "true")
527 ;;    (eq_attr "in_delay_slot" "true")
528 ;;    (nil)])
529 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT") (const_int 0))
530                    (eq_attr "type" "call"))
531   [(eq_attr "in_call_delay_slot" "true")
532    (eq_attr "in_call_delay_slot" "true")
533    (nil)])
535 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT
536                                     && !TARGET_AT_DBR_CONDEXEC")
537                        (const_int 0))
538                    (eq_attr "type" "brcc"))
539   [(eq_attr "in_delay_slot" "true")
540    (eq_attr "in_delay_slot" "true")
541    (nil)])
543 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT && TARGET_AT_DBR_CONDEXEC")
544                        (const_int 0))
545                    (eq_attr "type" "brcc"))
546   [(eq_attr "in_delay_slot" "true")
547    (nil)
548    (nil)])
550 (define_delay
551   (and (ne (symbol_ref "TARGET_ARCOMPACT")
552            (const_int 0))
553        (eq_attr "type" "return"))
554   [(eq_attr "in_ret_delay_slot" "yes")
555    (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
556    (eq_attr "cond_ret_delay_insn" "yes")])
558 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
559 ;; non-taken case, so the only meaningful way to have an annull-true
560 ;; filled delay slot is to conditionalize the delay slot insn.
561 (define_delay (and (ne (symbol_ref "TARGET_AT_DBR_CONDEXEC") (const_int 0))
562                    (eq_attr "type" "branch,uncond_branch,jump")
563                    (eq (symbol_ref "optimize_size") (const_int 0)))
564   [(eq_attr "in_delay_slot" "true")
565    (eq_attr "cond_delay_insn" "yes")
566    (eq_attr "cond_delay_insn" "yes")])
568 ;; For ARC700, anything goes for annulled-true insns, since there is no
569 ;; penalty for the unexposed delay slot when the branch is not taken,
570 ;; however, we must avoid things that have a delay slot themselvese to
571 ;; avoid confucing gcc.
572 (define_delay (and (ne (symbol_ref "!TARGET_AT_DBR_CONDEXEC") (const_int 0))
573                    (eq_attr "type" "branch,uncond_branch,jump")
574                    (eq (symbol_ref "optimize_size") (const_int 0)))
575   [(eq_attr "in_delay_slot" "true")
576    (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
577    (eq_attr "cond_delay_insn" "yes")])
579 ;; -mlongcall -fpic sfuncs use r12 to load the function address
580 (define_delay (and  (ne (symbol_ref "TARGET_ARCOMPACT") (const_int 0))
581                     (eq_attr "type" "sfunc"))
582   [(eq_attr "in_sfunc_delay_slot" "true")
583    (eq_attr "in_sfunc_delay_slot" "true")
584    (nil)])
585 ;; ??? need to use a working strategy for canuse_limm:
586 ;; - either canuse_limm is not eligible for delay slots, and has no
587 ;;   delay slots, or arc_reorg has to treat them as nocond, or it has to
588 ;;   somehow modify them to become inelegible for delay slots if a decision
589 ;;   is made that makes conditional execution required.
591 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
592   (const
593    (cond [(symbol_ref "arc_tune == TUNE_ARC600")
594           (const_string "arc600")
595           (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
596           (const_string "arc700_4_2_std")
597           (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
598           (const_string "arc700_4_2_xmac")]
599          (const_string "none"))))
601 (define_attr "tune_arc700" "false,true"
602   (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
603                 (const_string "true")
604                 (const_string "false")))
606 ;; Function units of the ARC
608 ;; (define_function_unit {name} {num-units} {n-users} {test}
609 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
611 ;; 1) A conditional jump cannot immediately follow the insn setting the flags in pre ARC700 processors.
612 ;; The ARC700 has no problems with consecutive instructions setting and
613 ;; using flags.
614 ;; (define_function_unit "compare" 1 0 (and (eq_attr "type" "compare") (not (eq_attr "cpu" "ARC700"))) 2 2 [(eq_attr "type" "branch")])
615 ;; (define_function_unit "compare" 1 0 (and (eq_attr "type" "compare") (eq_attr "cpu" "ARC700") ) 1 1 [(eq_attr "type" "branch")])
617 ;; 2) References to loaded registers should wait a cycle.
619 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
620 ;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
622 ;; Units that take one cycle do not need to be specified.
624 ;; Move instructions.
625 (define_expand "movqi"
626   [(set (match_operand:QI 0 "move_dest_operand" "")
627         (match_operand:QI 1 "general_operand" ""))]
628   ""
629   "if (prepare_move_operands (operands, QImode)) DONE;")
631 ; In order to allow the ccfsm machinery to do its work, the leading compact
632 ; alternatives say 'canuse' - there is another alternative that will match
633 ; when the condition codes are used.
634 ; Rcq won't match if the condition is actually used; to avoid a spurious match
635 ; via q, q is inactivated as constraint there.
636 ; Likewise, the length of an alternative that might be shifted to conditional
637 ; execution must reflect this, lest out-of-range branches are created.
638 ; The iscompact attribute allows the epilogue expander to know for which
639 ; insns it should lengthen the return insn.
640 (define_insn "*movqi_insn"
641   [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
642         (match_operand:QI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
643   "register_operand (operands[0], QImode)
644    || register_operand (operands[1], QImode)"
645   "@
646    mov%? %0,%1%&
647    mov%? %0,%1%&
648    mov%? %0,%1%&
649    mov%? %0,%1
650    mov%? %0,%1
651    mov%? %0,%1
652    mov%? %0,%S1
653    ldb%? %0,%1%&
654    stb%? %1,%0%&
655    ldb%? %0,%1%&
656    ldb%U1%V1 %0,%1
657    stb%U0%V0 %1,%0
658    stb%U0%V0 %1,%0"
659   [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
660    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
661    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse_limm,canuse,canuse,nocond,nocond,nocond,nocond,nocond,nocond")])
663 (define_expand "movhi"
664   [(set (match_operand:HI 0 "move_dest_operand" "")
665         (match_operand:HI 1 "general_operand" ""))]
666   ""
667   "if (prepare_move_operands (operands, HImode)) DONE;")
669 (define_insn "*movhi_insn"
670   [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
671         (match_operand:HI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,  ?i,?i,T,Rcq,m,c,?Rac,i"))]
672   "register_operand (operands[0], HImode)
673    || register_operand (operands[1], HImode)
674    || (CONSTANT_P (operands[1])
675        /* Don't use a LIMM that we could load with a single insn - we loose
676           delay-slot filling opportunities.  */
677        && !satisfies_constraint_I (operands[1])
678        && satisfies_constraint_Usc (operands[0]))"
679   "@
680    mov%? %0,%1%&
681    mov%? %0,%1%&
682    mov%? %0,%1%&
683    mov%? %0,%1
684    mov%? %0,%1
685    mov%? %0,%1
686    mov%? %0,%S1%&
687    mov%? %0,%S1
688    ldw%? %0,%1%&
689    stw%? %1,%0%&
690    ldw%U1%V1 %0,%1
691    stw%U0%V0 %1,%0
692    stw%U0%V0 %1,%0
693    stw%U0%V0 %S1,%0"
694   [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
695    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
696    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse_limm,canuse,canuse,canuse,nocond,nocond,nocond,nocond,nocond,nocond")])
698 (define_expand "movsi"
699   [(set (match_operand:SI 0 "move_dest_operand" "")
700         (match_operand:SI 1 "general_operand" ""))]
701   ""
702   "if (prepare_move_operands (operands, SImode)) DONE;")
705 ; In order to allow the ccfsm machinery to do its work, the leading compact
706 ; alternatives say 'canuse' - there is another alternative that will match
707 ; when the condition codes are used.
708 ; Rcq won't match if the condition is actually used; to avoid a spurious match
709 ; via q, q is inactivated as constraint there.
710 ; Likewise, the length of an alternative that might be shifted to conditional
711 ; execution must reflect this, lest out-of-range branches are created.
712 ; the iscompact attribute allows the epilogue expander to know for which
713 ; insns it should lengthen the return insn.
714 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
715 (define_insn "*movsi_insn"
716   [(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")
717         (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"))]
718   "register_operand (operands[0], SImode)
719    || register_operand (operands[1], SImode)
720    || (CONSTANT_P (operands[1])
721        /* Don't use a LIMM that we could load with a single insn - we loose
722           delay-slot filling opportunities.  */
723        && !satisfies_constraint_I (operands[1])
724        && satisfies_constraint_Usc (operands[0]))"
725   "@
726    mov%? %0,%1%&
727    mov%? %0,%1%&
728    mov%? %0,%1%&
729    mov%? %0,%1
730    mov%? %0,%1
731    ror %0,((%1*2+1) & 0x3f)
732    mov%? %0,%1
733    add %0,%S1
734    * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
735    mov%? %0,%S1%&
736    mov%? %0,%S1
737    ld%? %0,%1%&
738    st%? %1,%0%&
739    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
740    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
741    ld%? %0,%1%&
742    ld%U1%V1 %0,%1
743    st%U0%V0 %1,%0
744    st%U0%V0 %1,%0
745    st%U0%V0 %S1,%0"
746   [(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")
747    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
748    ; Use default length for iscompact to mark length varying.  But set length
749    ; of Crr to 4.
750    (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
751    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse_limm,canuse_limm,canuse,nocond,nocond,canuse,canuse,nocond,nocond,nocond,nocond,nocond,nocond,nocond,nocond,nocond")])
753 ;; sometimes generated by the epilogue code.  We don't want to
754 ;; recognize these addresses in general, because the limm is costly,
755 ;; and we can't use them for stores.  */
756 (define_insn "*movsi_pre_mod"
757   [(set (match_operand:SI 0 "register_operand" "=w")
758         (mem:SI (pre_modify
759                   (reg:SI SP_REG)
760                   (plus:SI (reg:SI SP_REG)
761                            (match_operand 1 "immediate_operand" "Cal")))))]
762   "reload_completed"
763   "ld.a %0,[sp,%1]"
764   [(set_attr "type" "load")
765    (set_attr "length" "8")])
767 /* Store a value to directly to memory.  The location might also be cached.
768    Since the cached copy can cause a write-back at unpredictable times,
769    we first write cached, then we write uncached.  */
770 (define_insn "store_direct"
771   [(set (match_operand:SI 0 "move_dest_operand" "=m")
772       (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
773        UNSPEC_DIRECT))]
774   ""
775   "st%U0 %1,%0\;st%U0.di %1,%0"
776   [(set_attr "type" "store")])
778 (define_insn "*movsi_set_cc_insn"
779   [(set (match_operand:CC_ZN 2 "cc_set_register" "")
780         (match_operator 3 "zn_compare_operator"
781           [(match_operand:SI 1 "nonmemory_operand" "cI,Cal") (const_int 0)]))
782    (set (match_operand:SI 0 "register_operand" "=w,w")
783         (match_dup 1))]
784   ""
785   "mov%?.f %0,%S1"
786   [(set_attr "type" "compare")
787    (set_attr "cond" "set_zn")
788    (set_attr "length" "4,8")])
790 (define_insn "unary_comparison"
791   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
792         (match_operator 3 "zn_compare_operator"
793           [(match_operator:SI 2 "unary_operator"
794              [(match_operand:SI 1 "register_operand" "c")])
795            (const_int 0)]))]
796   ""
797   "%O2.f 0,%1"
798   [(set_attr "type" "compare")
799    (set_attr "cond" "set_zn")])
802 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
803 (define_insn "*unary_comparison_result_used"
804   [(set (match_operand 2 "cc_register" "")
805         (match_operator 4 "zn_compare_operator"
806           [(match_operator:SI 3 "unary_operator"
807              [(match_operand:SI 1 "register_operand" "c")])
808                (const_int 0)]))
809    (set (match_operand:SI 0 "register_operand" "=w")
810         (match_dup 3))]
811   ""
812   "%O3.f %0,%1"
813   [(set_attr "type" "compare")
814    (set_attr "cond" "set_zn")
815    (set_attr "length" "4")])
817 (define_insn "*tst"
818   [(set
819      (match_operand 0 "cc_register" "")
820      (match_operator 3 "zn_compare_operator"
821        [(and:SI
822           (match_operand:SI 1 "register_operand"  "%Rcq,Rcq, c,  c,  c,  c,  c")
823           (match_operand:SI 2 "nonmemory_operand"  "Rcq,C0p,cI,C1p,Ccp,CnL,Cal"))
824         (const_int 0)]))]
825   "TARGET_ARCOMPACT
826    && ((register_operand (operands[1], SImode)
827        && nonmemory_operand (operands[2], SImode))
828       || (memory_operand (operands[1], SImode)
829           && satisfies_constraint_Cux (operands[2])))"
830   "*
831     switch (which_alternative)
832     {
833     case 0: case 2: case 6:
834       return \"tst%? %1,%2\";
835     case 1:
836       return \"btst%? %1,%z2\";
837     case 3:
838       return \"bmsk%?.f 0,%1,%Z2%&\";
839     case 4:
840       return \"bclr%?.f 0,%1,%M2%&\";
841     case 5:
842       return \"bic%?.f 0,%1,%n2-1\";
843     default:
844       gcc_unreachable ();
845     }
846   "
847   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false")
848    (set_attr "type" "compare")
849    (set_attr "length" "*,*,4,4,4,4,8")
850    (set_attr "cond" "set_zn")])
852 (define_insn "*commutative_binary_comparison"
853   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
854         (match_operator 5 "zn_compare_operator"
855           [(match_operator:SI 4 "commutative_operator"
856              [(match_operand:SI 1 "register_operand" "%c,c,c")
857               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
858            (const_int 0)]))
859    (clobber (match_scratch:SI 3 "=X,1,X"))]
860   ""
861   "%O4.f 0,%1,%2"
862   [(set_attr "type" "compare")
863    (set_attr "cond" "set_zn")
864    (set_attr "length" "4,4,8")])
866 ; for flag setting 'add' instructions like if (a+b) { ...}
867 ; the combiner needs this pattern
868 (define_insn "*addsi_compare"
869   [(set (reg:CC_ZN CC_REG)
870         (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
871                        (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
872   ""
873   "add.f 0,%0,%1"
874   [(set_attr "cond" "set")
875    (set_attr "type" "compare")
876    (set_attr "length" "4")])
878 ; for flag setting 'add' instructions like if (a+b < a) { ...}
879 ; the combiner needs this pattern
880 (define_insn "addsi_compare_2"
881   [(set (reg:CC_C CC_REG)
882         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
883                                (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
884                       (match_dup 0)))]
885   ""
886   "add.f 0,%0,%1"
887   [(set_attr "cond" "set")
888    (set_attr "type" "compare")
889    (set_attr "length" "4,8")])
891 (define_insn "*addsi_compare_3"
892   [(set (reg:CC_C CC_REG)
893         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
894                                (match_operand:SI 1 "register_operand" "c"))
895                       (match_dup 1)))]
896   ""
897   "add.f 0,%0,%1"
898   [(set_attr "cond" "set")
899    (set_attr "type" "compare")
900    (set_attr "length" "4")])
902 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
903 (define_insn "*commutative_binary_comparison_result_used"
904   [(set (match_operand 3 "cc_register" "")
905         (match_operator 5 "zn_compare_operator"
906           [(match_operator:SI 4 "commutative_operator"
907              [(match_operand:SI 1 "register_operand" "c,0,c")
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         (match_dup 4))]
912   ""
913   "%O4.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 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
919 (define_insn "*noncommutative_binary_comparison_result_used"
920   [(set (match_operand 3 "cc_register" "")
921         (match_operator 5 "zn_compare_operator"
922           [(match_operator:SI 4 "noncommutative_operator"
923              [(match_operand:SI 1 "register_operand" "c,0,c")
924               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
925                (const_int 0)]))
926    (set (match_operand:SI 0 "register_operand" "=w,w,w")
927         (match_dup 4 ))]
928   ""
929   "%O4.f %0,%1,%2"
930   [(set_attr "type" "compare,compare,compare")
931    (set_attr "cond" "set_zn,set_zn,set_zn")
932    (set_attr "length" "4,4,8")])
934 (define_insn "*noncommutative_binary_comparison"
935   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
936         (match_operator 5 "zn_compare_operator"
937           [(match_operator:SI 4 "noncommutative_operator"
938              [(match_operand:SI 1 "register_operand" "c,c,c")
939               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
940            (const_int 0)]))
941    (clobber (match_scratch:SI 3 "=X,1,X"))]
942   ""
943   "%O4.f 0,%1,%2"
944   [(set_attr "type" "compare")
945    (set_attr "cond" "set_zn")
946    (set_attr "length" "4,4,8")])
948 (define_expand "movdi"
949   [(set (match_operand:DI 0 "move_dest_operand" "")
950         (match_operand:DI 1 "general_operand" ""))]
951   ""
952   "
954   /* Everything except mem = const or mem = mem can be done easily.  */
956   if (GET_CODE (operands[0]) == MEM)
957     operands[1] = force_reg (DImode, operands[1]);
960 (define_insn_and_split "*movdi_insn"
961   [(set (match_operand:DI 0 "move_dest_operand" "=w,w,r,m")
962         (match_operand:DI 1 "move_double_src_operand" "c,HJi,m,c"))]
963   "register_operand (operands[0], DImode)
964    || register_operand (operands[1], DImode)"
965   "*
967   switch (which_alternative)
968     {
969     default:
970     case 0 :
971       /* We normally copy the low-numbered register first.  However, if
972          the first register operand 0 is the same as the second register of
973          operand 1, we must copy in the opposite order.  */
974       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
975         return \"mov%? %R0,%R1\;mov%? %0,%1\";
976       else
977       return \"mov%? %0,%1\;mov%? %R0,%R1\";
978     case 1 :
979       return \"mov%? %L0,%L1\;mov%? %H0,%H1\";
980     case 2 :
981       /* If the low-address word is used in the address, we must load it
982          last.  Otherwise, load it first.  Note that we cannot have
983          auto-increment in that case since the address register is known to be
984          dead.  */
985       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
986                              operands [1], 0))
987         return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
988       else switch (GET_CODE (XEXP(operands[1], 0)))
989         {
990         case POST_MODIFY: case POST_INC: case POST_DEC:
991           return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\";
992         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
993           return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\";
994         default:
995           return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\";
996         }
997     case 3 :
998       switch (GET_CODE (XEXP(operands[0], 0)))
999         {
1000         case POST_MODIFY: case POST_INC: case POST_DEC:
1001           return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\";
1002         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
1003           return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\";
1004         default:
1005           return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\";
1006         }
1007     }
1009   "&& reload_completed && optimize"
1010   [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
1011   "arc_split_move (operands);"
1012   [(set_attr "type" "move,move,load,store")
1013    ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1014    (set_attr "length" "8,16,16,16")])
1017 ;; Floating point move insns.
1019 (define_expand "movsf"
1020   [(set (match_operand:SF 0 "general_operand" "")
1021         (match_operand:SF 1 "general_operand" ""))]
1022   ""
1023   "if (prepare_move_operands (operands, SFmode)) DONE;")
1025 (define_insn "*movsf_insn"
1026   [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m")
1027         (match_operand:SF 1 "move_src_operand" "c,E,m,c"))]
1028   "register_operand (operands[0], SFmode)
1029    || register_operand (operands[1], SFmode)"
1030   "@
1031    mov%? %0,%1
1032    mov%? %0,%1 ; %A1
1033    ld%U1%V1 %0,%1
1034    st%U0%V0 %1,%0"
1035   [(set_attr "type" "move,move,load,store")])
1037 (define_expand "movdf"
1038   [(set (match_operand:DF 0 "general_operand" "")
1039         (match_operand:DF 1 "general_operand" ""))]
1040   ""
1041   "if (prepare_move_operands (operands, DFmode)) DONE;")
1043 (define_insn_and_split "*movdf_insn"
1044   [(set (match_operand:DF 0 "move_dest_operand"      "=w,w,r,m,D,r")
1045         (match_operand:DF 1 "move_double_src_operand" "c,E,m,c,r,D"))]
1046   "register_operand (operands[0], DFmode)
1047    || register_operand (operands[1], DFmode)"
1048   "*
1050   switch (which_alternative)
1051     {
1052     default:
1053     case 0 :
1054       /* We normally copy the low-numbered register first.  However, if
1055          the first register operand 0 is the same as the second register of
1056          operand 1, we must copy in the opposite order.  */
1057       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1058         return \"mov %R0,%R1\;mov %0,%1\";
1059       else
1060       return \"mov%? %0,%1\;mov%? %R0,%R1\";
1061     case 1 :
1062       return \"mov%? %L0,%L1\;mov%? %H0,%H1 ; %A1\";
1063     case 2 :
1064       /* If the low-address word is used in the address, we must load it
1065          last.  Otherwise, load it first.  Note that we cannot have
1066          auto-increment in that case since the address register is known to be
1067          dead.  */
1068       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
1069                              operands [1], 0))
1070         return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
1071       else switch (GET_CODE (XEXP(operands[1], 0)))
1072         {
1073         case POST_MODIFY: case POST_INC: case POST_DEC:
1074           return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\";
1075         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
1076           return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\";
1077         default:
1078           return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\";
1079         }
1080     case 3 :
1081       switch (GET_CODE (XEXP(operands[0], 0)))
1082         {
1083         case POST_MODIFY: case POST_INC: case POST_DEC:
1084           return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\";
1085         case PRE_MODIFY: case PRE_INC: case PRE_DEC:
1086           return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\";
1087         default:
1088           return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\";
1089         }
1090     case 4:
1091         if (!TARGET_DPFP)
1092           {
1093             fatal_error (\"DPFP register allocated without -mdpfp\\n\");
1094           }
1095         return \"dexcl%F0 0, %H1, %L1\";
1096     case 5:
1097         return \"lr %H0,[%H1h]\;lr %L0,[%H1l] ; double reg moves\";
1099     }
1101   "&& reload_completed && optimize
1102    /* Don't touch the DOUBLE_REGS alternatives.  */
1103    && !refers_to_regno_p (40, 44, operands[0], 0)
1104    && !refers_to_regno_p (40, 44, operands[1], 0)"
1105   [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
1106   "arc_split_move (operands);"
1107   [(set_attr "type" "move,move,load,store, move,lr")
1108    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
1109    ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1110    (set_attr "length" "8,16,16,16,4,16")])
1112 ;; Load/Store with update instructions.
1114 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1115 ;; hardware can also do cases where the increment is not the size of the
1116 ;; object.
1118 ;; In all these cases, we use operands 0 and 1 for the register being
1119 ;; incremented because those are the operands that local-alloc will
1120 ;; tie and these are the pair most likely to be tieable (and the ones
1121 ;; that will benefit the most).
1123 ;; We use match_operator here because we need to know whether the memory
1124 ;; object is volatile or not.
1127 ;; Note: loadqi_update has no 16-bit variant
1128 (define_insn "*loadqi_update"
1129   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1130         (match_operator:QI 4 "load_update_operand"
1131          [(match_operand:SI 1 "register_operand" "0,0")
1132           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1133    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1134         (plus:SI (match_dup 1) (match_dup 2)))]
1135   ""
1136   "ldb.a%V4 %3,[%0,%S2]"
1137   [(set_attr "type" "load,load")
1138    (set_attr "length" "4,8")])
1140 (define_insn "*load_zeroextendqisi_update"
1141   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1142         (zero_extend:SI (match_operator:QI 4 "load_update_operand"
1143                          [(match_operand:SI 1 "register_operand" "0,0")
1144                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1145    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1146         (plus:SI (match_dup 1) (match_dup 2)))]
1147   ""
1148   "ldb.a%V4 %3,[%0,%S2]"
1149   [(set_attr "type" "load,load")
1150    (set_attr "length" "4,8")])
1152 (define_insn "*load_signextendqisi_update"
1153   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1154         (sign_extend:SI (match_operator:QI 4 "load_update_operand"
1155                          [(match_operand:SI 1 "register_operand" "0,0")
1156                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1157    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1158         (plus:SI (match_dup 1) (match_dup 2)))]
1159   ""
1160   "ldb.x.a%V4 %3,[%0,%S2]"
1161   [(set_attr "type" "load,load")
1162    (set_attr "length" "4,8")])
1164 (define_insn "*storeqi_update"
1165   [(set (match_operator:QI 4 "store_update_operand"
1166          [(match_operand:SI 1 "register_operand" "0")
1167           (match_operand:SI 2 "short_immediate_operand" "I")])
1168         (match_operand:QI 3 "register_operand" "c"))
1169    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1170         (plus:SI (match_dup 1) (match_dup 2)))]
1171   ""
1172   "stb.a%V4 %3,[%0,%2]"
1173   [(set_attr "type" "store")
1174    (set_attr "length" "4")])
1176 ;; ??? pattern may have to be re-written
1177 ;; Note: no 16-bit variant for this pattern
1178 (define_insn "*loadhi_update"
1179   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1180         (match_operator:HI 4 "load_update_operand"
1181          [(match_operand:SI 1 "register_operand" "0,0")
1182           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1183    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1184         (plus:SI (match_dup 1) (match_dup 2)))]
1185   ""
1186   "ldw.a%V4 %3,[%0,%S2]"
1187   [(set_attr "type" "load,load")
1188    (set_attr "length" "4,8")])
1190 (define_insn "*load_zeroextendhisi_update"
1191   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1192         (zero_extend:SI (match_operator:HI 4 "load_update_operand"
1193                          [(match_operand:SI 1 "register_operand" "0,0")
1194                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1195    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1196         (plus:SI (match_dup 1) (match_dup 2)))]
1197   ""
1198   "ldw.a%V4 %3,[%0,%S2]"
1199   [(set_attr "type" "load,load")
1200    (set_attr "length" "4,8")])
1202 ;; Note: no 16-bit variant for this instruction
1203 (define_insn "*load_signextendhisi_update"
1204   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1205         (sign_extend:SI (match_operator:HI 4 "load_update_operand"
1206                          [(match_operand:SI 1 "register_operand" "0,0")
1207                           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1208    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1209         (plus:SI (match_dup 1) (match_dup 2)))]
1210   ""
1211   "ldw.x.a%V4 %3,[%0,%S2]"
1212   [(set_attr "type" "load,load")
1213    (set_attr "length" "4,8")])
1215 (define_insn "*storehi_update"
1216   [(set (match_operator:HI 4 "store_update_operand"
1217          [(match_operand:SI 1 "register_operand" "0")
1218           (match_operand:SI 2 "short_immediate_operand" "I")])
1219         (match_operand:HI 3 "register_operand" "c"))
1220    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1221         (plus:SI (match_dup 1) (match_dup 2)))]
1222   ""
1223   "stw.a%V4 %3,[%0,%2]"
1224   [(set_attr "type" "store")
1225    (set_attr "length" "4")])
1227 ;; No 16-bit variant for this instruction pattern
1228 (define_insn "*loadsi_update"
1229   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1230         (match_operator:SI 4 "load_update_operand"
1231          [(match_operand:SI 1 "register_operand" "0,0")
1232           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1233    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1234         (plus:SI (match_dup 1) (match_dup 2)))]
1235   ""
1236   "ld.a%V4 %3,[%0,%S2]"
1237   [(set_attr "type" "load,load")
1238    (set_attr "length" "4,8")])
1240 (define_insn "*storesi_update"
1241   [(set (match_operator:SI 4 "store_update_operand"
1242          [(match_operand:SI 1 "register_operand" "0")
1243           (match_operand:SI 2 "short_immediate_operand" "I")])
1244         (match_operand:SI 3 "register_operand" "c"))
1245    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1246         (plus:SI (match_dup 1) (match_dup 2)))]
1247   ""
1248   "st.a%V4 %3,[%0,%2]"
1249   [(set_attr "type" "store")
1250    (set_attr "length" "4")])
1252 (define_insn "*loadsf_update"
1253   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1254         (match_operator:SF 4 "load_update_operand"
1255          [(match_operand:SI 1 "register_operand" "0,0")
1256           (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1257    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1258         (plus:SI (match_dup 1) (match_dup 2)))]
1259   ""
1260   "ld.a%V4 %3,[%0,%S2]"
1261   [(set_attr "type" "load,load")
1262    (set_attr "length" "4,8")])
1264 (define_insn "*storesf_update"
1265   [(set (match_operator:SF 4 "store_update_operand"
1266          [(match_operand:SI 1 "register_operand" "0")
1267           (match_operand:SI 2 "short_immediate_operand" "I")])
1268         (match_operand:SF 3 "register_operand" "c"))
1269    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1270         (plus:SI (match_dup 1) (match_dup 2)))]
1271   ""
1272   "st.a%V4 %3,[%0,%2]"
1273   [(set_attr "type" "store")
1274    (set_attr "length" "4")])
1276 ;; Conditional move instructions.
1278 (define_expand "movsicc"
1279   [(set (match_operand:SI 0 "dest_reg_operand" "")
1280         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1281                          (match_operand:SI 2 "nonmemory_operand" "")
1282                          (match_operand:SI 3 "register_operand" "")))]
1283   ""
1284   "
1286   enum rtx_code code = GET_CODE (operands[1]);
1288   operands[1] = gen_compare_reg (code, VOIDmode);
1292 (define_expand "movdicc"
1293   [(set (match_operand:DI 0 "dest_reg_operand" "")
1294         (if_then_else:DI(match_operand 1 "comparison_operator" "")
1295                         (match_operand:DI 2 "nonmemory_operand" "")
1296                         (match_operand:DI 3 "register_operand" "")))]
1297   ""
1298   "
1300   enum rtx_code code = GET_CODE (operands[1]);
1302   operands[1] = gen_compare_reg (code, VOIDmode);
1306 (define_expand "movsfcc"
1307   [(set (match_operand:SF 0 "dest_reg_operand" "")
1308         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1309                       (match_operand:SF 2 "nonmemory_operand" "")
1310                       (match_operand:SF 3 "register_operand" "")))]
1311   ""
1312   "
1314   enum rtx_code code = GET_CODE (operands[1]);
1316   operands[1] = gen_compare_reg (code, VOIDmode);
1319 (define_expand "movdfcc"
1320   [(set (match_operand:DF 0 "dest_reg_operand" "")
1321         (if_then_else:DF (match_operand 1 "comparison_operator" "")
1322                       (match_operand:DF 2 "nonmemory_operand" "")
1323                       (match_operand:DF 3 "register_operand" "")))]
1324   ""
1325   "
1327   enum rtx_code code = GET_CODE (operands[1]);
1329   operands[1] = gen_compare_reg (code, VOIDmode);
1332 (define_insn "*movsicc_insn"
1333   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1334         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1335                        [(match_operand 4 "cc_register" "") (const_int 0)])
1336                       (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1337                       (match_operand:SI 2 "register_operand" "0,0")))]
1338   ""
1340   if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1341       && satisfies_constraint_Rcq (operands[0]))
1342     return "sub%?.ne %0,%0,%0";
1343   /* ??? might be good for speed on ARC600 too, *if* properly scheduled.  */
1344   if ((TARGET_ARC700 || optimize_size)
1345       && rtx_equal_p (operands[1], constm1_rtx)
1346       && GET_CODE (operands[3]) == LTU)
1347     return "sbc.cs %0,%0,%0";
1348   return "mov.%d3 %0,%S1";
1350   [(set_attr "type" "cmove,cmove")
1351    (set_attr "length" "4,8")])
1353 ; Try to generate more short moves, and/or less limms, by substituting a
1354 ; conditional move with a conditional sub.
1355 (define_peephole2
1356   [(set (match_operand:SI 0 "compact_register_operand")
1357         (match_operand:SI 1 "const_int_operand"))
1358    (set (match_dup 0)
1359         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1360                            [(match_operand 4 "cc_register" "") (const_int 0)])
1361                             (match_operand:SI 2 "const_int_operand" "")
1362                       (match_dup 0)))]
1363   "!satisfies_constraint_P (operands[1])
1364    && satisfies_constraint_P (operands[2])
1365    && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1366   [(set (match_dup 0) (match_dup 2))
1367    (cond_exec
1368      (match_dup 3)
1369      (set (match_dup 0)
1370           (plus:SI (match_dup 0) (match_dup 1))))]
1371   "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1372                                                     GET_MODE (operands[4])),
1373                                  VOIDmode, operands[4], const0_rtx);
1374    operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1376 (define_insn "*movdicc_insn"
1377   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1378         (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1379                         [(match_operand 4 "cc_register" "") (const_int 0)])
1380                       (match_operand:DI 1 "nonmemory_operand" "c,Ji")
1381                       (match_operand:DI 2 "register_operand" "0,0")))]
1382    ""
1383    "*
1385    switch (which_alternative)
1386      {
1387      default:
1388      case 0 :
1389        /* We normally copy the low-numbered register first.  However, if
1390          the first register operand 0 is the same as the second register of
1391          operand 1, we must copy in the opposite order.  */
1392        if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1393         return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1394        else
1395         return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1396      case 1 :
1397         return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1400      }
1402   [(set_attr "type" "cmove,cmove")
1403    (set_attr "length" "8,16")])
1406 (define_insn "*movsfcc_insn"
1407   [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1408         (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1409                        [(match_operand 4 "cc_register" "") (const_int 0)])
1410                       (match_operand:SF 1 "nonmemory_operand" "c,E")
1411                       (match_operand:SF 2 "register_operand" "0,0")))]
1412   ""
1413   "@
1414    mov.%d3 %0,%1
1415    mov.%d3 %0,%1 ; %A1"
1416   [(set_attr "type" "cmove,cmove")])
1418 (define_insn "*movdfcc_insn"
1419   [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1420         (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1421                  [(match_operand 4 "cc_register" "") (const_int 0)])
1422                       (match_operand:DF 2 "nonmemory_operand" "c,E")
1423                       (match_operand:DF 3 "register_operand" "0,0")))]
1424   ""
1425   "*
1427   switch (which_alternative)
1428     {
1429     default:
1430     case 0 :
1431       /* We normally copy the low-numbered register first.  However, if
1432          the first register operand 0 is the same as the second register of
1433          operand 1, we must copy in the opposite order.  */
1434       if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1435         return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1436       else
1437         return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1438     case 1 :
1439               return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1441     }
1443   [(set_attr "type" "cmove,cmove")
1444    (set_attr "length" "8,16")])
1447 ;; TODO - Support push_s and pop_s insns
1448 ;; PUSH/POP instruction
1449 ;(define_insn "*pushsi"
1450 ;  [(set (mem:SI (pre_dec:SI (reg:SI 28)))
1451 ;        (match_operand:SI 0 "register_operand" "q"))]
1452 ;  "TARGET_MIXED_CODE"
1453 ;  "push_s %0"
1454 ;  [(set_attr "type" "push")
1455 ;   (set_attr "iscompact" "true")
1456 ;   (set_attr "length" "2")])
1458 ;(define_insn "*popsi"
1459 ;  [(set (match_operand:SI 0 "register_operand" "=q")
1460 ;        (mem:SI (post_inc:SI (reg:SI 28))))]
1461 ;  "TARGET_MIXED_CODE"
1462 ;  "pop_s %0"
1463 ;  [(set_attr "type" "pop")
1464 ;   (set_attr "iscompact" "true")
1465 ;   (set_attr "length" "2")])
1467 ;; Zero extension instructions.
1468 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
1470 (define_insn "*zero_extendqihi2_a4"
1471   [(set (match_operand:HI 0 "dest_reg_operand" "=r")
1472         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1473   "TARGET_A4"
1474   "extb%? %0,%1"
1475   [(set_attr "type" "unary")])
1477 (define_insn "*zero_extendqihi2_i"
1478   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
1479         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
1480   ""
1481   "@
1482    extb%? %0,%1%&
1483    extb%? %0,%1%&
1484    bmsk%? %0,%1,7
1485    extb %0,%1
1486    ldb%U1 %0,%1"
1487   [(set_attr "type" "unary,unary,unary,unary,load")
1488    (set_attr "iscompact" "maybe,true,false,false,false")
1489    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond")])
1491 (define_expand "zero_extendqihi2"
1492   [(set (match_operand:HI 0 "dest_reg_operand" "")
1493         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1494   ""
1495   "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1498 ;; (define_insn "zero_extendqihi2"
1499 ;;   [(set (match_operand:HI 0 "register_operand" "=r,r")
1500 ;;      (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1501 ;;   ""
1502 ;;   "@
1503 ;;    extb %0,%1
1504 ;;    ldb%U1 %0,%1"
1505 ;;   [(set_attr "type" "unary,load")
1506 ;;    (set_attr "cond" "nocond,nocond")])
1508 (define_insn "*zero_extendqisi2_a4"
1509   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1510 ;       (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1511         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1512   "TARGET_A4"
1513   "@
1514    extb%? %0,%1
1515    ldb%U1 %0,%1"
1516   [(set_attr "type" "unary,load")])
1518 (define_insn "*zero_extendqisi2_ac"
1519   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
1520         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
1521   "TARGET_ARCOMPACT"
1522   "*
1523    switch (which_alternative)
1524    {
1525     case 0: case 1:
1526       return \"extb%? %0,%1%&\";
1527     case 2:
1528       return \"bmsk%? %0,%1,7\";
1529     case 3:
1530       return \"extb %0,%1\";
1531     case 4: case 5:
1532       return \"ldb%? %0,%1%&\";
1533     case 6:
1534       return \"ldb%U1 %0,%1\";
1535     default:
1536       gcc_unreachable ();
1537    }"
1538   [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1539    (set_attr "iscompact" "maybe,true,false,false,true,true,false")
1540    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,nocond,nocond")])
1542 (define_expand "zero_extendqisi2"
1543   [(set (match_operand:SI 0 "dest_reg_operand" "")
1544         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1545   ""
1546   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1548 ;   (set_attr "length" "2,4,8")
1550 ;; (define_insn "zero_extendqisi2"
1551 ;;   [(set (match_operand:SI 0 "register_operand" "=r,r")
1552 ;;      (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1553 ;;   ""
1554 ;;   "@
1555 ;;    extb %0,%1
1556 ;;    ldb%U1 %0,%1"
1557 ;;   [(set_attr "type" "unary,load")
1558 ;;    (set_attr "cond" "nocond,nocond")])
1560 (define_insn "*zero_extendhisi2_a4"
1561   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
1562         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1563   "TARGET_A4"
1564   "extw%? %0,%1"
1565   [(set_attr "type" "unary")])
1567 (define_insn "*zero_extendhisi2_i"
1568   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
1569         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
1570   ""
1571   "*
1572   switch (which_alternative)
1573     {
1574     case 0: case 1:
1575       return \"extw%? %0,%1%&\";
1576     case 2:
1577       return \"bmsk%? %0,%1,15\";
1578     case 3:
1579       return \"extw %0,%1\";
1580     case 4:
1581       return \"ldw%? %0,%1%&\";
1582     case 5:
1583       return \"ldw%U1 %0,%1\";
1584     case 6:
1585       return \"ldw%U1%V1 %0,%1\";
1586     default:
1587       gcc_unreachable ();
1588     }"
1589   [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1590    (set_attr "iscompact" "maybe,true,false,false,true,false,false")
1591    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,nocond,nocond")])
1594 (define_expand "zero_extendhisi2"
1595   [(set (match_operand:SI 0 "dest_reg_operand" "")
1596         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1597   ""
1598   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1601 ;; (define_insn "zero_extendhisi2"
1602 ;;   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1603 ;;      (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
1604 ;;   ""
1605 ;;   "@
1606 ;;    extw %0,%1
1607 ;;    ldw%U1 %0,%1"
1608 ;;   [(set_attr "type" "unary,load")
1609 ;;    (set_attr "cond" "nocond,nocond")])
1611 ;; Sign extension instructions.
1613 (define_insn "*extendqihi2_a4"
1614   [(set (match_operand:HI 0 "dest_reg_operand" "=r")
1615         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1616   "TARGET_A4"
1617   "sexb%? %0,%1"
1618   [(set_attr "type" "unary")])
1620 (define_insn "*extendqihi2_i"
1621   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
1622         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
1623   ""
1624   "@
1625    sexb%? %0,%1%&
1626    sexb %0,%1
1627    ldb.x%U1 %0,%1"
1628   [(set_attr "type" "unary,unary,load")
1629    (set_attr "iscompact" "true,false,false")
1630    (set_attr "cond" "nocond,nocond,nocond")])
1633 (define_expand "extendqihi2"
1634   [(set (match_operand:HI 0 "dest_reg_operand" "")
1635         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1636   ""
1637   "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1640 ;; (define_insn "extendqihi2"
1641 ;;   [(set (match_operand:HI 0 "register_operand" "=r,r")
1642 ;;      (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1643 ;;   ""
1644 ;;   "@
1645 ;;    sexb %0,%1
1646 ;;    ldb.x%U1 %0,%1"
1647 ;;   [(set_attr "type" "unary,load")
1648 ;;    (set_attr "cond" "nocond,nocond")])
1650 (define_insn "*extendqisi2_a4"
1651   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1652 ;       (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1653         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1654   "TARGET_A4"
1655   "@
1656     sexb%? %0,%1
1657     ldb.x%U1 %0,%1"
1658   [(set_attr "type" "unary,load")])
1660 ;; (define_insn "*extendqisi2_mixed"
1661 ;;   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1662 ;;      (sign_extend:SI (match_operand:QI 1 "compact_register_operand" "q")))]
1663 ;;   "TARGET_MIXED_CODE"
1664 ;;   "sexb_s %0,%1"
1665 ;;   [(set_attr "type" "unary")
1666 ;;    (set_attr "iscompact" "true")])
1668 (define_insn "*extendqisi2_ac"
1669   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1670         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1671   "TARGET_ARCOMPACT"
1672   "@
1673    sexb%? %0,%1%&
1674    sexb %0,%1
1675    ldb.x%U1 %0,%1"
1676   [(set_attr "type" "unary,unary,load")
1677    (set_attr "iscompact" "true,false,false")
1678    (set_attr "cond" "nocond,nocond,nocond")])
1680 (define_expand "extendqisi2"
1681   [(set (match_operand:SI 0 "dest_reg_operand" "")
1682         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1683   ""
1684   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1687 (define_insn "*extendhisi2_a4"
1688   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
1689         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1690   "TARGET_A4"
1691   "sexw%? %0,%1"
1692   [(set_attr "type" "unary")])
1694 ;; (define_insn "*extendhisi2_mixed"
1695 ;;   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1696 ;;      (sign_extend:SI (match_operand:HI 1 "compact_register_operand" "q")))]
1697 ;;   "TARGET_MIXED_CODE"
1698 ;;   "sexw_s %0,%1"
1699 ;;   [(set_attr "type" "unary")
1700 ;;    (set_attr "iscompact" "true")])
1703 (define_insn "*extendhisi2_i"
1704   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1705         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1706   ""
1707   "@
1708    sexw%? %0,%1%&
1709    sexw %0,%1
1710    ldw.x%U1%V1 %0,%1"
1711   [(set_attr "type" "unary,unary,load")
1712    (set_attr "iscompact" "true,false,false")
1713    (set_attr "cond" "nocond,nocond,nocond")])
1715 (define_expand "extendhisi2"
1716   [(set (match_operand:SI 0 "dest_reg_operand" "")
1717         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1718   ""
1719   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1722 ;; Unary arithmetic insns
1724 ;; We allow constant operands to enable late constant propagation, but it is
1725 ;; not worth while to have more than one dedicated alternative to output them -
1726 ;; if we are really worried about getting these the maximum benefit of all
1727 ;; the available alternatives, we should add an extra pass to fold such
1728 ;; operations to movsi.
1730 ;; Absolute instructions
1732 (define_insn "*abssi2_mixed"
1733   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1734         (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1735   "TARGET_MIXED_CODE"
1736   "abs%? %0,%1%&"
1737   [(set_attr "type" "two_cycle_core")
1738    (set_attr "iscompact" "true")])
1740 (define_insn "abssi2"
1741   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1742         (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1743   "TARGET_ARCOMPACT"
1744   "abs%? %0,%1%&"
1745   [(set_attr "type" "two_cycle_core")
1746    (set_attr "length" "*,4,8")
1747    (set_attr "iscompact" "true,false,false")
1748    (set_attr "cond" "nocond,nocond,nocond")])
1750 ;; Maximum and minimum insns
1752 (define_insn "smaxsi3"
1753    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1754          (smax:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1755                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1756   "TARGET_MINMAX"
1757   "max%? %0,%1,%2"
1758   [(set_attr "type" "two_cycle_core")
1759    (set_attr "length" "4,4,8")
1760    (set_attr "cond" "canuse,nocond,nocond")]
1763 (define_insn "sminsi3"
1764    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1765          (smin:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1766                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1767   "TARGET_MINMAX"
1768   "min%? %0,%1,%2"
1769   [(set_attr "type" "two_cycle_core")
1770    (set_attr "length" "4,4,8")
1771    (set_attr "cond" "canuse,nocond,nocond")]
1774 ;; Arithmetic instructions.
1775 ;; (define_insn "*addsi3_mixed"
1776 ;;   [(set (match_operand:SI 0 "compact_register_operand" "=q,q,q,r")
1777 ;;      (plus:SI (match_operand:SI 1 "compact_register_operand" "%q,0,0,r")
1778 ;;               (match_operand:SI 2 "nonmemory_operand" "qK,rO,Ji,rJi")))]
1779 ;;   "TARGET_MIXED_CODE"
1780 ;;   "*
1781 ;;    {
1782 ;;      switch (which_alternative)
1783 ;;      {
1784 ;;        case 0:
1785 ;;          return \"add_s %0,%1,%2\";
1786 ;;        case 1:
1787 ;;          return \"add_s %0,%1,%2\";
1788 ;;        case 12:
1789 ;;          if (INTVAL (operands[2]) < 0)
1790 ;;             return \"sub%? %0,%1,%n2\"; 
1791 ;;          else
1792 ;;            return \"add%? %0,%1,%2\";
1793 ;;        case 2:
1794 ;;          return \"add_s %0,%1,%S2\";
1795 ;;        case 3:
1796 ;;          return \"add%? %0,%1,%S2\";
1797 ;;        default:
1798 ;;          abort ();
1799 ;;      }
1800 ;;    }"
1801 ;;   [(set_attr "iscompact" "true,true,true,false")
1802 ;;    (set_attr "length" "*,*,6,8")
1803 ;;    (set_attr "cond" "nocond,nocond,nocond,canuse")])
1805 ; We say an insn can be conditionalized if this doesn't introduce a long
1806 ; immediate.  We set the type such that we still have good scheduling if the
1807 ; insn is conditionalized.
1808 ; ??? It would make sense to allow introduction of long immediates, but
1809 ;     we'd need to communicate to the ccfsm machinery the extra cost.
1810 ; The alternatives in the constraints still serve three purposes:
1811 ; - estimate insn size assuming conditional execution
1812 ; - guide reload to re-order the second and third operand to get a better fit.
1813 ; - give tentative insn type to guide scheduling
1814 ;   N.B. "%" for commutativity doesn't help when there is another matching
1815 ;   (but longer) alternative.
1816 (define_insn_and_split "*addsi3_mixed"
1817   ;;                                                      0       1   2   3   4   5   6    7     8    9     a   b c   d    e   f  10
1818   [(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")
1819         (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")
1820                  (match_operand:SI 2 "nonmemory_operand" "cL,     0, cL,  0,CL2,Csp,CM4,cCca,RcqqK,  cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1821   "TARGET_ARCOMPACT"
1822   "*if (which_alternative == 6)
1823       return arc_short_long (insn, \"add%? %0,%1,%2\", \"add1 %0,%1,%2/2\");
1824     return arc_output_addsi (operands,
1825                              arc_ccfsm_cond_exec_p () ? \"%?\" : \"\");"
1826   "&& reload_completed && get_attr_length (insn) == 8
1827    && satisfies_constraint_I (operands[2])"
1828   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1829   "split_addsi (operands);"
1830   [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*")
1831    (set (attr "iscompact")
1832         (cond [(eq (symbol_ref "*arc_output_addsi (operands, 0)") (const_int 0))
1833                (const_string "false")
1834                (match_operand 2 "long_immediate_operand" "")
1835                (const_string "maybe_limm")]
1836               (const_string "maybe")))
1837    (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8")
1838    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")])
1840 ;; (define_insn "*addsi3_mixed"
1841 ;;   [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,q,q,r,r,r,r,r,r,r,r,r")
1842 ;;      (plus:SI (match_operand:SI 1 "register_operand" "%q,0,0,0,0,r,0,r,0,0,r,0,r")
1843 ;;               (match_operand:SI 2 "nonmemory_operand" "qK,rO,J,i,r,r,L,L,I,J,J,i,i")))]
1844 ;;   ""
1845 ;;   "*
1846 ;;    {
1847 ;;      switch (which_alternative)
1848 ;;      {
1849 ;;        case 0:
1850 ;;          return \"add_s %0,%1,%2\";
1851 ;;        case 1:
1852 ;;          return \"add_s %0,%1,%2\";
1853 ;;        case 4:
1854 ;;          return \"add%? %0,%1,%2\";
1855 ;;        case 5:
1856 ;;          return \"add %0,%1,%2\";
1857 ;;        case 6:
1858 ;;          return \"add%? %0,%1,%2\";
1859 ;;        case 7:
1860 ;;          return \"add %0,%1,%2\";
1861 ;;        case 8:
1862 ;;          return \"add %0,%1,%2\";
1863 ;;        case 2:
1864 ;;          {
1865 ;;            int intval = INTVAL (operands[2]);
1866 ;;            if (intval < 0)
1867 ;;             {
1868 ;;               if (-intval< 0x20)
1869 ;;                 return \"sub_s %0,%1,%n2\"; 
1870 ;;               else
1871 ;;                 return \"sub %0,%1,%n2\"; 
1872 ;;             }
1873 ;;          else
1874 ;;            return \"add_s %0,%1,%2\";
1875 ;;          }
1876 ;;        case 3:
1877 ;;          return \"add_s %0,%1,%S2\";
1878 ;;        case 9:
1879 ;;          if (INTVAL (operands[2]) < 0)
1880 ;;             return \"sub%? %0,%1,%n2\"; 
1881 ;;          else
1882 ;;            return \"add%? %0,%1,%2\";
1883 ;;        case 10:
1884 ;;          if (INTVAL (operands[2]) < 0)
1885 ;;             return \"sub %0,%1,%n2\"; 
1886 ;;          else
1887 ;;            return \"add %0,%1,%2\";
1888 ;;        case 11:
1889 ;;          return \"add%? %0,%1,%S2\";
1890 ;;        case 12:
1891 ;;          return \"add %0,%1,%S2\";
1892 ;;        default:
1893 ;;          abort ();
1894 ;;      }
1895 ;;    }"
1896 ;;   [(set_attr "iscompact" "true,true,false,true,false,false,false,false,false,false,false,false,false")
1897 ;;    (set_attr "length" "2,2,8,6,4,4,4,4,4,8,8,8,8")
1898 ;;    (set_attr "cond" "nocond,nocond,nocond,nocond,canuse,nocond,canuse,nocond,nocond,canuse,nocond,canuse,nocond")])
1900 ;; ARC700/ARC600 multiply
1901 ;; SI <- SI * SI
1903 (define_expand "mulsi3"
1904  [(set (match_operand:SI 0 "nonimmediate_operand"            "")
1905         (mult:SI (match_operand:SI 1 "register_operand"  "")
1906                  (match_operand:SI 2 "nonmemory_operand" "")))]
1907   "(TARGET_ARC700 && !TARGET_NOMPY_SET)
1908     || TARGET_MUL64_SET || TARGET_MULMAC_32BY16_SET"
1909   "
1911   if ((TARGET_ARC700 && !TARGET_NOMPY_SET) &&
1912       !register_operand (operands[0], SImode))
1913     {
1914       rtx result = gen_reg_rtx (SImode);
1916       emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1917       emit_move_insn (operands[0], result);
1918       DONE;
1919     }
1920   else if (TARGET_MUL64_SET)
1921     {
1922       emit_insn (gen_mulsi_600 (operands[1], operands[2],
1923                                 gen_mlo (), gen_mhi ()));
1924       emit_move_insn (operands[0], gen_mlo ());
1925       DONE;
1926     }
1927   else if (TARGET_MULMAC_32BY16_SET)
1928     {
1929       if (immediate_operand (operands[2], SImode)
1930           && INTVAL (operands[2]) >= 0
1931           && INTVAL (operands[2]) <= 65535)
1932         {
1933           emit_insn (gen_umul_600 (operands[1], operands[2],
1934                                      gen_acc2 (), gen_acc1 ()));
1935           emit_move_insn (operands[0], gen_acc2 ());
1936           DONE;
1937         }
1938       operands[2] = force_reg (SImode, operands[2]);
1939       emit_insn (gen_umul_600 (operands[1], operands[2],
1940                                gen_acc2 (), gen_acc1 ()));
1941       emit_insn (gen_mac_600 (operands[1], operands[2],
1942                                gen_acc2 (), gen_acc1 ()));
1943       emit_move_insn (operands[0], gen_acc2 ());
1944       DONE;
1945     }
1948 ; mululw conditional execution without a LIMM clobbers an input register;
1949 ; we'd need a different pattern to describe this.
1950 (define_insn "umul_600"
1951   [(set (match_operand:SI 2 "acc2_operand" "")
1952         (mult:SI (match_operand:SI 0 "register_operand"  "c,c,c")
1953                  (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"  "c,L,J")
1954                                   (const_int 16)
1955                                   (const_int 0))))
1956    (clobber (match_operand:SI 3 "acc1_operand" ""))]
1957   "TARGET_MULMAC_32BY16_SET"
1958   "mululw%? 0, %0, %1"
1959   [(set_attr "length" "4,4,8")
1960    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1961    (set_attr "cond" "nocond, canuse_limm, canuse")])
1963 (define_insn "mac_600"
1964   [(set (match_operand:SI 2 "acc2_operand" "")
1965         (plus:SI
1966           (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1967                    (ashift:SI
1968                      (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,J")
1969                                       (const_int 16)
1970                                       (const_int 16))
1971                      (const_int 16)))
1972           (match_dup 2)))
1973    (clobber (match_operand:SI 3 "acc1_operand" ""))]
1974   "TARGET_MULMAC_32BY16_SET"
1975   "machlw%? 0, %0, %1"
1976   [(set_attr "length" "4,4,8")
1977    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1978    (set_attr "cond" "nocond, canuse_limm, canuse")])
1980 (define_insn "mulsi_600"
1981   [(set (match_operand:SI 2 "mlo_operand" "")
1982         (mult:SI (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c")
1983                  (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,J")))
1984    (clobber (match_operand:SI 3 "mhi_operand" ""))]
1985   "TARGET_MUL64_SET"
1986   "mul64%? \t0, %0, %1%&"
1987   [(set_attr "length" "*,4,4,8")
1988   (set_attr "iscompact" "maybe,false,false,false")
1989   (set_attr "type" "multi,multi,multi,multi")
1990    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1992 (define_insn "mulsidi_600"
1993   [(set (reg:DI 58)
1994         (mult:DI (sign_extend:DI
1995                    (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c"))
1996                  (sign_extend:DI
1997                    (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,J"))))]
1998   "TARGET_MUL64_SET"
1999   "mul64%? \t0, %0, %1%&"
2000   [(set_attr "length" "*,4,4,8")
2001   (set_attr "iscompact" "maybe,false,false,false")
2002   (set_attr "type" "multi,multi,multi,multi")
2003    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2005 (define_insn "umulsidi_600"
2006   [(set (reg:DI 58)
2007         (mult:DI (zero_extend:DI
2008                    (match_operand:SI 0 "register_operand"  "Rcq#q,c,c,%c"))
2009                  (sign_extend:DI
2010                    (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,J"))))]
2011   "TARGET_MUL64_SET"
2012   "mulu64%? \t0, %0, %1%&"
2013   [(set_attr "length" "*,4,4,8")
2014   (set_attr "iscompact" "maybe,false,false,false")
2015   (set_attr "type" "umulti")
2016    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2018 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2019 ; may not be used as destination constraint.
2021 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2022 ; but mpyu is faster for the standard multiplier.
2023 (define_insn "mulsi3_700"
2024  [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcr, r,r,Rcr,  r")
2025         (mult:SI (match_operand:SI 1 "register_operand"  " 0, c,0,  0,  c")
2026                  (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2027 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2028   "mpyu%? %0,%1,%2"
2029   [(set_attr "length" "4,4,4,8,8")
2030   (set_attr "type" "umulti")
2031   (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2034 (define_expand "mulsidi3"
2035   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2036         (mult:DI (sign_extend:DI(match_operand:SI 1 "register_operand" ""))
2037                  (sign_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2038   "(TARGET_ARC700 && !TARGET_NOMPY_SET)
2039    || TARGET_MULMAC_32BY16_SET"
2042   if ((TARGET_ARC700 && !TARGET_NOMPY_SET))
2043     {
2044       operands[2] = force_reg (SImode, operands[2]);
2045       if (!register_operand (operands[0], DImode))
2046         {
2047           rtx result = gen_reg_rtx (DImode);
2049           operands[2] = force_reg (SImode, operands[2]);
2050           emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2051           emit_move_insn (operands[0], result);
2052           DONE;
2053         }
2054     }
2055   if (TARGET_MUL64_SET)
2056     {
2057       operands[2] = force_reg (SImode, operands[2]);
2058       emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
2059       emit_move_insn (operands[0], gen_rtx_REG (DImode, 58));
2060     }
2061   else if (TARGET_MULMAC_32BY16_SET)
2062     {
2063       rtx result_hi = gen_highpart(SImode, operands[0]);
2064       rtx result_low = gen_lowpart(SImode, operands[0]);
2066       emit_insn (gen_mul64_600 (operands[1], operands[2]));
2067       emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2068       emit_move_insn (result_low, gen_acc2 ());
2069       DONE;
2070     }
2073 (define_insn "mul64_600"
2074   [(set (reg:DI 56)
2075         (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"  "c,c,c"))
2076                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"  "c,L,J")
2077                                   (const_int 16)
2078                                   (const_int 0))))
2079   ]
2080   "TARGET_MULMAC_32BY16_SET"
2081   "mullw%? 0, %0, %1"
2082   [(set_attr "length" "4,4,8")
2083    (set_attr "type" "mulmac_600")
2084    (set_attr "cond" "nocond, canuse_limm, canuse")])
2087 ;; ??? check if this is canonical rtl
2088 (define_insn "mac64_600"
2089   [(set (reg:DI 56)
2090         (plus:DI
2091           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2092                    (ashift:DI
2093                      (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,J")
2094                                       (const_int 16) (const_int 16))
2095                      (const_int 16)))
2096           (reg:DI 56)))
2097    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2098         (zero_extract:SI
2099           (plus:DI
2100             (mult:DI (sign_extend:DI (match_dup 1))
2101                      (ashift:DI
2102                        (sign_extract:DI (match_dup 2)
2103                                         (const_int 16) (const_int 16))
2104                           (const_int 16)))
2105             (reg:DI 56))
2106           (const_int 32) (const_int 32)))]
2107   "TARGET_MULMAC_32BY16_SET"
2108   "machlw%? %0, %1, %2"
2109   [(set_attr "length" "4,4,8")
2110    (set_attr "type" "mulmac_600")
2111    (set_attr "cond" "nocond, canuse_limm, canuse")])
2114 ;; DI <- DI(signed SI) * DI(signed SI)
2115 (define_insn_and_split "mulsidi3_700"
2116   [(set (match_operand:DI 0 "register_operand" "=&r")
2117         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2118                  (sign_extend:DI (match_operand:SI 2 "register_operand" "cL"))))]
2119   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2120   "#"
2121   "reload_completed"
2122   [(const_int 0)]
2124   int hi = !TARGET_BIG_ENDIAN;
2125   int lo = !hi;
2126   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2127   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2128   emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2129   emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
2130   DONE;
2132   [(set_attr "type" "multi")
2133    (set_attr "length" "8")])
2135 (define_insn "mulsi3_highpart"
2136   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
2137         (truncate:SI
2138          (lshiftrt:DI
2139           (mult:DI
2140            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
2141            (sign_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  s,s")))
2142           (const_int 32))))]
2143   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2144   "mpyh%? %0,%1,%2"
2145   [(set_attr "length" "4,4,8,8")
2146    (set_attr "type" "multi")
2147    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2149 ; Note that mpyhu has the same latency as mpy / mpyh,
2150 ; thus we use the type multi.
2151 (define_insn "*umulsi3_highpart_i"
2152   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
2153         (truncate:SI
2154          (lshiftrt:DI
2155           (mult:DI
2156            (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
2157            (zero_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  s,s")))
2158           (const_int 32))))]
2159   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2160   "mpyhu%? %0,%1,%2"
2161   [(set_attr "length" "4,4,8,8")
2162    (set_attr "type" "multi")
2163    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2165 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2166 ;; need a separate pattern for immediates
2167 ;; ??? This is fine for combine, but not for reload.
2168 (define_insn "umulsi3_highpart_int"
2169   [(set (match_operand:SI 0 "register_operand"            "=Rcr, r, r,Rcr,  r")
2170         (truncate:SI
2171          (lshiftrt:DI
2172           (mult:DI
2173            (zero_extend:DI (match_operand:SI 1 "register_operand"  " 0, c, 0,  0,  c"))
2174            (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2175           (const_int 32))))]
2176   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2177   "mpyhu%? %0,%1,%2"
2178   [(set_attr "length" "4,4,4,8,8")
2179    (set_attr "type" "multi")
2180    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2182 (define_expand "umulsi3_highpart"
2183   [(set (match_operand:SI 0 "general_operand"  "")
2184         (truncate:SI
2185          (lshiftrt:DI
2186           (mult:DI
2187            (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2188            (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2189           (const_int 32))))]
2190   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2191   "
2193   rtx target = operands[0];
2195   if (!register_operand (target, SImode))
2196     target = gen_reg_rtx (SImode);
2198   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2199     operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2200                                                   operands[2], SImode);
2201   else if (!immediate_operand (operands[2], SImode))
2202     operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2203   emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2204   if (target != operands[0])
2205     emit_move_insn (operands[0], target);
2206   DONE;
2209 (define_expand "umulsidi3"
2210   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2211         (mult:DI (zero_extend:DI(match_operand:SI 1 "register_operand" ""))
2212                  (zero_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2213   "(TARGET_ARC700 && !TARGET_NOMPY_SET)
2214    || TARGET_MULMAC_32BY16_SET"
2217   if ((TARGET_ARC700 && !TARGET_NOMPY_SET))
2218     {
2219       operands[2] = force_reg (SImode, operands[2]);
2220       if (!register_operand (operands[0], DImode))
2221         {
2222           rtx result = gen_reg_rtx (DImode);
2224           emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2225           emit_move_insn (operands[0], result);
2226           DONE;
2227         }
2228     }
2229   else if (TARGET_MUL64_SET)
2230     {
2231       operands[2] = force_reg (SImode, operands[2]);
2232       emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
2233       emit_move_insn (operands[0], gen_rtx_REG (DImode, 58));
2234     }
2235   else if (TARGET_MULMAC_32BY16_SET)
2236     {
2237       rtx result_hi = gen_reg_rtx (SImode);
2238       rtx result_low = gen_reg_rtx (SImode);
2240       result_hi = gen_highpart(SImode , operands[0]);
2241       result_low = gen_lowpart(SImode , operands[0]);
2243       emit_insn (gen_umul64_600 (operands[1], operands[2]));
2244       emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2245       emit_move_insn (result_low, gen_acc2 ());
2246       DONE;
2247     }
2250 (define_insn "umul64_600"
2251   [(set (reg:DI 56)
2252         (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"  "c,c,c"))
2253                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"  "c,L,Cal")
2254                                   (const_int 16)
2255                                   (const_int 0))))
2256   ]
2257   "TARGET_MULMAC_32BY16_SET"
2258   "mululw%? 0, %0, %1"
2259   [(set_attr "length" "4,4,8")
2260    (set_attr "type" "mulmac_600")
2261    (set_attr "cond" "nocond, canuse_limm, canuse")])
2264 (define_insn "umac64_600"
2265   [(set (reg:DI 56)
2266         (plus:DI
2267           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2268                    (ashift:DI
2269                      (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2270                                       (const_int 16) (const_int 16))
2271                      (const_int 16)))
2272           (reg:DI 56)))
2273    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2274         (zero_extract:SI
2275           (plus:DI
2276             (mult:DI (zero_extend:DI (match_dup 1))
2277                      (ashift:DI
2278                        (zero_extract:DI (match_dup 2)
2279                                         (const_int 16) (const_int 16))
2280                           (const_int 16)))
2281             (reg:DI 56))
2282           (const_int 32) (const_int 32)))]
2283   "TARGET_MULMAC_32BY16_SET"
2284   "machulw%? %0, %1, %2"
2285  [(set_attr "length" "4,4,8")
2286   (set_attr "type" "mulmac_600")
2287   (set_attr "cond" "nocond, canuse_limm, canuse")])
2291 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2292 (define_insn_and_split "umulsidi3_700"
2293   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2294         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2295                  (zero_extend:DI (match_operand:SI 2 "register_operand" "c"))))]
2296 ;;               (zero_extend:DI (match_operand:SI 2 "register_operand" "rL"))))]
2297   "TARGET_ARC700 && !TARGET_NOMPY_SET"
2298   "#"
2299   "reload_completed"
2300   [(const_int 0)]
2302   int hi = !TARGET_BIG_ENDIAN;
2303   int lo = !hi;
2304   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2305   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2306   emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2307   emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
2308   DONE;
2310   [(set_attr "type" "umulti")
2311   (set_attr "length" "8")])
2313 (define_expand "addsi3"
2314   [(set (match_operand:SI 0 "dest_reg_operand" "")
2315         (plus:SI (match_operand:SI 1 "register_operand" "")
2316                  (match_operand:SI 2 "nonmemory_operand" "")))]
2317   ""
2318   "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2]) ) 
2319      {
2320        operands[2]=force_reg(SImode, operands[2]);
2321      }
2322   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2323    {
2324       operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2325    }
2327   ")
2329 (define_insn "*addsi3_insn_a4"
2330   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r,r,r,r")
2331         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0,r,0,0,r,0,r")
2332                  (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,J,J,i,i")))]
2333   "TARGET_A4"
2334   "*
2335    {
2336      switch (which_alternative)
2337      {
2338        case 1:
2339          return \"add %0,%1,%2\";
2340        case 0:
2341          return \"add%? %0,%1,%2\";
2342        case 3:
2343          return \"add %0,%1,%2\";
2344        case 2:
2345          return \"add%? %0,%1,%2\";
2346        case 4:
2347          return \"add %0,%1,%2\";
2348        case 6:
2349          if (INTVAL (operands[2]) < 0)
2350             return \"sub %0,%1,%n2\"; 
2351          else
2352            return \"add %0,%1,%2\";
2353        case 5:
2354          if (INTVAL (operands[2]) < 0)
2355             return \"sub%? %0,%1,%n2\"; 
2356          else
2357            return \"add%? %0,%1,%2\";
2358        case 8:
2359          return \"add %0,%1,%S2\";
2360        case 7:
2361          return \"add%? %0,%1,%S2\";
2362        default:
2363          gcc_unreachable ();
2364      }
2365    }"
2366   [(set_attr "length" "4,4,4,4,4,8,8,8,8")
2367   (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond,canuse,nocond")]
2370 (define_expand "adddi3"
2371   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2372                    (plus:DI (match_operand:DI 1 "register_operand" "")
2373                             (match_operand:DI 2 "nonmemory_operand" "")))
2374               (clobber (reg:CC CC_REG))])]
2375   ""
2377   if (TARGET_EXPAND_ADDDI)
2378     {
2379       rtx l0 = gen_lowpart (SImode, operands[0]);
2380       rtx h0 = disi_highpart (operands[0]);
2381       rtx l1 = gen_lowpart (SImode, operands[1]);
2382       rtx h1 = disi_highpart (operands[1]);
2383       rtx l2 = gen_lowpart (SImode, operands[2]);
2384       rtx h2 = disi_highpart (operands[2]);
2385       rtx cc_c = gen_rtx_REG (CC_Cmode, 61);
2387       if (CONST_INT_P (h2) && INTVAL (h2) < 0 && SIGNED_INT12 (INTVAL (h2)))
2388         {
2389           emit_insn (gen_sub_f (l0, l1, gen_int_mode (-INTVAL (l2), SImode)));
2390           emit_insn (gen_sbc (h0, h1,
2391                               gen_int_mode (-INTVAL (h2) - (l1 != 0), SImode),
2392                               cc_c));
2393           DONE;
2394         }
2395       emit_insn (gen_add_f (l0, l1, l2));
2396       emit_insn (gen_adc (h0, h1, h2));
2397       DONE;
2398     }
2401 ; This assumes that there can be no strictly partial overlap between
2402 ; operands[1] and operands[2].
2403 (define_insn_and_split "*adddi3_i"
2404   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2405         (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2406                  (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2407    (clobber (reg:CC CC_REG))]
2408   ""
2409   "#"
2410   "reload_completed"
2411   [(const_int 0)]
2413   int hi = !TARGET_BIG_ENDIAN;
2414   int lo = !hi;
2415   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2416   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2417   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2418   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2419   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2420   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2422   
2423   if (l2 == const0_rtx)
2424     {
2425       if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2426         emit_move_insn (l0, l1);
2427       emit_insn (gen_addsi3 (h0, h1, h2));
2428       if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2429         emit_move_insn (l0, l1);
2430       DONE;
2431     }
2432   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2433       && INTVAL (operands[2]) >= -0x7fffffff)
2434     {
2435       emit_insn (gen_subdi3_i (operands[0], operands[1],
2436                  GEN_INT (-INTVAL (operands[2]))));
2437       DONE;
2438     }
2439   if (rtx_equal_p (l0, h1))
2440     {
2441       if (h2 != const0_rtx)
2442         emit_insn (gen_addsi3 (h0, h1, h2));
2443       else if (!rtx_equal_p (h0, h1))
2444         emit_move_insn (h0, h1);
2445       emit_insn (gen_add_f (l0, l1, l2));
2446       emit_insn
2447         (gen_rtx_COND_EXEC
2448           (VOIDmode,
2449            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2450            gen_rtx_SET (VOIDmode, h0, plus_constant (h0, 1))));
2451       DONE;
2452     }
2453   emit_insn (gen_add_f (l0, l1, l2));
2454   emit_insn (gen_adc (h0, h1, h2));
2455   DONE;
2457   [(set_attr "cond" "clob")
2458    (set_attr "type" "binary")
2459    (set_attr "length" "16,16,20")])
2461 (define_insn "add_f"
2462   [(set (reg:CC_C CC_REG)
2463         (compare:CC_C
2464           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2465                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2466           (match_dup 1)))
2467    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2468         (plus:SI (match_dup 1) (match_dup 2)))]
2469   ""
2470   "add.f %0,%1,%2"
2471   [(set_attr "cond" "set")
2472    (set_attr "type" "compare")
2473    (set_attr "length" "4,4,8")])
2475 (define_insn "*add_f_2"
2476   [(set (reg:CC_C CC_REG)
2477         (compare:CC_C
2478           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2479                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2480           (match_dup 2)))
2481    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2482         (plus:SI (match_dup 1) (match_dup 2)))]
2483   ""
2484   "add.f %0,%1,%2"
2485   [(set_attr "cond" "set")
2486    (set_attr "type" "compare")
2487    (set_attr "length" "4,4,8")])
2489 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2490 ; needlessly prioritizing the matching constraint.
2491 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2492 ; execution ; is used where possible.
2493 (define_insn_and_split "adc"
2494   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2495         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2496                           (match_operand:SI 1 "nonmemory_operand"
2497                                                          "%c,0,c,0,cCal"))
2498                  (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2499   "register_operand (operands[1], SImode)
2500    || register_operand (operands[2], SImode)"
2501   "@
2502         adc %0,%1,%2
2503         add.cs %0,%1,1
2504         adc %0,%1,%2
2505         adc %0,%1,%2
2506         adc %0,%1,%2"
2507   ; if we have a bad schedule after sched2, split.
2508   "reload_completed
2509    && !optimize_size && TARGET_ARC700
2510    && arc_scheduling_not_expected ()
2511    && arc_sets_cc_p (prev_nonnote_insn (insn))
2512    /* If next comes a return or other insn that needs a delay slot,
2513       expect the adc to get into the delay slot.  */
2514    && next_nonnote_insn (insn)
2515    && !arc_need_delay (next_nonnote_insn (insn))
2516    /* Restore operands before emitting.  */
2517    && (extract_insn_cached (insn), 1)"
2518   [(set (match_dup 0) (match_dup 3))
2519    (cond_exec
2520      (ltu (reg:CC_C CC_REG) (const_int 0))
2521      (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2522   "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2523   [(set_attr "cond" "use")
2524    (set_attr "type" "cc_arith")
2525    (set_attr "length" "4,4,4,4,8")])
2527 ; combiner-splitter cmp / scc -> cmp / adc
2528 (define_split
2529   [(set (match_operand:SI 0 "dest_reg_operand" "")
2530         (gtu:SI (match_operand:SI 1 "register_operand" "")
2531                 (match_operand:SI 2 "register_operand" "")))
2532    (clobber (reg CC_REG))]
2533   ""
2534   [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2535    (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2537 ; combine won't work when an intermediate result is used later...
2538 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2539 (define_peephole2
2540   [(set (match_operand:SI 0 "dest_reg_operand" "")
2541         (plus:SI (match_operand:SI 1 "register_operand" "")
2542                  (match_operand:SI 2 "nonmemory_operand" "")))
2543    (set (reg:CC_C 61)
2544         (compare:CC_C (match_dup 0)
2545                       (match_operand:SI 3 "nonmemory_operand" "")))]
2546   "rtx_equal_p (operands[1], operands[3])
2547    || rtx_equal_p (operands[2], operands[3])"
2548   [(parallel
2549      [(set (reg:CC_C CC_REG)
2550            (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2551       (set (match_dup 0)
2552            (plus:SI (match_dup 1) (match_dup 2)))])])
2554 ;(define_insn "*adc_0"
2555 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2556 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2557 ;                (match_operand:SI 1 "register_operand" "c")))]
2558 ;  ""
2559 ;  "adc %0,%1,0"
2560 ;  [(set_attr "cond" "use")
2561 ;   (set_attr "type" "cc_arith")
2562 ;   (set_attr "length" "4")])
2564 ;(define_split
2565 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2566 ;       (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2567 ;                        (match_operand:SI 2 "register_operand" "c"))
2568 ;                (match_operand:SI 3 "register_operand" "c")))
2569 ;   (clobber (reg CC_REG))]
2570 ;  ""
2571 ;  [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2572 ;   (set (match_dup 0)
2573 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2574 ;                (match_dup 3)))])
2576 ;; (define_insn "*subsi3_mixed"
2577 ;;   [(set (match_operand:SI 0 "register_operand" "=q,q,r")
2578 ;;      (minus:SI (match_operand:SI 1 "register_operand" "q,0,r")
2579 ;;                (match_operand:SI 2 "nonmemory_operand" "K,qM,rJ")))]
2580 ;;   "TARGET_MIXED_CODE"
2581 ;;   "@
2582 ;;    sub_s %0,%1,%2
2583 ;;    sub_s %0,%1,%2
2584 ;;    sub%? %0,%1,%S2"
2585 ;;   [(set_attr "iscompact" "true,true,false")
2586 ;;    (set_attr "length" "2,2,*")])
2588 (define_expand "subsi3"
2589   [(set (match_operand:SI 0 "dest_reg_operand" "")
2590         (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2591                  (match_operand:SI 2 "nonmemory_operand" "")))]
2592   ""
2593   "
2595   int c = 1;
2597   if (!register_operand (operands[2], SImode))
2598     {
2599       operands[1] = force_reg (SImode, operands[1]);
2600       c = 2;
2601     }
2602   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c]) ) 
2603     operands[c] = force_reg (SImode, operands[c]);
2604   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2605       operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2608 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2609 ; combine should make such an insn go away.
2610 (define_insn_and_split "subsi3_insn"
2611   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcw,Rcw,w,w,w,  w,  w,  w")
2612         (minus:SI (match_operand:SI 1 "nonmemory_operand"   "0,  0, cL,c,L,I,Cal,Cal,  c")
2613                   (match_operand:SI 2 "nonmemory_operand" "Rcqq, c,  0,c,c,0,  0,  c,Cal")))]
2614   "register_operand (operands[1], SImode)
2615    || register_operand (operands[2], SImode)"
2616   "@
2617     sub%? %0,%1,%2%&
2618     sub%? %0,%1,%2
2619     rsub%? %0,%2,%1
2620     sub %0,%1,%2
2621     rsub %0,%2,%1
2622     rsub %0,%2,%1
2623     rsub%? %0,%2,%1
2624     rsub %0,%2,%1
2625     sub %0,%1,%2"
2626   "reload_completed && get_attr_length (insn) == 8
2627    && satisfies_constraint_I (operands[1])"
2628   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2629   "split_subsi (operands);"
2630   [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false")
2631   (set_attr "length" "*,4,4,4,4,4,8,8,8")
2632   (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2634 (define_expand "subdi3"
2635   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2636                    (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2637                              (match_operand:DI 2 "nonmemory_operand" "")))
2638               (clobber (reg:CC 61))])]
2639   ""
2641   if (!register_operand (operands[2], DImode))
2642     operands[1] = force_reg (DImode, operands[1]);
2643   if (TARGET_EXPAND_ADDDI)
2644     {
2645       rtx l0 = gen_lowpart (SImode, operands[0]);
2646       rtx h0 = disi_highpart (operands[0]);
2647       rtx l1 = gen_lowpart (SImode, operands[1]);
2648       rtx h1 = disi_highpart (operands[1]);
2649       rtx l2 = gen_lowpart (SImode, operands[2]);
2650       rtx h2 = disi_highpart (operands[2]);
2651       rtx cc_c = gen_rtx_REG (CC_Cmode, 61);
2653       emit_insn (gen_sub_f (l0, l1, l2));
2654       emit_insn (gen_sbc (h0, h1, h2, cc_c));
2655       DONE;
2656     }
2659 (define_insn_and_split "subdi3_i"
2660   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2661         (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2662                   (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2663    (clobber (reg:CC 61))]
2664   "register_operand (operands[1], DImode)
2665    || register_operand (operands[2], DImode)"
2666   "#"
2667   "reload_completed"
2668   [(const_int 0)]
2670   int hi = !TARGET_BIG_ENDIAN;
2671   int lo = !hi;
2672   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2673   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2674   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2675   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2676   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2677   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2679   if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2680     {
2681       h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2682       if (!rtx_equal_p (h0, h1))
2683         emit_insn (gen_rtx_SET (VOIDmode, h0, h1));
2684       emit_insn (gen_sub_f (l0, l1, l2));
2685       emit_insn
2686         (gen_rtx_COND_EXEC
2687           (VOIDmode,
2688            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2689            gen_rtx_SET (VOIDmode, h0, plus_constant (h0, -1))));
2690       DONE;
2691     }
2692   emit_insn (gen_sub_f (l0, l1, l2));
2693   emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2694   DONE;
2696   [(set_attr "cond" "clob")
2697    (set_attr "length" "16,16,16,20,20")])
2699 (define_insn "*sbc_0"
2700   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2701         (minus:SI (match_operand:SI 1 "register_operand" "c")
2702                   (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2703                           (const_int 0))))]
2704   ""
2705   "sbc %0,%1,0"
2706   [(set_attr "cond" "use")
2707    (set_attr "type" "cc_arith")
2708    (set_attr "length" "4")])
2710 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2711 ; needlessly prioritizing the matching constraint.
2712 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2713 ; is used where possible.
2714 (define_insn_and_split "sbc"
2715   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2716         (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2717                                                 "c,0,c,0,cCal")
2718                             (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2719                                     (const_int 0)))
2720                   (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2721   "register_operand (operands[1], SImode)
2722    || register_operand (operands[2], SImode)"
2723   "@
2724         sbc %0,%1,%2
2725         sub.cs %0,%1,1
2726         sbc %0,%1,%2
2727         sbc %0,%1,%2
2728         sbc %0,%1,%2"
2729   ; if we have a bad schedule after sched2, split.
2730   "reload_completed
2731    && !optimize_size && TARGET_ARC700
2732    && arc_scheduling_not_expected ()
2733    && arc_sets_cc_p (prev_nonnote_insn (insn))
2734    /* If next comes a return or other insn that needs a delay slot,
2735       expect the adc to get into the delay slot.  */
2736    && next_nonnote_insn (insn)
2737    && !arc_need_delay (next_nonnote_insn (insn))
2738    /* Restore operands before emitting.  */
2739    && (extract_insn_cached (insn), 1)"
2740   [(set (match_dup 0) (match_dup 4))
2741    (cond_exec
2742      (ltu (reg:CC_C CC_REG) (const_int 0))
2743      (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2744   "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2745   [(set_attr "cond" "use")
2746    (set_attr "type" "cc_arith")
2747    (set_attr "length" "4,4,4,4,8")])
2749 (define_insn "sub_f"
2750   [(set (reg:CC CC_REG)
2751         (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2752                     (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2753    (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2754         (minus:SI (match_dup 1) (match_dup 2)))]
2755   "register_operand (operands[1], SImode)
2756    || register_operand (operands[2], SImode)"
2757   "@
2758         sub.f %0,%1,%2
2759         rsub.f %0,%2,%1
2760         sub.f %0,%1,%2
2761         rsub.f %0,%2,%1
2762         sub.f %0,%1,%2
2763         sub.f %0,%1,%2"
2764   [(set_attr "type" "compare")
2765    (set_attr "length" "4,4,4,4,8,8")])
2767 ; combine won't work when an intermediate result is used later...
2768 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2769 (define_peephole2
2770   [(set (reg:CC CC_REG)
2771         (compare:CC (match_operand:SI 1 "register_operand" "")
2772                     (match_operand:SI 2 "nonmemory_operand" "")))
2773    (set (match_operand:SI 0 "dest_reg_operand" "")
2774         (minus:SI (match_dup 1) (match_dup 2)))]
2775   ""
2776   [(parallel
2777      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2778       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
2780 (define_peephole2
2781   [(set (reg:CC CC_REG)
2782         (compare:CC (match_operand:SI 1 "register_operand" "")
2783                     (match_operand:SI 2 "nonmemory_operand" "")))
2784    (set (match_operand 3 "" "") (match_operand 4 "" ""))
2785    (set (match_operand:SI 0 "dest_reg_operand" "")
2786         (minus:SI (match_dup 1) (match_dup 2)))]
2787   "!reg_overlap_mentioned_p (operands[3], operands[1])
2788    && !reg_overlap_mentioned_p (operands[3], operands[2])
2789    && !reg_overlap_mentioned_p (operands[0], operands[4])
2790    && !reg_overlap_mentioned_p (operands[0], operands[3])"
2791   [(parallel
2792      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2793       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2794    (set (match_dup 3) (match_dup 4))])
2796 (define_insn "*add_n"
2797   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,w,w")
2798         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c")
2799                           (match_operand:SI 2 "_2_4_8_operand" ""))
2800                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal")))]
2801   ""
2802   "add%z2%? %0,%3,%1%&"
2803   [(set_attr "type" "shift")
2804    (set_attr "length" "*,4,4,8")
2805    (set_attr "cond" "canuse,canuse,nocond,nocond")
2806    (set_attr "iscompact" "maybe,false,false,false")])
2808 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
2809 ;; what synth_mult likes.
2810 (define_insn "*sub_n"
2811   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2812         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
2813                   (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
2814                            (match_operand:SI 3 "_2_4_8_operand" ""))))]
2815   ""
2816   "sub%z3%? %0,%1,%2"
2817   [(set_attr "type" "shift")
2818    (set_attr "length" "4,4,8")
2819    (set_attr "cond" "canuse,nocond,nocond")
2820    (set_attr "iscompact" "false")])
2822 ; ??? check if combine matches this.
2823 (define_insn "*bset"
2824   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 
2825         (ior:SI (ashift:SI (const_int 1) 
2826                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2827                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2828   "TARGET_ARCOMPACT"
2829   "bset%? %0,%2,%1"
2830   [(set_attr "length" "4,4,8")
2831    (set_attr "cond" "canuse,nocond,nocond")]
2834 ; ??? check if combine matches this.
2835 (define_insn "*bxor"
2836   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 
2837         (xor:SI (ashift:SI (const_int 1) 
2838                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")) 
2839                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2840   "TARGET_ARCOMPACT"
2841   "bxor%? %0,%2,%1"
2842   [(set_attr "length" "4,4,8")
2843    (set_attr "cond" "canuse,nocond,nocond")]
2846 ; ??? check if combine matches this.
2847 (define_insn "*bclr"
2848   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 
2849         (and:SI (not:SI (ashift:SI (const_int 1) 
2850                                    (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))) 
2851                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2852   "TARGET_ARCOMPACT"
2853   "bclr%? %0,%2,%1"
2854   [(set_attr "length" "4,4,8")
2855    (set_attr "cond" "canuse,nocond,nocond")]
2858 ; ??? FIXME: find combine patterns for bmsk.
2860 ;;Following are the define_insns added for the purpose of peephole2's
2862 ; see also iorsi3 for use with constant bit number.
2863 (define_insn "*bset_insn"
2864   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 
2865         (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal") 
2866                 (ashift:SI (const_int 1) 
2867                            (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2868   "TARGET_ARCOMPACT"
2869   "@
2870      bset%? %0,%1,%2 ;;peep2, constr 1
2871      bset %0,%1,%2 ;;peep2, constr 2
2872      bset %0,%S1,%2 ;;peep2, constr 3"
2873   [(set_attr "length" "4,4,8")]
2876 ; see also xorsi3 for use with constant bit number.
2877 (define_insn "*bxor_insn"
2878   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 
2879         (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal") 
2880                 (ashift:SI (const_int 1) 
2881                         (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2882   "TARGET_ARCOMPACT"
2883   "@
2884      bxor%? %0,%1,%2
2885      bxor %0,%1,%2
2886      bxor %0,%S1,%2"
2887   [(set_attr "length" "4,4,8")
2888    (set_attr "cond" "canuse,nocond,nocond")]
2891 ; see also andsi3 for use with constant bit number.
2892 (define_insn "*bclr_insn"
2893   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2894         (and:SI (not:SI (ashift:SI (const_int 1)
2895                                    (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
2896                 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
2897   "TARGET_ARCOMPACT"
2898   "@
2899      bclr%? %0,%1,%2
2900      bclr %0,%1,%2
2901      bclr %0,%S1,%2"
2902   [(set_attr "length" "4,4,8")
2903    (set_attr "cond" "canuse,nocond,nocond")]
2906 ; see also andsi3 for use with constant bit number.
2907 (define_insn "*bmsk_insn"
2908   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2909         (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2910                 (plus:SI (ashift:SI (const_int 1)
2911                                     (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
2912                                              (const_int 1)))
2913                          (const_int -1))))]
2914   "TARGET_ARCOMPACT"
2915   "@
2916      bmsk%? %0,%S1,%2
2917      bmsk %0,%1,%2
2918      bmsk %0,%S1,%2"
2919   [(set_attr "length" "4,4,8")]
2922 ;;Instructions added for peephole2s end
2924 ;; Boolean instructions.
2926 ;; (define_insn "*andsi3_mixed"
2927 ;;   [(set (match_operand:SI 0 "compact_register_operand" "=q")
2928 ;;      (and:SI (match_operand:SI 1 "compact_register_operand" "0") 
2929 ;;              (match_operand:SI 2 "compact_register_operand" "q")))]
2930 ;;   "TARGET_MIXED_CODE"
2931 ;;   "and_s %0,%1,%2"
2932 ;;   [(set_attr "iscompact" "true")
2933 ;;    (set_attr "type" "binary")
2934 ;;    (set_attr "length" "2")])
2936 (define_insn "*andsi3_insn_a4"
2937   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
2938         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2939                 (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
2940   "TARGET_A4"
2941   "@
2942     and%? %0,%1,%2
2943     and%? %0,%1,%S2"
2944   [(set_attr "type" "binary, binary")
2945    (set_attr "length" "4, 8")])
2947 (define_expand "andsi3"
2948   [(set (match_operand:SI 0 "dest_reg_operand" "")
2949         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2950                 (match_operand:SI 2 "nonmemory_operand" "")))]
2951   "TARGET_ARCOMPACT"
2952   "if (!satisfies_constraint_Cux (operands[2]))
2953      operands[1] = force_reg (SImode, operands[1]);
2954    else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
2955      operands[1] = arc_rewrite_small_data (operands[1]);")
2957 (define_insn "andsi3_i"
2958   [(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")
2959         (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") 
2960                 (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")))]
2961   "TARGET_ARCOMPACT
2962    && ((register_operand (operands[1], SImode)
2963        && nonmemory_operand (operands[2], SImode))
2964       || (memory_operand (operands[1], SImode)
2965           && satisfies_constraint_Cux (operands[2])))"
2966   "*
2968   switch (which_alternative)
2969     {
2970     case 0: case 5: case 10: case 11: case 15: case 16: case 17:
2971       return \"and%? %0,%1,%2%&\";
2972     case 1: case 6:
2973       return \"and%? %0,%2,%1%&\";
2974     case 2: case 7: case 12:
2975       return \"bmsk%? %0,%1,%Z2%&\";
2976     case 3: case 8: case 13:
2977       return \"bclr%? %0,%1,%M2%&\";
2978     case 4:
2979       return (INTVAL (operands[2]) == 0xff
2980               ? \"extb%? %0,%1%&\" : \"extw%? %0,%1%&\");
2981     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
2982     case 18:
2983       if (TARGET_BIG_ENDIAN)
2984         {
2985           rtx xop[2];
2987           xop[0] = operands[0];
2988           xop[1] = adjust_address (operands[1], QImode,
2989                                    INTVAL (operands[2]) == 0xff ? 3 : 2);
2990           output_asm_insn (INTVAL (operands[2]) == 0xff
2991                            ? \"ldb %0,%1\" : \"ldw %0,%1\",
2992                            xop);
2993           return \"\";
2994         }
2995       return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ldw %0,%1\";
2996     default:
2997       gcc_unreachable ();
2998     }
3000   [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3001    (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
3002    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3003    (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
3005 ; combiner splitter, pattern found in ldtoa.c .
3006 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3007 (define_split
3008   [(set (reg:CC_Z CC_REG)
3009         (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3010                               (match_operand 1 "const_int_operand" ""))
3011                       (match_operand 2 "const_int_operand" "")))
3012    (clobber (match_operand:SI 3 "register_operand" ""))]
3013   "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3014   [(set (match_dup 3)
3015         (plus:SI (match_dup 0) (match_dup 4)))
3016    (set (reg:CC_Z CC_REG)
3017         (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3018                       (const_int 0)))]
3019   "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3021 ;; (define_insn "andsi3"
3022 ;;   [(set (match_operand:SI 0 "register_operand" "=r,r")
3023 ;;      (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3024 ;;              (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
3025 ;;   ""
3026 ;;   "@
3027 ;;     and%? %0,%1,%2
3028 ;;     and%? %0,%1,%S2"
3029 ;;   [(set_attr "type" "binary, binary")
3030 ;;    (set_attr "length" "4, 8")])
3032 (define_insn_and_split "anddi3"
3033   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,&w,w")
3034         (and:DI (match_operand:DI 1 "register_operand" "%c,0,c,0")
3035                 (match_operand:DI 2 "nonmemory_operand" "c,c,H,H")))]
3036   "TARGET_OLD_DI_PATTERNS"
3037   "#"
3038   "reload_completed"
3039   [(set (match_dup 3) (and:SI (match_dup 4) (match_dup 5)))
3040    (set (match_dup 6) (and:SI (match_dup 7) (match_dup 8)))]
3041   "arc_split_dilogic (operands, AND); DONE;"
3042   [(set_attr "length" "8,8,16,16")])
3044 ;; (define_insn "*bicsi3_insn_mixed"
3045 ;;   [(set (match_operand:SI 0 "compact_register_operand" "=q")
3046 ;;      (and:SI (match_operand:SI 1 "compact_register_operand" "0")
3047 ;;              (not:SI (match_operand:SI 2 "compact_register_operand" "q"))))]
3048 ;;   "TARGET_MIXED_CODE"
3049 ;;   "bic_s %0,%1,%2"
3050 ;;   [(set_attr "iscompact" "true")])
3053 ;;bic define_insn that allows limm to be the first operand
3054 (define_insn "*bicsi3_insn"
3055    [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3056         (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3057                 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3058   ""
3059   "@
3060    bic%? %0, %2, %1%& ;;constraint 0
3061    bic%? %0,%2,%1  ;;constraint 1
3062    bic %0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
3063    bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3064    bic %0,%2,%1    ;;constraint 4
3065    bic %0,%2,%S1   ;;constraint 5, FIXME: will it ever get generated ???
3066    bic %0,%S2,%1   ;;constraint 6"
3067   [(set_attr "length" "*,4,4,8,4,8,8")
3068   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3069   (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3072 (define_insn "*iorsi3_a4"
3073   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3074         (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
3075                 (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
3076   "TARGET_A4"
3077   "@
3078     or%? %0,%1,%2
3079     or%? %0,%1,%S2"
3080   [(set_attr "type" "binary, binary")
3081    (set_attr "length" "4, 8")])
3083 (define_insn "iorsi3"
3084   [(set (match_operand:SI 0 "dest_reg_operand"        "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w,  w,w,Rcw,  w")
3085         (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq,   0,  0,  c,  0, 0, c,  c,0,  0,  c")
3086                 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL,  0,C0p, I,cL,C0p,I,Cal,Cal")))]
3087   "TARGET_ARCOMPACT"
3088   "*
3089   switch (which_alternative)
3090     {
3091     case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3092       return \"or%? %0,%1,%2%&\";
3093     case 1: case 4:
3094       return \"or%? %0,%2,%1%&\";
3095     case 2: case 5: case 8:
3096       return \"bset%? %0,%1,%z2%&\";
3097     default:
3098       gcc_unreachable ();
3099     }"
3100   [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3101    (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3102    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3104 ;; (define_insn "iorsi3"
3105 ;;   [(set (match_operand:SI 0 "register_operand" "=r,r")
3106 ;;      (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
3107 ;;              (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
3108 ;;   ""
3109 ;;   "@
3110 ;;     or%? %0,%1,%2
3111 ;;     or%? %0,%1,%S2"
3112 ;;   [(set_attr "type" "binary, binary")
3113 ;;    (set_attr "length" "4, 8")])
3115 (define_insn_and_split "iordi3"
3116   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,&w,w")
3117         (ior:DI (match_operand:DI 1 "register_operand" "%c,0,c,0")
3118                 (match_operand:DI 2 "nonmemory_operand" "c,c,H,H")))]
3119   "TARGET_OLD_DI_PATTERNS"
3120   "#"
3121   "reload_completed"
3122   [(set (match_dup 3) (ior:SI (match_dup 4) (match_dup 5)))
3123    (set (match_dup 6) (ior:SI (match_dup 7) (match_dup 8)))]
3124   "arc_split_dilogic (operands, IOR); DONE;"
3125   [(set_attr "length" "8,8,16,16")])
3127 ;; (define_insn "*xorsi3_mixed"
3128 ;;   [(set (match_operand:SI 0 "compact_register_operand" "=q")
3129 ;;      (xor:SI (match_operand:SI 1 "compact_register_operand" "0")
3130 ;;              (match_operand:SI 2 "compact_register_operand" "q")))]
3131 ;;   "TARGET_MIXED_CODE"
3132 ;;   "xor_s %0,%1,%2"
3133 ;;   [(set_attr "iscompact" "true")
3134 ;;    (set_attr "length" "2")])
3136 (define_insn "xorsi3"
3137   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w,  w,w,  w,  w")
3138         (xor:SI (match_operand:SI 1 "register_operand"  "%0,   Rcq,  0,  c,  0,  0, c,  c,0,  0,  c")
3139                 (match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, cL,  0,C0p,  I,cL,C0p,I,Cal,Cal")))]
3140   ""
3141   "*
3142   switch (which_alternative)
3143     {
3144     case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3145       return \"xor%? %0,%1,%2%&\";
3146     case 1: case 3:
3147       return \"xor%? %0,%2,%1%&\";
3148     case 4: case 7:
3149       return \"bxor%? %0,%1,%z2\";
3150     default:
3151       gcc_unreachable ();
3152     }
3153   "
3154   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3155    (set_attr "type" "binary")
3156    (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3157    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3159 (define_insn_and_split "xordi3"
3160   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,&w,w")
3161         (xor:DI (match_operand:DI 1 "register_operand" "%c,0,c,0")
3162                 (match_operand:DI 2 "nonmemory_operand" "c,c,H,H")))]
3163   "TARGET_OLD_DI_PATTERNS"
3164   "#"
3165   "reload_completed"
3166   [(set (match_dup 3) (xor:SI (match_dup 4) (match_dup 5)))
3167    (set (match_dup 6) (xor:SI (match_dup 7) (match_dup 8)))]
3168   "arc_split_dilogic (operands, XOR); DONE;"
3169   [(set_attr "length" "8,8,16,16")])
3171 (define_insn "*negsi2_a4"
3172   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3173         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3174   "TARGET_A4"
3175   "sub%? %0,0,%1"
3176   [(set_attr "type" "unary")
3177    (set_attr "length" "4")])
3179 (define_insn "negsi2"
3180   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3181         (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3182   ""
3183   "neg%? %0,%1%&"
3184   [(set_attr "type" "unary")
3185    (set_attr "iscompact" "maybe,true,false,false")
3186    (set_attr "cond" "canuse,nocond,canuse,nocond")])
3188 ;; (define_insn "negsi2"
3189 ;;   [(set (match_operand:SI 0 "register_operand" "=r")
3190 ;;      (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3191 ;;   ""
3192 ;;   "sub%? %0,0,%1"
3193 ;;   [(set_attr "type" "unary")
3194 ;;    (set_attr "length" "8")])
3196 (define_insn_and_split "negdi2"
3197   [(set (match_operand:DI 0 "dest_reg_operand" "=&w")
3198         (neg:DI (match_operand:DI 1 "register_operand" "c")))
3199    (clobber (reg:SI 61))]
3200   "TARGET_OLD_DI_PATTERNS"
3201   "#"
3202   ""
3203   [(set (match_dup 0) (minus:DI (const_int 0) (match_dup 1)))]
3204   ""
3205   [(set_attr "type" "unary")
3206    (set_attr "cond" "clob")
3207    (set_attr "length" "16")])
3209 (define_insn "*one_cmplsi2_a4"
3210   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3211         (not:SI (match_operand:SI 1 "register_operand" "r")))]
3212   "TARGET_A4"
3213   "xor %0,%1,-1"
3214   [(set_attr "type" "unary")
3215    (set_attr "cond" "nocond")])
3217 (define_insn "one_cmplsi2"
3218   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3219         (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3220   ""
3221   "not%? %0,%1%&"
3222   [(set_attr "type" "unary,unary")
3223    (set_attr "iscompact" "true,false")])
3225 ;; (define_insn "*one_cmplsi2_ac32"
3226 ;;   [(set (match_operand:SI 0 "register_operand" "=r")
3227 ;;      (not:SI (match_operand:SI 1 "register_operand" "r")))]
3228 ;;   "TARGET_ARCOMPACT"
3229 ;;   "not %0,%1"
3230 ;;   [(set_attr "type" "unary")
3231 ;;    (set_attr "cond" "nocond")])
3233 (define_insn "*one_cmpldi2_a4"
3234   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
3235         (not:DI (match_operand:DI 1 "register_operand" "r")))]
3236   "TARGET_A4"
3237   "xor %H0,%H1,-1\;xor %L0,%L1,-1"
3238   [(set_attr "type" "unary")
3239    (set_attr "cond" "nocond")
3240    (set_attr "length" "16")])
3242 (define_insn_and_split "one_cmpldi2"
3243   [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3244         (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3245   "TARGET_ARCOMPACT"
3246   "#"
3247   "&& reload_completed"
3248   [(set (match_dup 2) (not:SI (match_dup 3)))
3249    (set (match_dup 4) (not:SI (match_dup 5)))]
3251   int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3253   operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3254   operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3255   operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3256   operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3258   [(set_attr "type" "unary,unary")
3259    (set_attr "cond" "nocond,nocond")
3260    (set_attr "length" "4,8")])
3262 ;; Shift instructions.
3264 (define_expand "ashlsi3"
3265   [(set (match_operand:SI 0 "dest_reg_operand" "")
3266         (ashift:SI (match_operand:SI 1 "register_operand" "")
3267                    (match_operand:SI 2 "nonmemory_operand" "")))]
3268   ""
3269   "
3271   if (!TARGET_SHIFTER)
3272     {
3273 /* ashwin : all gen_rtx (VAR.. ) are converted to gen_rtx_VAR (..) */
3274       emit_insn (gen_rtx_PARALLEL
3275                  (VOIDmode,
3276                   gen_rtvec (3,
3277                              gen_rtx_SET (VOIDmode, operands[0],
3278                                       gen_rtx_ASHIFT (SImode, operands[1], operands[2])),
3279                              gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)),
3280                              gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, 61))
3281                         )));
3282       DONE;
3283     }
3286 (define_expand "ashrsi3"
3287   [(set (match_operand:SI 0 "dest_reg_operand" "")
3288         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3289                      (match_operand:SI 2 "nonmemory_operand" "")))]
3290   ""
3291   "
3293   if (!TARGET_SHIFTER)
3294     {
3295       emit_insn (gen_rtx_PARALLEL
3296                  (VOIDmode,
3297                   gen_rtvec (3,
3298                              gen_rtx_SET (VOIDmode, operands[0],
3299                                       gen_rtx_ASHIFTRT (SImode, operands[1], operands[2])),
3300                              gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)),
3301                              gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, 61)))));
3302       DONE;
3303     }
3306 (define_expand "lshrsi3"
3307   [(set (match_operand:SI 0 "dest_reg_operand" "")
3308         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3309                      (match_operand:SI 2 "nonmemory_operand" "")))]
3310   ""
3311   "
3313   if (!TARGET_SHIFTER)
3314     {
3315       emit_insn (gen_rtx_PARALLEL
3316                  (VOIDmode,
3317                   gen_rtvec (3,
3318                              gen_rtx_SET (VOIDmode, operands[0],
3319                                       gen_rtx_LSHIFTRT (SImode, operands[1], operands[2])),
3320                              gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)),
3321                              gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode,61)))));
3322                                                       DONE;
3323     }
3326 (define_insn "*shift_si3"
3327   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3328         (match_operator:SI 3 "shift_operator"
3329                            [(match_operand:SI 1 "register_operand" "0")
3330                             (match_operand:SI 2 "nonmemory_operand" "rJ")]))
3331    (clobber (match_scratch:SI 4 "=&r"))
3332    (clobber (reg:CC 61))
3333   ]
3334   "!TARGET_SHIFTER"
3335   "* return output_shift (operands);"
3336   [(set_attr "type" "shift")
3337    (set_attr "length" "32")])
3339 ; asl, asr, lsr patterns:
3340 ; There is no point in including an 'I' alternative since only the lowest 5
3341 ; bits are used for the shift.  OTOH Cal can be useful if the shift amount
3342 ; is defined in an external symbol, as we don't have special relocations
3343 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3344 ; provide one alternatice for this, without condexec support.
3345 (define_insn "*ashlsi3_insn_mixed"
3346   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3347         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3348                    (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3349   "TARGET_SHIFTER
3350    && (register_operand (operands[1], SImode)
3351        || register_operand (operands[2], SImode))"
3352   "asl%? %0,%1,%2%&"
3353   [(set_attr "type" "shift")
3354    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3355    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3357 ;; (define_insn "*ashlsi3_insn"
3358 ;;   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3359 ;;         (ashift:SI (match_operand:SI 1 "register_operand" "r,r,r,0")
3360 ;;                    (match_operand:SI 2 "nonmemory_operand" "N,r,Cal,rJ")))]
3361 ;;   "TARGET_SHIFTER"
3362 ;;   "@
3363 ;;    asl %0,%1
3364 ;;    asl %0, %1, %2
3365 ;;    asl %0, %1, %2
3366 ;;    asl%? %0,%1,%S2"
3367 ;;   [(set_attr "type" "shift,shift,shift,shift")
3368 ;;   (set_attr "length" "4, 4, 8, 8")
3369 ;;    (set_attr "cond" "nocond,nocond,nocond,canuse")])
3371 ;; (define_insn "*ashrsi3_insn_mixed"
3372 ;;   [(set (match_operand:SI 0 "register_operand" "=q,q,q,r,r")
3373 ;;         (ashiftrt:SI (match_operand:SI 1 "register_operand" "q,q,0,0,r")
3374 ;;                      (match_operand:SI 2 "nonmemory_operand" "N,K,qM,rJ,rJ")))]
3375 ;;   "TARGET_MIXED_CODE"
3376 ;;   "@
3377 ;;    asr_s %0,%1
3378 ;;    asr_s %0,%1,%2
3379 ;;    asr_s %0,%1,%2
3380 ;;    asr%? %0,%1,%S2
3381 ;;    asr   %0,%1,%S2"
3382 ;;   [(set_attr "type" "shift,shift,shift,shift,shift")
3383 ;;    (set_attr "iscompact" "true,true,true,false,false")])
3385 ;; (define_insn "*ashrsi3_insn"
3386 ;;   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3387 ;;         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r")
3388 ;;                      (match_operand:SI 2 "nonmemory_operand" "N,rJ,rJ")))]
3389 ;;   "TARGET_SHIFTER"
3390 ;;   "@
3391 ;;    asr %0,%1
3392 ;;    asr%? %0,%1,%S2
3393 ;;    asr %0,%1,%S2"
3394 ;;   [(set_attr "type" "shift,shift,shift")
3395 ;;    (set_attr "cond" "nocond,canuse,nocond")])
3396 (define_insn "*ashrsi3_insn_mixed"
3397   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3398         (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3399                    (match_operand:SI 2 "nonmemory_operand"    "K,  K,RcqqM, cL,cL,cCal")))]
3400   "TARGET_SHIFTER
3401    && (register_operand (operands[1], SImode)
3402        || register_operand (operands[2], SImode))"
3403   "asr%? %0,%1,%2%&"
3404   [(set_attr "type" "shift")
3405    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3406    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3408 ;; (define_insn "*lshrsi3_insn_mixed"
3409 ;;   [(set (match_operand:SI 0 "register_operand" "=q,q,r")
3410 ;;         (lshiftrt:SI (match_operand:SI 1 "register_operand" "q,0,r")
3411 ;;                      (match_operand:SI 2 "nonmemory_operand" "N,qM,rJ")))]
3412 ;;   "TARGET_MIXED_CODE"
3413 ;;   "@
3414 ;;    lsr_s %0,%1
3415 ;;    lsr_s %0,%1,%2
3416 ;;    lsr%? %0,%1,%S2"
3417 ;;   [(set_attr "type" "shift,shift,shift")
3418 ;;    (set_attr "iscompact" "true,true,false")])
3420 ;; (define_insn "*lshrsi3_insn"
3421 ;;   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3422 ;;           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r")
3423 ;;                      (match_operand:SI 2 "nonmemory_operand" "N,rJ,rJ")))]
3424 ;;   "TARGET_SHIFTER"
3425 ;;   "@
3426 ;;    lsr %0,%1
3427 ;;    lsr%? %0,%1,%S2
3428 ;;    lsr %0,%1,%S2"
3429 ;;   [(set_attr "type" "shift,shift,shift")
3430 ;;    (set_attr "cond" "nocond,canuse,nocond")])
3431 (define_insn "*lshrsi3_insn_mixed"
3432   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3433         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3434                    (match_operand:SI 2 "nonmemory_operand"    "N,  N,RcqqM, cL,cL,cCal")))]
3435   "TARGET_SHIFTER
3436    && (register_operand (operands[1], SImode)
3437        || register_operand (operands[2], SImode))"
3438   "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3439             ?  \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3440   [(set_attr "type" "shift")
3441    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3442    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3444 (define_insn "rotrsi3"
3445   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
3446         (rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCal")
3447                      (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3448   "TARGET_SHIFTER"
3449   "ror%? %0,%1,%2"
3450   [(set_attr "type" "shift,shift,shift")
3451    (set_attr "cond" "canuse,nocond,nocond")
3452    (set_attr "length" "4,4,8")])
3454 ;; Compare instructions.
3455 ;; This controls RTL generation and register allocation.
3457 ;; We generate RTL for comparisons and branches by having the cmpxx
3458 ;; patterns store away the operands.  Then, the scc and bcc patterns
3459 ;; emit RTL for both the compare and the branch.
3461 (define_expand "cmpsi"
3462   [(set (reg:CC 61)
3463         (compare:CC (match_operand:SI 0 "register_operand" "")
3464                     (match_operand:SI 1 "nonmemory_operand" "")))]
3465   ""
3466   "
3468   arc_compare_op0 = operands[0];
3469   if (GET_CODE(operands[1]) == SYMBOL_REF && flag_pic)
3470     arc_compare_op1 = force_reg (SImode, operands[1]);
3471   else
3472    arc_compare_op1 = operands[1];
3473   DONE;
3476 ;; ??? We may be able to relax this a bit by adding a new constraint for 0.
3477 ;; This assumes sub.f 0,symbol,0 is a valid insn.
3478 ;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
3479 ;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
3480 ;; if it's a small constant.
3482 (define_insn "*cmpsi_cc_insn_a4"
3483   [(set (reg:CC 61)
3484         (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
3485                     (match_operand:SI 1 "nonmemory_operand" "r,I,Cal")))]
3486   "TARGET_A4"
3487   "@
3488    sub.f 0,%0,%1
3489    sub.f %1,%0,%1
3490    sub.f 0,%0,%S1"
3491   [(set_attr "type" "compare,compare,compare")
3492   ])
3494 (define_insn "*cmpsi_cczn_insn_a4"
3495   [(set (reg:CC_ZN 61)
3496         (compare:CC_ZN (match_operand:SI 0 "register_operand" "r,r,r")
3497                        (match_operand:SI 1 "nonmemory_operand" "r,I,Cal")))]
3498   "TARGET_A4"
3499   "@
3500    sub.f 0,%0,%1
3501    sub.f %1,%0,%1
3502    sub.f 0,%0,%S1"
3503   [(set_attr "type" "compare,compare,compare")
3504   ])
3506 ;; (define_insn "*cmpsi_cc_insn_mixed"
3507 ;;   [(set (reg:CC 61)
3508 ;;         (compare:CC (match_operand:SI 0 "compact_register_operand" "q,r")
3509 ;;                     (match_operand:SI 1 "nonmemory_operand" "rO,rJ")))]
3510 ;;   "TARGET_MIXED_CODE"
3511 ;;   "@
3512 ;;    cmp_s %0,%1
3513 ;;    cmp%? %0,%S1"
3514 ;;   [(set_attr "type" "compare,compare")
3515 ;;    (set_attr "iscompact" "true,false")])
3517 ;; (define_insn "*cmpsi_cc_insn"
3518 ;;   [(set (reg:CC 61)
3519 ;;         (compare:CC (match_operand:SI 0 "register_operand" "r")
3520 ;;                     (match_operand:SI 1 "nonmemory_operand" "rJ")))]
3521 ;;   "TARGET_ARCOMPACT"
3522 ;;   "cmp%? %0,%S1"
3523 ;;   [(set_attr "type" "compare")
3524 ;;   ])
3526 ;; ??? Could add a peephole to generate compare with swapped operands and
3527 ;; modifed cc user if second, but not first operand is a compact register.
3528 (define_insn "cmpsi_cc_insn_mixed"
3529   [(set (reg:CC 61)
3530         (compare:CC (match_operand:SI 0 "register_operand"  "Rcq#q, c, qRcq, c")
3531                     (match_operand:SI 1 "nonmemory_operand"  "cO,cI,  Cal, Cal")))]
3532   "TARGET_ARCOMPACT"
3533   "cmp%? %0,%B1%&"
3534   [(set_attr "type" "compare")
3535    (set_attr "iscompact" "true,false,true_limm,false")
3536    (set_attr "cond" "set")
3537    (set_attr "length" "*,4,*,8")])
3539 (define_insn "*cmpsi_cc_zn_insn"
3540   [(set (reg:CC_ZN 61)
3541         (compare:CC_ZN (match_operand:SI 0 "register_operand"  "qRcq,c")
3542                        (const_int 0)))]
3543   "TARGET_ARCOMPACT"
3544   "tst%? %0,%0%&"
3545   [(set_attr "type" "compare,compare")
3546    (set_attr "iscompact" "true,false")
3547    (set_attr "cond" "set_zn")
3548    (set_attr "length" "*,4")])
3550 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3551 (define_insn "*btst"
3552   [(set (reg:CC_ZN CC_REG)
3553         (compare:CC_ZN
3554           (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3555                            (const_int 1)
3556                            (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3557           (const_int 0)))]
3558   ""
3559   "btst%? %0,%1"
3560   [(set_attr "iscompact" "true,false")
3561    (set_attr "cond" "set")
3562    (set_attr "type" "compare")
3563    (set_attr "length" "*,4")])
3565 ; combine suffers from 'simplifications' that replace a one-bit zero
3566 ; extract with a shift if it can prove that the upper bits are zero.
3567 ; arc_reorg sees the code after sched2, which can have caused our
3568 ; inputs to be clobbered even if they were not clobbered before.
3569 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3570 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3571 ; bbit (i.e. bad scheduling) and missed conditional execution,
3572 ; so make this an option.
3573 (define_peephole2
3574   [(set (reg:CC_ZN CC_REG)
3575         (compare:CC_ZN
3576           (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3577                            (const_int 1)
3578                            (match_operand:SI 1 "nonmemory_operand" ""))
3579           (const_int 0)))
3580    (set (pc)
3581         (if_then_else (match_operator 3 "equality_comparison_operator"
3582                                       [(reg:CC_ZN CC_REG) (const_int 0)])
3583                       (label_ref (match_operand 2 "" ""))
3584                       (pc)))]
3585   "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3586   [(parallel [(set (pc)
3587                    (if_then_else
3588                      (match_op_dup 3
3589                        [(zero_extract:SI (match_dup 0)
3590                                          (const_int 1) (match_dup 1))
3591                         (const_int 0)])
3592                      (label_ref (match_dup 2))
3593                      (pc)))
3594               (clobber (reg:CC_ZN CC_REG))])])
3596 (define_insn "*cmpsi_cc_z_insn"
3597   [(set (reg:CC_Z 61)
3598         (compare:CC_Z (match_operand:SI 0 "register_operand"  "qRcq,c")
3599                       (match_operand:SI 1 "p2_immediate_operand"  "O,n")))]
3600   "TARGET_ARCOMPACT"
3601   "@
3602         cmp%? %0,%1%&
3603         bxor.f 0,%0,%z1"
3604   [(set_attr "type" "compare,compare")
3605    (set_attr "iscompact" "true,false")
3606    (set_attr "cond" "set,set_zn")
3607    (set_attr "length" "*,4")])
3609 (define_insn "*cmpsi_cc_c_insn"
3610   [(set (reg:CC_C 61)
3611         (compare:CC_C (match_operand:SI 0 "register_operand"  "Rcqq, c,Rcqq,  c")
3612                       (match_operand:SI 1 "nonmemory_operand" "cO,  cI, Cal,Cal")))]
3613   "TARGET_ARCOMPACT"
3614   "cmp%? %0,%S1%&"
3615   [(set_attr "type" "compare")
3616    (set_attr "iscompact" "true,false,true_limm,false")
3617    (set_attr "cond" "set")
3618    (set_attr "length" "*,4,*,8")])
3620 ;; Next come the scc insns.
3622 (define_expand "seq"
3623   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3624   ""
3625   "
3627   operands[1] = gen_compare_reg (EQ, SImode);
3630 (define_expand "sne"
3631   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3632   ""
3633   "
3635   operands[1] = gen_compare_reg (NE, SImode);
3638 (define_expand "sgt"
3639   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3640   ""
3641   "
3643   operands[1] = gen_compare_reg (GT, SImode);
3646 (define_expand "sle"
3647   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3648   ""
3649   "
3651   operands[1] = gen_compare_reg (LE, SImode);
3654 (define_expand "sge"
3655   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3656   ""
3657   "
3659   operands[1] = gen_compare_reg (GE, SImode);
3662 (define_expand "slt"
3663   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3664   ""
3665   "
3667   operands[1] = gen_compare_reg (LT, SImode);
3670 (define_expand "sgtu"
3671   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3672   ""
3673   "
3675   operands[1] = gen_compare_reg (GTU, SImode);
3678 (define_expand "sleu"
3679   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3680   ""
3681   "
3683   operands[1] = gen_compare_reg (LEU, SImode);
3686 (define_expand "sgeu"
3687   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3688   ""
3689   "
3691   operands[1] = gen_compare_reg (GEU, SImode);
3694 (define_expand "sltu"
3695   [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3696   ""
3697   "
3699   operands[1] = gen_compare_reg (LTU, SImode);
3702 (define_insn_and_split "*scc_insn"
3703   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3704         (match_operator:SI 1 "proper_comparison_operator" [(reg 61) (const_int 0)]))]
3705   ""
3706   "#"
3707   "reload_completed"
3708   [(set (match_dup 0) (const_int 1))
3709    (cond_exec
3710      (match_dup 1)
3711      (set (match_dup 0) (const_int 0)))]
3713   operands[1]
3714     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3715                                          GET_MODE (XEXP (operands[1], 0))),
3716                       VOIDmode,
3717                       XEXP (operands[1], 0), XEXP (operands[1], 1));
3719   [(set_attr "type" "unary")])
3721 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3722 ;; that is one lower if the carry flag is set.
3724 ;; ??? Look up negscc insn.  See pa.md for example.
3725 (define_insn "*neg_scc_insn"
3726   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3727         (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3728                  [(reg 61) (const_int 0)])))]
3729   ""
3730   "mov %0,-1\;sub.%D1 %0,%0,%0"
3731   [(set_attr "type" "unary")
3732    (set_attr "length" "8")])
3734 (define_insn "*not_scc_insn"
3735   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3736         (not:SI (match_operator:SI 1 "proper_comparison_operator"
3737                  [(reg 61) (const_int 0)])))]
3738   ""
3739   "mov %0,1\;sub.%d1 %0,%0,%0"
3740   [(set_attr "type" "unary")
3741    (set_attr "length" "8")])
3743 ; cond_exec patterns
3744 (define_insn "*movsi_ne"
3745   [(cond_exec
3746      (ne (match_operand:CC_Z 2 "cc_use_register" "") (const_int 0))
3747      (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
3748           (match_operand:SI 1 "nonmemory_operand" "%C_0,Lc,?Cal")))]
3749   ""
3750   "@
3751         sub%?.ne %0,%0,%0%&
3752         mov.ne %0,%1
3753         mov.ne %0,%S1"
3754   [(set_attr "type" "cmove,cmove,cmove")
3755    (set_attr "iscompact" "true,false,false")
3756    (set_attr "length" "*,4,8")])
3758 (define_insn "*movsi_cond_exec"
3759   [(cond_exec
3760      (match_operator 3 "proper_comparison_operator"
3761        [(match_operand 2 "cc_register" "") (const_int 0)])
3762      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3763           (match_operand:SI 1 "nonmemory_operand" "%Lc,?Cal")))]
3764   ""
3765   "mov.%d3 %0,%S1"
3766   [(set_attr "type" "cmove")
3767    (set_attr "length" "4,8")])
3769 (define_insn "*add_cond_exec"
3770   [(cond_exec
3771      (match_operator 4 "proper_comparison_operator"
3772        [(match_operand 3 "cc_register" "") (const_int 0)])
3773      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3774           (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
3775                    (match_operand:SI 2 "nonmemory_operand" "cCca,?Cal"))))]
3776   ""
3777   "*return arc_output_addsi (operands, \".%d4\");"
3778   [(set_attr "cond" "use")
3779    (set_attr "type" "cmove")
3780    (set_attr "length" "4,8")])
3782 ; ??? and could use bclr,bmsk
3783 ; ??? or / xor could use bset / bxor
3784 (define_insn "*commutative_cond_exec"
3785   [(cond_exec
3786      (match_operator 5 "proper_comparison_operator"
3787        [(match_operand 4 "cc_register" "") (const_int 0)])
3788      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3789           (match_operator:SI 3 "commutative_operator"
3790             [(match_operand:SI 1 "register_operand" "%0,0")
3791              (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3792   ""
3793   "%O3.%d5 %0,%1,%2"
3794   [(set_attr "cond" "use")
3795    (set_attr "type" "cmove")
3796    (set_attr "length" "4,8")])
3798 (define_insn "*sub_cond_exec"
3799   [(cond_exec
3800      (match_operator 4 "proper_comparison_operator"
3801        [(match_operand 3 "cc_register" "") (const_int 0)])
3802      (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3803           (minus:SI (match_operand:SI 1 "register_operand" "0,cL,Cal")
3804                     (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3805   ""
3806   "@
3807         sub.%d4 %0,%1,%2
3808         rsub.%d4 %0,%2,%1
3809         rsub.%d4 %0,%2,%1"
3810   [(set_attr "cond" "use")
3811    (set_attr "type" "cmove")
3812    (set_attr "length" "4,4,8")])
3814 (define_insn "*noncommutative_cond_exec"
3815   [(cond_exec
3816      (match_operator 5 "proper_comparison_operator"
3817        [(match_operand 4 "cc_register" "") (const_int 0)])
3818      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3819           (match_operator:SI 3 "noncommutative_operator"
3820             [(match_operand:SI 1 "register_operand" "0,0")
3821              (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3822   ""
3823   "%O3.%d5 %0,%1,%2"
3824   [(set_attr "cond" "use")
3825    (set_attr "type" "cmove")
3826    (set_attr "length" "4,8")])
3828 ;; These control RTL generation for conditional jump insns
3830 (define_expand "beq"
3831   [(set (pc)
3832         (if_then_else (match_dup 1)
3833                       (label_ref (match_operand 0 "" ""))
3834                       (pc)))]
3835   ""
3836   "
3838   operands[1] = gen_compare_reg (EQ, VOIDmode);
3841 (define_expand "bne"
3842   [(set (pc)
3843         (if_then_else (match_dup 1)
3844                       (label_ref (match_operand 0 "" ""))
3845                       (pc)))]
3846   ""
3847   "
3849   operands[1] = gen_compare_reg (NE, VOIDmode);
3852 (define_expand "bgt"
3853   [(set (pc)
3854         (if_then_else (match_dup 1)
3855                       (label_ref (match_operand 0 "" ""))
3856                       (pc)))]
3857   ""
3858   "
3860   operands[1] = gen_compare_reg (GT, VOIDmode);
3863 (define_expand "ble"
3864   [(set (pc)
3865         (if_then_else (match_dup 1)
3866                       (label_ref (match_operand 0 "" ""))
3867                       (pc)))]
3868   ""
3869   "
3871   operands[1] = gen_compare_reg (LE, VOIDmode);
3874 (define_expand "bge"
3875   [(set (pc)
3876         (if_then_else (match_dup 1)
3877                       (label_ref (match_operand 0 "" ""))
3878                       (pc)))]
3879   ""
3880   "
3882   operands[1] = gen_compare_reg (GE, VOIDmode);
3885 (define_expand "blt"
3886   [(set (pc)
3887         (if_then_else (match_dup 1)
3888                       (label_ref (match_operand 0 "" ""))
3889                       (pc)))]
3890   ""
3891   "
3893   operands[1] = gen_compare_reg (LT, VOIDmode);
3896 (define_expand "bgtu"
3897   [(set (pc)
3898         (if_then_else (match_dup 1)
3899                       (label_ref (match_operand 0 "" ""))
3900                       (pc)))]
3901   ""
3902   "
3904   operands[1] = gen_compare_reg (GTU, VOIDmode);
3907 (define_expand "bleu"
3908   [(set (pc)
3909         (if_then_else (match_dup 1)
3910                       (label_ref (match_operand 0 "" ""))
3911                       (pc)))]
3912   ""
3913   "
3915   operands[1] = gen_compare_reg (LEU, VOIDmode);
3918 (define_expand "bgeu"
3919   [(set (pc)
3920         (if_then_else (match_dup 1)
3921                       (label_ref (match_operand 0 "" ""))
3922                       (pc)))]
3923   ""
3924   "
3926   operands[1] = gen_compare_reg (GEU, VOIDmode);
3929 (define_expand "bltu"
3930   [(set (pc)
3931         (if_then_else (match_dup 1)
3932                       (label_ref (match_operand 0 "" ""))
3933                       (pc)))]
3934   ""
3935   "
3937   operands[1] = gen_compare_reg (LTU, VOIDmode);
3940 (define_expand "bunge"
3941   [(set (pc)
3942         (if_then_else (match_dup 1)
3943                       (label_ref (match_operand 0 "" ""))
3944                       (pc)))]
3945   ""
3946   "
3948   operands[1] = gen_compare_reg (UNGE, VOIDmode);
3951 (define_expand "bungt"
3952   [(set (pc)
3953         (if_then_else (match_dup 1)
3954                       (label_ref (match_operand 0 "" ""))
3955                       (pc)))]
3956   ""
3957   "
3959   operands[1] = gen_compare_reg (UNGT, VOIDmode);
3962 (define_expand "bunle"
3963   [(set (pc)
3964         (if_then_else (match_dup 1)
3965                       (label_ref (match_operand 0 "" ""))
3966                       (pc)))]
3967   ""
3968   "
3970   operands[1] = gen_compare_reg (UNLE, VOIDmode);
3973 (define_expand "bunlt"
3974   [(set (pc)
3975         (if_then_else (match_dup 1)
3976                       (label_ref (match_operand 0 "" ""))
3977                       (pc)))]
3978   ""
3979   "
3981   operands[1] = gen_compare_reg (UNLT, VOIDmode);
3984 (define_expand "buneq"
3985   [(set (pc)
3986         (if_then_else (match_dup 1)
3987                       (label_ref (match_operand 0 "" ""))
3988                       (pc)))]
3989   ""
3990   "
3992   operands[1] = gen_compare_reg (UNEQ, VOIDmode);
3995 (define_expand "bltgt"
3996   [(set (pc)
3997         (if_then_else (match_dup 1)
3998                       (label_ref (match_operand 0 "" ""))
3999                       (pc)))]
4000   ""
4001   "
4003   operands[1] = gen_compare_reg (LTGT, VOIDmode);
4006 (define_expand "bordered"
4007   [(set (pc)
4008         (if_then_else (match_dup 1)
4009                       (label_ref (match_operand 0 "" ""))
4010                       (pc)))]
4011   ""
4012   "
4014   operands[1] = gen_compare_reg (ORDERED, VOIDmode);
4017 (define_expand "bunordered"
4018   [(set (pc)
4019         (if_then_else (match_dup 1)
4020                       (label_ref (match_operand 0 "" ""))
4021                       (pc)))]
4022   ""
4023   "
4025   operands[1] = gen_compare_reg (UNORDERED, VOIDmode);
4028 ;; Now match both normal and inverted jump.
4030 ;; TODO - supporting 16-bit conditional short branch insns if needed.
4032 ; (define_insn "*branch_insn_mixed"
4033 ;   [(set (pc)
4034 ;       (if_then_else (match_operator 1 "comparison_operator"
4035 ;                                     [(reg 61) (const_int 0)])
4036 ;                     (label_ref (match_operand 0 "" ""))
4037 ;                     (pc)))]
4038 ;   "TARGET_MIXED_CODE"
4039 ;   "*
4040 ; {
4041 ;   if (arc_ccfsm_branch_deleted_p ())
4042 ;     {
4043 ;       arc_ccfsm_record_branch_deleted ();
4044 ;       return \"; branch deleted, next insns conditionalized\";
4045 ;     }
4046 ;   else
4047 ;     return \"b%d1_s %^%l0\";
4048 ; }"
4049 ;  [(set_attr "type" "branch")])
4051 ; When estimating sizes during arc_reorg, when optimizing for speed, there
4052 ; are three reasons why we need to consider branches to be length 6:
4053 ; - unnull-false delay slot insns are implemented using conditional execution,
4054 ;   thus preventing short insn formation where used.
4055 ; - for ARC600: unnul-true delay slot isnns are implemented where possile
4056 ;   using conditional execution, preventing short insn formation where used.
4057 ; - for ARC700: likely or somewhat likely taken branches are made long and
4058 ;   unaligned if possible to avoid branch penalty.
4059 (define_insn "*branch_insn"
4060   [(set (pc)
4061         (if_then_else (match_operator 1 "proper_comparison_operator"
4062                                       [(reg 61) (const_int 0)])
4063                       (label_ref (match_operand 0 "" ""))
4064                       (pc)))]
4065   ""
4066   "*
4068   if (arc_ccfsm_branch_deleted_p ())
4069     {
4070       arc_ccfsm_record_branch_deleted ();
4071       return \"; branch deleted, next insns conditionalized\";
4072     }
4073   else
4074     {
4075       arc_ccfsm_record_condition (operands[1], 0, insn, 0);
4076       if (get_attr_length (insn) == 2)
4077          return \"b%d1%? %^%l0%&\";
4078       else
4079          return \"b%d1%# %^%l0\";
4080     }
4082   [(set_attr "type" "branch")
4083    (set
4084      (attr "lock_length")
4085      (cond [
4086        ; In arc_reorg we just guesstimate; might be more or less.
4087        (ne (symbol_ref "arc_branch_size_unknown_p ()") (const_int 0))
4088        (const_int 4)
4090        (eq_attr "delay_slot_filled" "yes")
4091        (const_int 4)
4093        (ne
4094          (if_then_else
4095            (match_operand 1 "equality_comparison_operator" "")
4096            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4097                 (gt (minus (match_dup 0) (pc))
4098                     (minus (const_int 506)
4099                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4100            (ior (lt (minus (match_dup 0) (pc)) (const_int -64))
4101                 (gt (minus (match_dup 0) (pc))
4102                     (minus (const_int 58)
4103                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
4104          (const_int 0))
4105        (const_int 4)
4107        (eq_attr "verify_short" "yes")
4108        (const_int 2)]
4109       (const_int 4)))
4110    (set (attr "iscompact")
4111         (cond [(eq_attr "lock_length" "2") (const_string "true")]
4112               (const_string "false")))])
4114 (define_insn "*rev_branch_insn"
4115   [(set (pc)
4116         (if_then_else (match_operator 1 "proper_comparison_operator"
4117                                       [(reg 61) (const_int 0)])
4118                       (pc)
4119                       (label_ref (match_operand 0 "" ""))))]
4120   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
4121   "*
4123   if (arc_ccfsm_branch_deleted_p ())
4124     {
4125       arc_ccfsm_record_branch_deleted ();
4126       return \"; branch deleted, next insns conditionalized\";
4127     }
4128   else
4129     {
4130       arc_ccfsm_record_condition (operands[1], 1, insn, 0);
4131       if (get_attr_length (insn) == 2)
4132          return \"b%D1%? %^%l0\";
4133       else
4134          return \"b%D1%# %^%l0\";
4135     }
4137   [(set_attr "type" "branch")
4138    (set
4139      (attr "lock_length")
4140      (cond [
4141        ; In arc_reorg we just guesstimate; might be more or less.
4142        (ne (symbol_ref "arc_branch_size_unknown_p ()") (const_int 0))
4143        (const_int 4)
4145        (eq_attr "delay_slot_filled" "yes")
4146        (const_int 4)
4148        (ne
4149          (if_then_else
4150            (match_operand 1 "equality_comparison_operator" "")
4151            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4152                 (gt (minus (match_dup 0) (pc))
4153                     (minus (const_int 506)
4154                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4155            (ior (lt (minus (match_dup 0) (pc)) (const_int -64))
4156                 (gt (minus (match_dup 0) (pc))
4157                     (minus (const_int 58)
4158                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
4159          (const_int 0))
4160        (const_int 4)
4162        (eq_attr "verify_short" "yes")
4163        (const_int 2)]
4164       (const_int 4)))
4165    (set (attr "iscompact")
4166         (cond [(eq_attr "lock_length" "2") (const_string "true")]
4167               (const_string "false")))])
4169 ;; Unconditional and other jump instructions.
4171 ;; TODO - supporting 16-bit short branch insns if needed.
4172 ;(define_insn "*jump_mixed"
4173 ;  [(set (pc) (label_ref (match_operand 0 "" "")))]
4174 ;  "TARGET_MIXED_CODE"
4175 ;  "b_s %^%l0"
4176 ;  [(set_attr "type" "uncond_branch")])
4178 (define_expand "jump"
4179   [(set (pc) (label_ref (match_operand 0 "" "")))]
4180   ""
4181   "")
4183 (define_insn "jump_i"
4184   [(set (pc) (label_ref (match_operand 0 "" "")))]
4185   "!TARGET_LONG_CALLS_SET || !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
4186   "b%!%* %^%l0%&"
4187   [(set_attr "type" "uncond_branch")
4188    (set (attr "iscompact")
4189         (if_then_else (eq_attr "lock_length" "2")
4190                       (const_string "true") (const_string "false")))
4191    (set_attr "cond" "canuse")
4192    (set (attr "lock_length")
4193         (cond [
4194           ; In arc_reorg we just guesstimate; might be more or less.
4195           (ne (symbol_ref "arc_branch_size_unknown_p ()") (const_int 0))
4196           (const_int 4)
4198           (eq_attr "delay_slot_filled" "yes")
4199           (const_int 4)
4201           (ne (symbol_ref "find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)")
4202               (const_int 0))
4203           (const_int 4)
4205           (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4206                (gt (minus (match_dup 0) (pc))
4207                    (minus (const_int 506)
4208                           (symbol_ref "get_attr_delay_slot_length (insn)"))))
4209           (const_int 4)
4211           (and (ne (symbol_ref "arc_ccfsm_advance_to (insn),
4212                                 arc_ccfsm_cond_exec_p ()")
4213                    (const_int 0))
4214                (ior (lt (minus (match_dup 0) (pc)) (const_int -64))
4215                     (gt (minus (match_dup 0) (pc))
4216                         (minus (const_int 58)
4217                                (symbol_ref
4218                                 "get_attr_delay_slot_length (insn)")))))
4219           (const_int 4)
4221           (eq_attr "verify_short" "yes")
4222           (const_int 2)]
4224          (const_int 4)))])
4226 (define_insn "indirect_jump"
4227   [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
4228   ""
4229   "j%!%* [%0]%&"
4230   [(set_attr "type" "jump")
4231    (set_attr "iscompact" "false,false,false,maybe,false")
4232    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
4234 ;; (define_insn "indirect_jump"
4235 ;;   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
4236 ;;   ""
4237 ;;   "j%* [%0]"
4238 ;;   [(set_attr "type" "jump")])
4240 ;; Implement a switch statement.
4241 ; ??? the following comment shows ignorance of gcc internals
4242 ; - or possibly code that old that it predates the current facilities.
4243 ;; This wouldn't be necessary in the non-pic case if we could distinguish
4244 ;; label refs of the jump table from other label refs.  The problem is that
4245 ;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
4246 ;; the real address since it's the address of the table.
4248 (define_expand "casesi"
4249   [(set (match_dup 5)
4250         (minus:SI (match_operand:SI 0 "register_operand" "")
4251                   (match_operand:SI 1 "nonmemory_operand" "")))
4252    (set (reg:CC CC_REG)
4253         (compare:CC (match_dup 5)
4254                     (match_operand:SI 2 "nonmemory_operand" "")))
4255    (set (pc)
4256         (if_then_else (gtu (reg:CC 61)
4257                            (const_int 0))
4258                       (label_ref (match_operand 4 "" ""))
4259                       (pc)))
4260    (set (match_dup 6)
4261         (unspec:SI [(match_operand 3 "" "")
4262                     (match_dup 5) (match_dup 7)] UNSPEC_CASESI))
4263    (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
4264   ""
4265   "
4267   rtx x;
4269   operands[5] = gen_reg_rtx (SImode);
4270   operands[6] = gen_reg_rtx (SImode);
4271   operands[7] = operands[3];
4272   emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4273   emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4274   x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4275   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4276                             gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4277   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
4278   if (TARGET_COMPACT_CASESI)
4279     {
4280       emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4281     }
4282   else
4283     {
4284       operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4285       if (flag_pic || !cse_not_expected)
4286         operands[3] = force_reg (Pmode, operands[3]);
4287       emit_insn (gen_casesi_load (operands[6],
4288                                   operands[3], operands[5], operands[7]));
4289       if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4290         emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4291       emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4292     }
4293   DONE;
4296 (define_insn "casesi_load"
4297   [(set (match_operand:SI 0 "register_operand"             "=Rcq,r,r")
4298         (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4299                     (match_operand:SI 2 "register_operand"  "Rcq,c,c")
4300                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))]
4301   ""
4302   "*
4304   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
4306   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4307     {
4308       gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4309       gcc_assert (GET_MODE (diff_vec) == SImode);
4310       gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4311     }
4313   switch (GET_MODE (diff_vec))
4314     {
4315     case SImode:
4316       return \"ld.as %0,[%1,%2]%&\";
4317     case HImode:
4318       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4319         return \"ldw.as %0,[%1,%2]\";
4320       return \"ldw.x.as %0,[%1,%2]\";
4321     case QImode:
4322       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4323         return \"ldb%? %0,[%1,%2]%&\";
4324       return \"ldb.x %0,[%1,%2]\";
4325     default:
4326       gcc_unreachable ();
4327     }
4329   [(set_attr "type" "load")
4330    (set_attr_alternative "iscompact"
4331      [(cond
4332         [(ne (symbol_ref "GET_MODE (PATTERN (next_real_insn (operands[3])))")
4333              (symbol_ref "QImode"))
4334          (const_string "false")
4335          (eq (symbol_ref "ADDR_DIFF_VEC_FLAGS (PATTERN (next_real_insn (operands[3]))).offset_unsigned") (const_int 0))
4336          (const_string "false")]
4337         (const_string "true"))
4338       (const_string "false")
4339       (const_string "false")])
4340    (set_attr_alternative "length"
4341      [(cond
4342         [(eq_attr "iscompact" "false")
4343          (const_int 4)
4344          (and (ne (symbol_ref "0") (const_int 0)) (eq (match_dup 0) (pc)))
4345          (const_int 4)
4346          (eq_attr "verify_short" "yes")
4347          (const_int 2)]
4348         (const_int 4))
4349       (const_int 4)
4350       (const_int 8)])])
4352 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4353 ; even for CASE_VECTOR_PC_RELATIVE.
4354 (define_insn "casesi_jump"
4355   [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4356    (use (label_ref (match_operand 1 "" "")))]
4357   ""
4358   "j%!%* [%0]%&"
4359   [(set_attr "type" "jump")
4360    (set_attr "iscompact" "false,maybe,false")
4361    (set_attr "cond" "canuse")])
4363 (define_insn "casesi_compact_jump"
4364   [(set (pc)
4365         (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4366                    UNSPEC_CASESI))
4367    (use (label_ref (match_operand 1 "" "")))
4368    (clobber (match_scratch:SI 2 "=q,0"))]
4369   "TARGET_COMPACT_CASESI"
4370   "*
4372   rtx diff_vec = PATTERN (next_real_insn (operands[1]));
4373   int unalign = arc_get_unalign ();
4374   rtx xop[3];
4375   const char *s;
4377   xop[0] = operands[0];
4378   xop[2] = operands[2];
4379   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4381   switch (GET_MODE (diff_vec))
4382     {
4383     case SImode:
4384       /* Max length can be 12 in this case, but this is OK because
4385          2 of these are for alignment, and are anticipated in the length
4386          of the ADDR_DIFF_VEC.  */
4387       if (unalign && !satisfies_constraint_Rcq (xop[0]))
4388         s = \"add2 %2,pcl,%0\n\tld_s%2,[%2,12]\";
4389       else if (unalign)
4390         s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4391       else
4392         s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4393       arc_clear_unalign ();
4394       break;
4395     case HImode:
4396       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4397         {
4398           if (satisfies_constraint_Rcq (xop[0]))
4399             {
4400               s = \"add_s %2,%0,%1\n\tldw.as %2,[pcl,%2]\";
4401               xop[1] = GEN_INT ((10 - unalign) / 2U);
4402             }
4403           else
4404             {
4405               s = \"add1 %2,pcl,%0\n\tldw_s %2,[%2,%1]\";
4406               xop[1] = GEN_INT (10 + unalign);
4407             }
4408         }
4409       else
4410         {
4411           if (satisfies_constraint_Rcq (xop[0]))
4412             {
4413               s = \"add_s %2,%0,%1\n\tldw.x.as %2,[pcl,%2]\";
4414               xop[1] = GEN_INT ((10 - unalign) / 2U);
4415             }
4416           else
4417             {
4418               s = \"add1 %2,pcl,%0\n\tldw_s.x %2,[%2,%1]\";
4419               xop[1] = GEN_INT (10 + unalign);
4420             }
4421         }
4422       arc_toggle_unalign ();
4423       break;
4424     case QImode:
4425       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4426         {
4427           if (rtx_equal_p (xop[2], xop[0])
4428               || find_reg_note (insn, REG_DEAD, xop[0]))
4429             {
4430               s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4431               xop[1] = GEN_INT (8 + unalign);
4432             }
4433           else
4434             {
4435               s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4436               xop[1] = GEN_INT (10 + unalign);
4437               arc_toggle_unalign ();
4438             }
4439         }
4440       else if (rtx_equal_p (xop[0], xop[2])
4441                || find_reg_note (insn, REG_DEAD, xop[0]))
4442         {
4443           s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4444           xop[1] = GEN_INT (10 - unalign);
4445           arc_toggle_unalign ();
4446         }
4447       else
4448         {
4449           /* ??? Length is 12.  */
4450           s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4451           xop[1] = GEN_INT (8 + unalign);
4452         }
4453       break;
4454     default:
4455       gcc_unreachable ();
4456     }
4457   output_asm_insn (s, xop);
4458   return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4460   [(set_attr "length" "10")
4461    (set_attr "type" "jump")
4462    (set_attr "iscompact" "true")
4463    (set_attr "cond" "nocond")])
4465 ;; TODO: Splitting it up as separate patterns (when enabling this pattern) for
4466 ;;       TARGET_MIXED_CODE so that length can be set correctly.
4467 (define_insn "tablejump"
4468   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
4469    (use (label_ref (match_operand 1 "" "")))]
4470   "0 /* disabled -> using casesi now */"
4471   "j%* %a0"
4472   [(set_attr "type" "jump")])
4474 (define_expand "call"
4475   ;; operands[1] is stack_size_rtx
4476   ;; operands[2] is next_arg_register
4477   [(parallel [(call (match_operand:SI 0 "call_operand" "")
4478                     (match_operand 1 "" ""))
4479              (clobber (reg:SI 31))])]
4480   ""
4481   "{
4482     rtx callee;
4484     gcc_assert (MEM_P (operands[0]));
4485     callee  = XEXP (operands[0], 0);
4486     if (crtl->profile && arc_profile_call (callee))
4487       {
4488         emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
4489                                                            \"_mcount_call\"),
4490                                        operands[1]));
4491         DONE;
4492       }
4493     /* This is to decide if we should generate indirect calls by loading the
4494        32 bit address of the callee into a register before performing the
4495        branch and link - this exposes cse opportunities.
4496        Also, in weird cases like compile/20010107-1.c, we may get a PLUS.  */
4497     if (GET_CODE (callee) != REG
4498         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4499       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4500   }
4504 (define_insn "*call_i"
4505   [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Rcqq,c,Cbr,L,I,Cal"))
4506          (match_operand 1 "" ""))
4507    (clobber (reg:SI 31))]
4508   ""
4509   "@
4510    jl%!%* [%0]%&
4511    jl%!%* [%0]
4512    bl%!%* %P0
4513    jl%!%* %S0
4514    jl%* %S0
4515    jl%! %S0"
4516   [(set_attr "type" "call,call,call,call,call,call_no_delay_slot")
4517    (set_attr "iscompact" "maybe,*,*,*,*,*")
4518    (set_attr_alternative "cond"
4519      [(const_string "canuse")
4520       (const_string "canuse")
4521       (cond [(eq (symbol_ref "TARGET_MEDIUM_CALLS") (const_int 0))
4522              (const_string "canuse")
4523              (eq_attr "delay_slot_filled" "yes")
4524              (const_string "nocond")
4525              (eq (symbol_ref "flag_pic") (const_int 0))
4526              (const_string "canuse_limm")]
4527             (const_string "nocond"))
4528       (const_string "canuse")
4529       (if_then_else (eq_attr "delay_slot_filled" "yes")
4530                     (const_string "nocond")
4531                     (const_string "canuse_limm"))
4532       (const_string "canuse")])
4533    (set_attr "length" "*,4,4,4,4,8")])
4535 (define_insn "call_prof"
4536   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal"))
4537          (match_operand 1 "" ""))
4538    (clobber (reg:SI 31))
4539    (use (reg:SI 8))
4540    (use (reg:SI 9))]
4541    ""
4542   "@
4543    bl%!%* %P0;2
4544    jl%! %^%S0"
4545   [(set_attr "type" "call,call_no_delay_slot")
4546    (set_attr "cond" "canuse,canuse")
4547    (set_attr "length" "4,8")])
4549 (define_expand "call_value"
4550   ;; operand 2 is stack_size_rtx
4551   ;; operand 3 is next_arg_register
4552   [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4553                    (call (match_operand:SI 1 "call_operand" "")
4554                          (match_operand 2 "" "")))
4555              (clobber (reg:SI 31))])]
4556   ""
4557   "
4558   {
4559     rtx callee;
4561     gcc_assert (MEM_P (operands[1]));
4562     callee = XEXP (operands[1], 0);
4563     if (crtl->profile && arc_profile_call (callee))
4564       {
4565         emit_call_insn (gen_call_value_prof (operands[0],
4566                                              gen_rtx_SYMBOL_REF (Pmode,
4567                                                             \"_mcount_call\"),
4568                                              operands[2]));
4569         DONE;
4570       }
4571      /* See the comment in define_expand \"call\".  */
4572     if (GET_CODE (callee) != REG
4573         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4574       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4575   }")
4578 (define_insn "*call_value_i"
4579   [(set (match_operand 0 "dest_reg_operand"  "=Rcqq,w,  w,w,w,  w")
4580         (call (mem:SI (match_operand:SI 1
4581                        "call_address_operand" "Rcqq,c,Cbr,L,I,Cal"))
4582               (match_operand 2 "" "")))
4583    (clobber (reg:SI 31))]
4584   ""
4585   "@
4586    jl%!%* [%1]%&
4587    jl%!%* [%1]
4588    bl%!%* %P1;1
4589    jl%!%* %S1
4590    jl%* %S1
4591    jl%! %S1"
4592   [(set_attr "type" "call,call,call,call,call,call_no_delay_slot")
4593    (set_attr "iscompact" "maybe,*,*,*,*,*")
4594    (set_attr_alternative "cond"
4595      [(const_string "canuse")
4596       (const_string "canuse")
4597       (cond [(eq (symbol_ref "TARGET_MEDIUM_CALLS") (const_int 0))
4598              (const_string "canuse")
4599              (eq_attr "delay_slot_filled" "yes")
4600              (const_string "nocond")
4601              (eq (symbol_ref "flag_pic") (const_int 0))
4602              (const_string "canuse_limm")]
4603             (const_string "nocond"))
4604       (const_string "canuse")
4605       (const_string "canuse_limm")
4606       (const_string "canuse")])
4607    (set_attr "length" "*,4,4,4,4,8")])
4610 ;; TODO - supporting 16-bit short "branch and link" insns if required.
4611 ;(define_insn "*call_value_via_label_mixed"
4612 ;  [(set (match_operand 0 "register_operand" "=r")
4613 ;        (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
4614 ;              (match_operand 2 "" "")))
4615 ;  (clobber (reg:SI 31))]
4616 ;  "TARGET_MIXED_CODE"
4617 ;  "bl_s %1"
4618 ;  [(set_attr "type" "call")])
4620 (define_insn "call_value_prof"
4621   [(set (match_operand 0 "dest_reg_operand" "=r,r")
4622         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal"))
4623               (match_operand 2 "" "")))
4624    (clobber (reg:SI 31))
4625    (use (reg:SI 8))
4626    (use (reg:SI 9))]
4627    ""
4628   "@
4629    bl%!%* %P1;1
4630    jl%! %^%S1"
4631   [(set_attr "type" "call,call_no_delay_slot")
4632    (set_attr "cond" "canuse,canuse")
4633    (set_attr "length" "4,8")])
4635 (define_insn "nop"
4636   [(const_int 0)]
4637   ""
4638   "nop%?"
4639   [(set_attr "type" "misc")
4640    (set_attr "iscompact" "true")
4641    (set_attr "cond" "canuse")
4642    (set_attr "length" "2")])
4644 ;; Special pattern to flush the icache.
4645 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
4647 (define_insn "flush_icache"
4648   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4649   ""
4650   "* return \"\";"
4651   [(set_attr "type" "misc")])
4653 ;; Split up troublesome insns for better scheduling.
4655 ;; Peepholes go at the end.
4656 ;;asl followed by add can be replaced by an add{1,2,3}
4657 ;; Three define_peepholes have been added for this optimization
4658 ;; ??? This used to target non-canonical rtl.  Now we use add_n, which
4659 ;; can be generated by combine.  Check if these peepholes still provide
4660 ;; any benefit.
4662 ;; -------------------------------------------------------------
4663 ;; Pattern 1 : r0 = r1 << {i}
4664 ;;             r3 = r4/INT + r0     ;;and commutative
4665 ;;                 ||
4666 ;;                 \/
4667 ;;             add{i} r3,r4/INT,r1
4668 ;; -------------------------------------------------------------
4670 (define_peephole2
4671   [(set (match_operand:SI 0 "dest_reg_operand" "")
4672         (ashift:SI (match_operand:SI 1 "register_operand" "")
4673                    (match_operand:SI 2 "const_int_operand" "")))
4674   (set (match_operand:SI 3 "dest_reg_operand" "")
4675        (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4676                 (match_operand:SI 5 "nonmemory_operand" "")))]
4677   "TARGET_ARCOMPACT
4678    && TARGET_DROSS
4679    && (INTVAL (operands[2]) == 1
4680        || INTVAL (operands[2]) == 2
4681        || INTVAL (operands[2]) == 3)
4682    && (true_regnum (operands[4]) == true_regnum (operands[0])
4683        || true_regnum (operands[5]) == true_regnum (operands[0]))
4684    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4685  ;; the preparation statements take care to put proper operand in operands[4]
4686  ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4687   [(set (match_dup 3)
4688         (plus:SI (mult:SI (match_dup 1)
4689                           (match_dup 2))
4690                  (match_dup 4)))]
4691   "DROSS (\"addn peephole2\");
4692    if (true_regnum (operands[4]) == true_regnum (operands[0]))
4693       operands[4] = operands[5];
4694    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4697 ;; triggered by -g -O2 -mARC600 -mmul64 -mnorm
4698 ;; libstdc++-v3/testsuite/23_containers/deque/check_construct_destroy.cc
4699 (define_peephole
4700   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4701         (ashift:SI (match_operand:SI 1 "register_operand" "c,c")
4702                    (match_operand:SI 2 "const_int_operand" "n,n")))
4703   (set (match_operand:SI 3 "dest_reg_operand" "=w,w")
4704        (plus:SI (match_operand:SI 4 "nonmemory_operand" "ci,0")
4705                 (match_operand:SI 5 "nonmemory_operand" "0,ci")))]
4706   "TARGET_ARCOMPACT
4707    && (INTVAL (operands[2]) == 1
4708        || INTVAL (operands[2]) == 2
4709        || INTVAL (operands[2]) == 3)
4710    && (true_regnum (operands[4]) == true_regnum (operands[0])
4711        || true_regnum (operands[5]) == true_regnum (operands[0]))
4712    && arc_dead_or_set_postreload_p (insn, operands[0])"
4713   "*{
4714     DROSS (\"addn_peephole\");
4715     /* This handles commutativity */
4716     if (which_alternative == 1)
4717       operands[4] = operands[5];
4718     switch (INTVAL (operands[2])) {
4719          case 1: return \"add1 %3,%S4,%1;;addi peephole - pattern 1\";
4720          case 2: return \"add2 %3,%S4,%1;;addi peephole - pattern 2\";
4721          case 3: return \"add3 %3,%S4,%1;;addi peephole - pattern 3\";
4722          default: gcc_unreachable ();
4723     }
4724   }"
4725   [(set_attr "length" "8")]
4728 ; ??? For ARC700, bbit peepholes should be replaced with a combiner pattern
4729 ; combining a CC_Z btst with a bne/beq, and then properly branch shortened.
4730 ; The combined pattern should be grokked by the ccfsm machinery.
4731 ; For ARC600, the peephole should be adjusted to use btst as input.
4733 ; bbit0, bbit1 peephole that incorporates bic
4734 (define_peephole
4735   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4736         (and:SI (not:SI (match_operand:SI 1 "register_operand" "c"))
4737                 (match_operand:SI 2 "immediate_operand" "Cal")))
4738    (set (reg:CC_ZN 61)
4739         (compare:CC_ZN (match_dup 0)
4740                        (match_operand:SI 3 "immediate_operand" "Cal")))
4741    (set (pc)
4742         (if_then_else (match_operator 4 "proper_comparison_operator"
4743                                       [(reg 61) (const_int 0)])
4744                       (label_ref (match_operand 5 "" ""))
4745                       (pc)))
4746   ]
4747   "TARGET_ARCOMPACT
4748    && valid_bbit_pattern_p (operands,insn)
4749    && arc_dead_or_set_postreload_p (prev_nonnote_insn (insn), operands[0])
4750    && arc_dead_or_set_postreload_p (insn, XEXP (operands[4], 0))"
4751    "* return gen_bbit_bic_insns (operands);"
4752    [(set_attr "type" "branch")
4753     (set_attr "length" "4")]
4757 ; bbit0,bbit1 peephole optimization
4759 (define_peephole
4760   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4761         (and:SI (match_operand:SI 1 "register_operand" "%c")
4762                 (match_operand:SI 2 "immediate_operand" "Cal")))
4763    (set (reg:CC_ZN 61)
4764         (compare:CC_ZN (match_dup 0)
4765                        (match_operand:SI 3 "immediate_operand" "Cal")))
4766    (set (pc)
4767         (if_then_else (match_operator 4 "proper_comparison_operator"
4768                         [(reg 61) (const_int 0)])
4769                       (label_ref (match_operand 5 "" ""))
4770                       (pc)))
4772   "TARGET_ARCOMPACT
4773    && valid_bbit_pattern_p (operands,insn)
4774    && arc_dead_or_set_postreload_p (prev_nonnote_insn(insn), operands [0])"
4775   "* return gen_bbit_insns(operands);"
4776   [ (set_attr "type" "branch")
4777     (set_attr "length" "4")])
4780 ;; bset peephole2 optimization
4781 (define_peephole2
4782   [(set (match_operand:SI 0 "dest_reg_operand" "")
4783         (const_int 1))
4784   (set (match_operand:SI 1 "dest_reg_operand" "")
4785         (ashift:SI (match_dup 0)
4786                    (match_operand:SI 2 "register_operand" "")))
4787   (set (match_operand:SI 3 "dest_reg_operand" "")
4788        (ior:SI (match_operand:SI 4 "nonmemory_operand" "")
4789                (match_operand:SI 5 "nonmemory_operand" "")))]
4790   "TARGET_ARCOMPACT
4791    && TARGET_DROSS
4792    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[1]) == true_regnum (operands[0])))
4793    && (peep2_reg_dead_p (3, operands[1]) || (true_regnum (operands[3]) == true_regnum (operands[1])))
4794    && (true_regnum (operands[4]) == true_regnum (operands[1])
4795        || true_regnum (operands[5]) == true_regnum (operands[1]))"
4796   [(set (match_dup 3)
4797         (ior:SI (match_dup 4)
4798                 (ashift:SI (const_int 1) (match_dup 2))))]  
4799   "DROSS (\"bset peephole2\");
4800    if (true_regnum (operands[4]) == true_regnum (operands[1]))
4801       operands[4] = operands[5];"
4805 ;; -------------------------------------------------------------
4806 ;; Pattern 1 : r0 = r1 << {i}
4807 ;;             r3 = r4 - r0 
4808 ;;                 ||
4809 ;;                 \/
4810 ;;             sub{i} r3,r4,r1
4811 ;; -------------------------------------------------------------
4813 (define_peephole2
4814   [(set (match_operand:SI 0 "dest_reg_operand" "")
4815         (ashift:SI (match_operand:SI 1 "register_operand" "")
4816                    (match_operand:SI 2 "const_int_operand" "")))
4817    (set (match_operand:SI 3 "dest_reg_operand" "")
4818         (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4819                   (match_dup 0)))]
4820   "TARGET_ARCOMPACT
4821    && TARGET_DROSS
4822    && (INTVAL (operands[2]) == 1
4823        || INTVAL (operands[2]) == 2
4824        || INTVAL (operands[2]) == 3)
4825    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4826   [(set (match_dup 3)
4827         (minus:SI (match_dup 4)
4828                   (mult:SI (match_dup 1)
4829                            (match_dup 2))))]
4830   "DROSS (\"subn peephole2 1/2\");
4831    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4834 (define_peephole
4835   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4836         (ashift:SI (match_operand:SI 1 "register_operand" "c")
4837                    (match_operand:SI 2 "const_int_operand" "i")))
4838   (set (match_operand:SI 3 "dest_reg_operand" "=r")
4839        (minus:SI (match_operand:SI 4 "nonmemory_operand" "cCal")
4840                 (match_dup 0)))]
4841   "TARGET_ARCOMPACT
4842    && TARGET_DROSS
4843    && (INTVAL (operands[2]) == 1
4844        || INTVAL (operands[2]) == 2
4845        || INTVAL (operands[2]) == 3)
4846    && arc_dead_or_set_postreload_p (insn, operands[0])"
4847   "*
4848    {
4849      DROSS (\"subn peephole 1/2\");
4850      switch (INTVAL (operands[2]))
4851        {
4852        case 1: return \";;sub1 peephole - pattern 1\;sub1%? %3,%S4,%1\";
4853        case 2: return \";;sub2 peephole - pattern 1\;sub2%? %3,%S4,%1\";
4854        case 3: return \";;sub3 peephole - pattern 1\;sub3%? %3,%S4,%1\";
4855        default: gcc_unreachable ();
4856        }
4857     }"
4858     [(set_attr "length" "4")]
4863 ;; -------------------------------------------------------------
4864 ;; Pattern 2 : r0 = r1 << {i}
4865 ;;             r3 = INT
4866 ;;             r5 = r3 - r0
4867 ;;                 ||
4868 ;;                 \/
4869 ;;             sub{i} r5,INT,r1
4870 ;; -------------------------------------------------------------
4872 (define_peephole2
4873   [(set (match_operand:SI 0 "dest_reg_operand" "")
4874        (ashift:SI (match_operand:SI 1 "register_operand" "")
4875                   (match_operand:SI 2 "immediate_operand" "")))
4876    (set (match_operand:SI 3 "dest_reg_operand" "") 
4877         (match_operand:SI 4 "immediate_operand" ""))
4878    (set (match_operand:SI 5 "dest_reg_operand" "")
4879         (minus:SI (match_dup 3)
4880                   (match_dup 0)))]
4881   "TARGET_ARCOMPACT
4882    && TARGET_DROSS
4883    && GET_CODE (operands[2]) == CONST_INT 
4884    && (INTVAL (operands[2]) == 1
4885        || INTVAL (operands[2]) == 2
4886        || INTVAL (operands[2]) == 3)
4887    && (peep2_reg_dead_p (3, operands[0]) || (true_regnum (operands[5]) == true_regnum (operands[0])))
4888    && (peep2_reg_dead_p (3, operands[3]) || (true_regnum (operands[5]) == true_regnum (operands[3])))"
4889   [(set (match_dup 5)
4890         (minus:SI (match_dup 4)
4891                   (mult:SI (match_dup 1)
4892                            (match_dup 2))))]
4893   "DROSS (\"subn peephole2 2/2\");
4894    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4897 (define_peephole
4898   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4899        (ashift:SI (match_operand:SI 1 "register_operand" "c")
4900                   (match_operand:SI 2 "immediate_operand" "Cal")))
4901    (set (match_operand:SI 3 "dest_reg_operand" "=w") 
4902         (match_operand:SI 4 "immediate_operand" "Cal"))
4903    (set (match_operand:SI 5 "dest_reg_operand" "=w")
4904        (minus:SI (match_dup 3)
4905                 (match_dup 0)
4906                 ))]
4907   "TARGET_ARCOMPACT
4908    && TARGET_DROSS
4909    && GET_CODE (operands[2]) == CONST_INT 
4910    && (INTVAL (operands[2]) == 1
4911        ||  INTVAL (operands[2]) == 2
4912        ||  INTVAL (operands[2]) == 3)
4913    && arc_dead_or_set_postreload_p (insn, operands[3])
4914    && arc_dead_or_set_postreload_p (insn, operands[0])"
4915   "*
4916    {
4917      DROSS (\"subn peephole 2/2\");
4918      switch (INTVAL (operands[2]))
4919        {
4920        case 1: return \";;sub1 peephole - pattern 2\;sub1%? %5,%S4,%1\";
4921        case 2: return \";;sub2 peephole - pattern 2\;sub2%? %5,%S4,%1\";
4922        case 3: return \";;sub3 peephole - pattern 2\;sub3%? %5,%S4,%1\";
4923        default: gcc_unreachable ();
4924        }
4925    }"
4926     [(set_attr "length" "4")]
4929 ;;bxor peephole2
4930 (define_peephole2
4931   [(set (match_operand:SI 0 "dest_reg_operand" "")
4932         (const_int 1))
4933   (set (match_operand:SI 1 "dest_reg_operand" "")
4934         (ashift:SI (match_dup 0)
4935                    (match_operand:SI 2 "register_operand" "")))
4936   (set (match_operand:SI 3 "dest_reg_operand" "")
4937        (xor:SI (match_operand:SI 4 "nonmemory_operand" "")
4938                (match_operand:SI 5 "nonmemory_operand" ""))) 
4941   TARGET_ARCOMPACT
4942   && TARGET_DROSS
4943   && ( peep2_reg_dead_p (3, operands[1]) || ( true_regnum(operands[3])==true_regnum(operands[1]) ) )
4944   && ( peep2_reg_dead_p (2, operands[0]) || ( true_regnum(operands[1])==true_regnum(operands[0]) ) )
4945   && ( true_regnum(operands[4])==true_regnum(operands[1]) || true_regnum(operands[5])==true_regnum(operands[1]) )"
4947  ;; the preparation statements take care to put proper operand in operands[4]
4948  ;; operands[4] will always contain the correct operand
4949  [(set (match_dup 3)
4950         (xor:SI (match_dup 4)
4951                 (ashift:SI (const_int 1)
4952                         (match_dup 2) ) ) ) ]
4954   "DROSS (\"bxor peephole2\");
4955    if ( true_regnum(operands[4])==true_regnum(operands[1]) )
4956         operands[4] = operands[5];
4957   "
4960 ;; bclr peephole2 optimization 
4961 (define_peephole2
4962   [(set (match_operand:SI 0 "dest_reg_operand" "")
4963         (const_int 1))
4964    (set (match_operand:SI 1 "dest_reg_operand" "")
4965        (ashift:SI (match_dup 0)
4966                   (match_operand:SI 2 "register_operand" "")))
4967    (set (match_operand:SI 3 "dest_reg_operand" "")
4968         (and:SI (not:SI (match_dup 1))
4969                 (match_operand:SI 4 "nonmemory_operand" "")))]
4970   "TARGET_ARCOMPACT 
4971    && TARGET_DROSS
4972    && ( peep2_reg_dead_p (2, operands[0]) || true_regnum(operands[1])==true_regnum(operands[0]) )
4973    && ( peep2_reg_dead_p (3, operands[1]) || true_regnum(operands[3])==true_regnum(operands[1]) )"
4974   [(set (match_dup 3)
4975         (and:SI (not:SI (ashift:SI (const_int 1)
4976                                    (match_dup 2)))
4977                 (match_dup 4)))]
4978   "DROSS (\"bclr peephole2\");"
4981 ;; bmsk peephole2 optimization 
4982 (define_peephole2
4983   [(set (match_operand:SI 0 "dest_reg_operand" "")
4984        (plus:SI (match_operand:SI 1 "register_operand" "")
4985                 (const_int 1)))
4986   (set (match_operand:SI 2 "dest_reg_operand" "")
4987         (const_int 1))
4988   (set (match_operand:SI 3 "dest_reg_operand" "")
4989        (ashift:SI (match_dup 2)
4990                   (match_dup 0)))
4991   (set (match_operand:SI 4 "dest_reg_operand" "")
4992        (plus:SI (match_dup 3) 
4993                  (const_int -1) ))
4994   (set (match_operand:SI 5 "dest_reg_operand" "")
4995        (and:SI (match_operand:SI 6 "nonmemory_operand" "")
4996                (match_operand:SI 7 "nonmemory_operand" ""))) 
4997   ]
4998   "TARGET_ARCOMPACT
4999    && TARGET_DROSS
5000   && ( peep2_reg_dead_p (3, operands[0]) || true_regnum(operands[3])==true_regnum(operands[0]) )
5001   && ( peep2_reg_dead_p (3, operands[2]) || true_regnum(operands[3])==true_regnum(operands[2]) )
5002   && ( peep2_reg_dead_p (4, operands[3]) || true_regnum(operands[4])==true_regnum(operands[3]) )
5003   && ( peep2_reg_dead_p (5, operands[4]) || true_regnum(operands[5])==true_regnum(operands[4]) )
5004   && ( true_regnum(operands[6])==true_regnum(operands[4]) || true_regnum(operands[7])==true_regnum(operands[4]) )"
5005   [(set (match_dup 5)
5006         (and:SI (match_dup 6)
5007                 (plus:SI (ashift:SI (const_int 1)
5008                                     (plus:SI (match_dup 1)
5009                                              (const_int 1)))
5010                          (const_int -1))))]
5011   "DROSS (\"bmsk peephole2\");
5012    if ( true_regnum(operands[6])==true_regnum(operands[4]) )
5013       operands[6]=operands[7];
5014   "
5017 ;; Instructions generated through builtins
5019 (define_insn "norm"
5020   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5021         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5022                             UNSPEC_NORM))]
5023   "TARGET_NORM"
5024   "@
5025    norm \t%0, %1
5026    norm \t%0, %S1"
5027   [(set_attr "length" "4,8")
5028    (set_attr "type" "two_cycle_core,two_cycle_core")])
5030 (define_insn "normw"
5031   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5032         (unspec:SI [(match_operand:HI 1 "general_operand" "cL,Cal")]
5033                             UNSPEC_NORMW))]
5034   "TARGET_NORM"
5035   "@
5036    normw \t%0, %1
5037    normw \t%0, %S1"
5038   [(set_attr "length" "4,8")
5039    (set_attr "type" "two_cycle_core,two_cycle_core")])
5042 (define_insn "swap"
5043   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
5044         (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
5045                             UNSPEC_SWAP))]
5046   "TARGET_SWAP"
5047   "@
5048    swap \t%0, %1
5049    swap \t%0, %S1
5050    swap \t%0, %1"
5051   [(set_attr "length" "4,8,4")
5052    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
5054 ;; FIXME: an intrinsic for multiply is daft.  Can we remove this?
5055 (define_insn "mul64"
5056   [(unspec [(match_operand:SI 0 "general_operand" "q,r,r,%r")
5057                      (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
5058                    UNSPEC_MUL64)]
5059   "TARGET_MUL64_SET"
5060   "@
5061    mul64%? \t0, %0, %1%&
5062    mul64%? \t0, %0, %1
5063    mul64 \t0, %0, %1
5064    mul64%? \t0, %0, %S1"
5065   [(set_attr "length" "2,4,4,8")
5066   (set_attr "iscompact" "true,false,false,false")
5067   (set_attr "type" "binary,binary,binary,binary")
5068   (set_attr "cond" "canuse,canuse, nocond, canuse")])
5070 (define_insn "mulu64"
5071   [(unspec [(match_operand:SI 0 "general_operand" "%r,r,r,r")
5072                      (match_operand:SI 1 "general_operand" "rL,I,r,Cal")]
5073                    UNSPEC_MULU64)]
5074   "TARGET_MUL64_SET"
5075   "@
5076    mulu64%? \t0, %0, %1
5077    mulu64 \t0, %0, %1
5078    mulu64 \t0, %0, %1
5079    mulu64%? \t0, %0, %S1"
5080   [(set_attr "length" "4,4,4,8")
5081    (set_attr "type" "binary,binary,binary,binary")
5082    (set_attr "cond" "canuse,nocond,nocond,canuse")])
5084 (define_insn "divaw"
5085   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
5086                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
5087                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
5088                                            UNSPEC_DIVAW))]
5089   "TARGET_EA_SET && TARGET_ARCOMPACT"
5090   "@
5091    divaw \t%0, %1, %2
5092    divaw \t%0, %S1, %2
5093    divaw \t%0, %1, %S2"
5094   [(set_attr "length" "4,8,8")
5095    (set_attr "type" "divaw,divaw,divaw")])
5097 ; FIXME: The %? is of no use here, since cond is not canuse
5098 (define_insn "flag"
5099   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5100                    VUNSPEC_FLAG)]
5101   ""
5102   "@
5103     flag%? %0
5104     flag %0
5105     flag%? %S0"
5106   [(set_attr "length" "4,4,8")
5107    (set_attr "type" "misc,misc,misc")
5108    (set_attr "cond" "clob,clob,clob")])
5110 (define_insn "brk"
5111   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5112                    VUNSPEC_BRK)]
5113   ""
5114   "brk"
5115   [(set_attr "length" "4")
5116   (set_attr "type" "misc")])
5118 (define_insn "rtie"
5119   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5120                    VUNSPEC_RTIE)]
5121   ""
5122   "rtie"
5123   [(set_attr "length" "4")
5124   (set_attr "type" "misc")
5125   (set_attr "cond" "clob")])
5127 (define_insn "sync"
5128   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5129                    VUNSPEC_SYNC)]
5130   ""
5131   "sync"
5132   [(set_attr "length" "4")
5133   (set_attr "type" "misc")])
5135 (define_insn "swi"
5136   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5137                    VUNSPEC_SWI)]
5138   ""
5139   "*
5141     if(TARGET_ARC700)
5142         return \"trap0\";
5143     else
5144         return \"swi\";
5146   [(set_attr "length" "4")
5147   (set_attr "type" "misc")])
5150 (define_insn "sleep"
5151   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
5152                    VUNSPEC_SLEEP)]
5153   "(TARGET_A4 || check_if_valid_sleep_operand(operands,0))"
5154   "*
5155    if (TARGET_A4)
5156       return \"sleep\";
5157    else
5158       return \"sleep %0\";
5159   "
5160   [(set_attr "length" "4")
5161   (set_attr "type" "misc")])
5163 (define_insn "core_read"
5164   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
5165         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "HJ,!r")]
5166                             VUNSPEC_CORE_READ))]
5167   ""
5168   "*
5169     if(check_if_valid_regno_const (operands,1))
5170        return \"mov \t%0, r%1\";
5171     return \"mov \t%0, r%1\";
5172   "
5173   [(set_attr "length" "4")
5174    (set_attr "type" "unary")])
5176 (define_insn "core_write"
5177   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
5178                      (match_operand:SI 1 "general_operand" "HJ,!r")]
5179                    VUNSPEC_CORE_WRITE)]
5180   ""
5181   "*
5182     if(check_if_valid_regno_const (operands,1))
5183        return \"mov \tr%1, %0\";
5184     return \"mov \tr%1, %0\";
5185   "
5186   [(set_attr "length" "4")
5187    (set_attr "type" "unary")])
5189 (define_insn "lr"
5190   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
5191         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HJ,r,D")]
5192                             VUNSPEC_LR))]
5193   ""
5194   "lr\t%0, [%1]"
5195   [(set_attr "length" "4,8,4,8")
5196    (set_attr "type" "lr,lr,lr,lr")])
5198 (define_insn "sr"
5199   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
5200                      (match_operand:SI 1 "general_operand" "Ir,I,HJ,r")]
5201                    VUNSPEC_SR)]
5202   ""
5203   "sr\t%S0, [%1]"
5204   [(set_attr "length" "8,4,8,4")
5205    (set_attr "type" "sr,sr,sr,sr")])
5207 (define_insn "trap_s"
5208   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
5209                    VUNSPEC_TRAP_S)]
5210   "TARGET_ARC700"
5211   "*
5212     if (which_alternative == 0)
5213        return \"trap_s %0\";
5215     fatal_error (\"Operand to trap_s should be an unsigned 6-bit value.\");
5216   "
5217   [(set_attr "length" "4")
5218   (set_attr "type" "misc")])
5220 (define_insn "unimp_s"
5221   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5222                    VUNSPEC_UNIMP_S)]
5223   "TARGET_ARC700"
5224   "unimp_s"
5225   [(set_attr "length" "4")
5226   (set_attr "type" "misc")])
5228 ;; End of instructions generated through builtins
5230 ; Since the demise of REG_N_SETS, it is no longer possible to find out
5231 ; in the prologue / epilogue expanders how many times blink is set.
5232 ; Using df_regs_ever_live_p to decide if blink needs saving means that
5233 ; any explicit use of blink will cause it to be saved; hence we cannot
5234 ; represent the blink use in return / sibcall instructions themselves, and
5235 ; instead have to show it in EPILOGUE_USES and must explicitly
5236 ; forbid instructions that change blink in the return / sibcall delay slot.
5237 (define_expand "sibcall"
5238   [(parallel [(call (match_operand 0 "memory_operand" "")
5239                     (match_operand 1 "general_operand" ""))
5240               (return)
5241               (use (match_operand 2 "" ""))])]
5242   ""
5243   "
5244   {
5245     rtx callee = XEXP (operands[0], 0);
5247     if (operands[2] == NULL_RTX)
5248       operands[2] = const0_rtx;
5249     if (crtl->profile && arc_profile_call (callee))
5250       {
5251         emit_insn (gen_sibcall_prof
5252                     (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
5253                      operands[1], operands[2]));
5254         DONE;
5255       }
5256     if (GET_CODE (callee) != REG
5257         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
5258       XEXP (operands[0], 0) = force_reg (Pmode, callee);
5259   }"
5262 (define_expand "sibcall_value"
5263   [(parallel [(set (match_operand 0 "dest_reg_operand" "")
5264                    (call (match_operand 1 "memory_operand" "")
5265                          (match_operand 2 "general_operand" "")))
5266               (return)
5267               (use (match_operand 3 "" ""))])]
5268   ""
5269   "
5270   {
5271     rtx callee = XEXP (operands[1], 0);
5273     if (operands[3] == NULL_RTX)
5274       operands[3] = const0_rtx;
5275     if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
5276       {
5277         emit_insn (gen_sibcall_value_prof
5278                     (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
5279                      operands[2], operands[3]));
5280         DONE;
5281       }
5282     if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
5283       XEXP (operands[1], 0) = force_reg (Pmode, callee);
5284   }"
5287 (define_insn "*sibcall_insn"
5288  [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Rs5,Rsc,Cal"))
5289         (match_operand 1 "" ""))
5290   (return)
5291   (use (match_operand 2 "" ""))]
5292   ""
5293   "@
5294    b%!%* %P0
5295    j%!%* [%0]%&
5296    j%!%* [%0]
5297    j%! %P0"
5298   [(set_attr "type" "call,call,call,call_no_delay_slot")
5299    (set_attr "iscompact" "false,maybe,false,false")
5300    (set_attr "is_SIBCALL" "yes")]
5303 (define_insn "*sibcall_value_insn"
5304  [(set (match_operand 0 "dest_reg_operand" "")
5305        (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Rs5,Rsc,Cal"))
5306              (match_operand 2 "" "")))
5307   (return)
5308   (use (match_operand 3 "" ""))]
5309   ""
5310   "@
5311    b%!%* %P1
5312    j%!%* [%1]%&
5313    j%!%* [%1]
5314    j%! %P1"
5315   [(set_attr "type" "call,call,call,call_no_delay_slot")
5316    (set_attr "iscompact" "false,maybe,false,false")
5317    (set_attr "is_SIBCALL" "yes")]
5320 (define_insn "sibcall_prof"
5321  [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal"))
5322         (match_operand 1 "" ""))
5323   (return)
5324   (use (match_operand 2 "" ""))
5325   (use (reg:SI 8))
5326   (use (reg:SI 9))]
5327   ""
5328   "@
5329    b%!%* %P0;2
5330    j%! %^%S0;2"
5331   [(set_attr "type" "call,call_no_delay_slot")
5332    (set_attr "is_SIBCALL" "yes")]
5335 (define_insn "sibcall_value_prof"
5336  [(set (match_operand 0 "dest_reg_operand" "")
5337        (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal"))
5338              (match_operand 2 "" "")))
5339   (return)
5340   (use (match_operand 3 "" ""))
5341   (use (reg:SI 8))
5342   (use (reg:SI 9))]
5343   ""
5344   "@
5345    b%!%* %P1;1
5346    j%! %^%S1;1"
5347   [(set_attr "type" "call,call_no_delay_slot")
5348    (set_attr "is_SIBCALL" "yes")]
5351 (define_expand "prologue"
5352   [(pc)]
5353   ""
5355   arc_expand_prologue ();
5356   DONE;
5359 (define_expand "epilogue"
5360   [(pc)]
5361   ""
5363   arc_expand_epilogue (0);
5364   DONE;
5367 (define_expand "sibcall_epilogue"
5368   [(pc)]
5369   "TARGET_ARCOMPACT"
5371   arc_expand_epilogue (1);
5372   DONE;
5375 ; Since the demise of REG_N_SETS, it is no longer possible to find out
5376 ; in the prologue / epilogue expanders how many times blink is set.
5377 ; Using df_regs_ever_live_p to decide if blink needs saving means that
5378 ; any explicit use of blink will cause it to be saved; hence we cannot
5379 ; represent the blink use in return / sibcall instructions themselves, and
5380 ; instead have to show it in EPILOGUE_USES and must explicitly
5381 ; forbid instructions that change blink in the return / sibcall delay slot.
5382 (define_insn "return_i"
5383   [(return)]
5384   "reload_completed"
5386   rtx reg
5387     = gen_rtx_REG (Pmode,
5388                    arc_return_address_regs[arc_compute_function_type (cfun)]);
5390   if (TARGET_PAD_RETURN)
5391     arc_pad_return ();
5392   output_asm_insn (\"j%!%* [%0]%&\", &reg);
5393   return \"\";
5395   [(set_attr "type" "return")
5396    (set_attr "cond" "canuse")
5397    (set (attr "iscompact")
5398         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
5399                    (symbol_ref "ARC_FUNCTION_NORMAL"))
5400                (const_string "maybe")]
5401               (const_string "false")))
5402    (set (attr "length")
5403         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
5404                    (symbol_ref "ARC_FUNCTION_NORMAL"))
5405                (const_int 4)
5406                (and (ne (symbol_ref "0") (const_int 0))
5407                     (ne (minus (match_dup 0) (pc)) (const_int 0)))
5408                (const_int 4)
5409                (eq_attr "verify_short" "no")
5410                (const_int 4)]
5411               (const_int 2)))])
5413  ;; Comment in final.c (insn_current_reference_address) says
5414  ;; forward branch addresses are calculated from the next insn after branch
5415  ;; and for backward branches, it is calculated from the branch insn start.
5416  ;; The shortening logic here is tuned to accomodate this behaviour
5417 ;; ??? This should be grokked by the ccfsm machinery.
5418 (define_insn "cbranchsi4_scratch"
5419   [(set (pc)
5420         (if_then_else (match_operator 0 "proper_comparison_operator"
5421                         [(match_operand:SI 1 "register_operand" "c,c, c")
5422                          (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
5423                       (label_ref (match_operand 3 "" ""))
5424                       (pc)))
5425    (clobber (match_operand 4 "cc_register" ""))]
5426    "TARGET_ARCOMPACT
5427     && (reload_completed
5428         || (TARGET_EARLY_CBRANCHSI
5429             && brcc_nolimm_operator (operands[0], VOIDmode)))
5430     && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
5431    "*
5432      switch (get_attr_length (insn))
5433      {
5434        case 2: return \"br%d0%? %1, %2, %^%l3%&\";
5435        case 4: return \"br%d0%* %1, %B2, %^%l3\";
5436        case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
5437                  return \"br%d0%* %1, %B2, %^%l3\";
5438        case 6: case 10:
5439        case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\";
5440        default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
5441      }
5442    "
5443   [(set_attr "cond" "clob, clob, clob")
5444    (set (attr "iscompact")
5445         (cond [(eq_attr "lock_length" "2,6,10") (const_string "true")]
5446               (const_string "false")))
5447    (set (attr "type")
5448         (if_then_else
5449           (ne (symbol_ref "valid_brcc_with_delay_p (operands)") (const_int 0))
5450           (const_string "brcc")
5451           (const_string "brcc_no_delay_slot")))
5452    ; For forward branches, we need to account not only for the distance to
5453    ; the target, but also the difference between pcl and pc, the instruction
5454    ; length, and any delay insn, if present.
5455    (set
5456      (attr "lock_length")
5457      (cond ; the outer cond does a test independent of branch shortening.
5458        [(match_operand 0 "brcc_nolimm_operator" "")
5459         (cond
5460           [(and (match_operand:CC_Z 4 "cc_register")
5461                 (eq_attr "delay_slot_filled" "no")
5462                 (ge (minus (match_dup 3) (pc)) (const_int -128))
5463                 (le (minus (match_dup 3) (pc))
5464                     (minus (const_int 122)
5465                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5466            (const_int 2)
5467            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5468                 (le (minus (match_dup 3) (pc))
5469                     (minus (const_int 248)
5470                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5471            (const_int 4)
5472            (match_operand:SI 1 "compact_register_operand" "")
5473            (const_int 6)]
5474           (const_int 8))]
5475          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5476                      (le (minus (match_dup 3) (pc)) (const_int 244)))
5477                 (const_int 8)
5478                 (match_operand:SI 1 "compact_register_operand" "")
5479                 (const_int 10)]
5480                (const_int 12))))
5481    (set
5482      (attr "length")
5483      (cond ; the outer cond does a test independent of branch shortening.
5484        [(match_operand 0 "brcc_nolimm_operator" "")
5485         (cond
5486           [(and (match_operand:CC_Z 4 "cc_register")
5487                 (eq_attr "delay_slot_filled" "no")
5488                 (ge (minus (match_dup 3) (pc)) (const_int -128))
5489                 (le (minus (match_dup 3) (pc))
5490                     (minus (const_int 122)
5491                            (symbol_ref "get_attr_delay_slot_length (insn)")))
5492                 (eq_attr "verify_short" "yes"))
5493            (const_int 2)
5494            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5495                 (le (minus (match_dup 3) (pc))
5496                     (minus (const_int 248)
5497                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5498            (const_int 4)
5499            (and (match_operand:SI 1 "compact_register_operand" "")
5500                 (eq_attr "verify_short" "yes"))
5501            (const_int 6)]
5502           (const_int 8))]
5503          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5504                      (le (minus (match_dup 3) (pc)) (const_int 244)))
5505                 (const_int 8)
5506                 (and (match_operand:SI 1 "compact_register_operand" "")
5507                      (eq_attr "verify_short" "yes"))
5508                 (const_int 10)]
5509                (const_int 12))))])
5511 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5512 (define_insn "*bbit"
5513   [(set (pc)
5514         (if_then_else
5515           (match_operator 3 "equality_comparison_operator"
5516             [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5517                               (const_int 1)
5518                               (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5519              (const_int 0)])
5520              (label_ref (match_operand 0 "" ""))
5521              (pc)))
5522    (clobber (reg:CC_ZN CC_REG))]
5523   "!find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
5525   switch (get_attr_length (insn))
5526     {
5527       case 4: return (GET_CODE (operands[3]) == EQ
5528                       ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5529       case 6:
5530       case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5531       default: gcc_unreachable ();
5532     }
5534   [(set_attr "type" "brcc")
5535    (set_attr "cond" "clob")
5536    (set (attr "lock_length")
5537         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5538                     (le (minus (match_dup 0) (pc))
5539                     (minus (const_int 248)
5540                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5541                (const_int 4)
5542                (eq (symbol_ref "which_alternative") (const_int 0))
5543                (const_int 6)]
5544               (const_int 8)))
5545    (set (attr "length")
5546         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5547                     (le (minus (match_dup 0) (pc))
5548                     (minus (const_int 248)
5549                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5550                (const_int 4)
5551                (and (eq (symbol_ref "which_alternative") (const_int 0))
5552                     (eq_attr "verify_short" "yes"))
5553                (const_int 6)]
5554               (const_int 8)))
5555    (set (attr "iscompact")
5556         (if_then_else (eq_attr "lock_length" "6")
5557                       (const_string "true") (const_string "false")))])
5559 ; operand 0 is the loop count pseudo register
5560 ; operand 1 is the number of loop iterations or 0 if it is unknown
5561 ; operand 2 is the maximum number of loop iterations
5562 ; operand 3 is the number of levels of enclosed loops
5563 ; operand 4 is the loop end pattern
5564 (define_expand "doloop_begin"
5565   [(use (match_operand 0 "register_operand" ""))
5566    (use (match_operand:QI 1 "const_int_operand" ""))
5567    (use (match_operand:QI 2 "const_int_operand" ""))
5568    (use (match_operand:QI 3 "const_int_operand" ""))
5569    (use (match_operand 4 "" ""))]
5570   ""
5572   if (INTVAL (operands[3]) > 1)
5573     FAIL;
5574   emit_insn (gen_doloop_begin_i (operands[0], const0_rtx,
5575                                  GEN_INT (INSN_UID (operands[4])),
5576                                  const0_rtx, const0_rtx));
5577   DONE;
5580 ; ??? can't describe the insn properly as then the optimizers try to
5581 ; hoist the SETs.
5582 ;(define_insn "doloop_begin_i"
5583 ;  [(set (reg:SI LP_START) (pc))
5584 ;   (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_LP))
5585 ;   (use (match_operand 0 "const_int_operand" "n"))]
5586 ;  ""
5587 ;  "lp .L__GCC__LP%0"
5590 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
5591 ; instruction that was not at the start of the loop.
5592 ; There is no point is reloading this insn - then lp_count would still not
5593 ; be available for the loop end.
5594 (define_insn "doloop_begin_i"
5595   [(unspec:SI [(pc)] UNSPEC_LP)
5596    (clobber (reg:SI LP_START))
5597    (clobber (reg:SI LP_END))
5598    (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
5599    (use (match_operand 1 "const_int_operand" "n,n,C_0"))
5600    (use (match_operand 2 "const_int_operand" "n,n,X"))
5601    (use (match_operand 3 "const_int_operand" "C_0,n,X"))
5602    (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
5603   ""
5605   rtx scan;
5606   int len, size = 0;
5607   int n_insns = 0;
5608   rtx loop_start = operands[4];
5610   if (CONST_INT_P (loop_start))
5611     loop_start = NULL_RTX;
5612   /* Size implications of the alignment will be taken care off by the
5613      alignemnt inserted at the loop start.  */
5614   if (LOOP_ALIGN (0) && INTVAL (operands[1]))
5615     asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5616   if (!INTVAL (operands[1]))
5617     return "; LITTLE LOST LOOP";
5618   if (loop_start && flag_pic)
5619     /* ??? Can do better for when a scratch register
5620        is known.  But that would require extra testing.  */
5621     return ".p2align 2\;push_s r0\;add r0,pcl,%4-.+2\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-.+2\;sr r0,[3]; LP_END\;pop_s r0";
5622   /* Check if the loop end is in range to be set by the lp instruction.  */
5623   size = INTVAL (operands[3]) < 2 ? 0 : 2048;
5624   for (size = 0, scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
5625     {
5626       if (!INSN_P (scan))
5627         continue;
5628       if (recog_memoized (scan) == CODE_FOR_doloop_end_i
5629           && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
5630               == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
5631         break;
5632       len = get_attr_length (scan);
5633       size += len;
5634     }
5635   /* Try to verify that there are at least three instruction fetches
5636      between the loop setup and the first encounter of the loop end.  */
5637   for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
5638     {
5639       if (!INSN_P (scan))
5640         continue;
5641       if (GET_CODE (PATTERN (scan)) == SEQUENCE)
5642         scan = XVECEXP (PATTERN (scan), 0, 0);
5643       if (JUMP_P (scan))
5644         {
5645           if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
5646             {
5647               n_insns += 2;
5648               if (simplejump_p (scan))
5649                 {
5650                   insn = XEXP (SET_SRC (PATTERN (scan)), 0);
5651                   continue;
5652                 }
5653               if (JUMP_LABEL (scan)
5654                   && (!next_active_insn (JUMP_LABEL (scan))
5655                       || (recog_memoized (next_active_insn (JUMP_LABEL (scan)))
5656                           != CODE_FOR_doloop_begin_i))
5657                   && (!next_active_insn (NEXT_INSN (PREV_INSN (scan)))
5658                       || (recog_memoized
5659                            (next_active_insn (NEXT_INSN (PREV_INSN (scan))))
5660                           != CODE_FOR_doloop_begin_i)))
5661                 n_insns++;
5662             }
5663           break;
5664         }
5665       len = get_attr_length (scan);
5666       /* Size estimation of asms assumes that each line which is nonempty
5667          codes an insn, and that each has a long immediate.  For minimum insn
5668          count, assume merely that a nonempty asm has at least one insn.  */
5669       if (GET_CODE (PATTERN (scan)) == ASM_INPUT
5670           || asm_noperands (PATTERN (scan)) >= 0)
5671         n_insns += (len != 0);
5672       else
5673         n_insns += (len > 4 ? 2 : (len ? 1 : 0));
5674     }
5675   if (LOOP_ALIGN (0))
5676     asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5677   gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
5678   if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
5679     {
5680       if (flag_pic)
5681         /* ??? Can do better for when a scratch register
5682            is known.  But that would require extra testing.  */
5683         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";
5684       output_asm_insn ((size < 2048
5685                         ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
5686                        operands);
5687       output_asm_insn (loop_start
5688                        ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
5689                        operands);
5690       if (TARGET_ARC600 && n_insns < 1)
5691         output_asm_insn ("nop", operands);
5692       return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
5693     }
5694   else if (TARGET_ARC600 && n_insns < 3)
5695     {
5696       /* At least four instructions are needed between the setting of LP_COUNT
5697          and the loop end - but the lp instruction qualifies as one.  */
5698       rtx prev = prev_nonnote_insn (insn);
5700       if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
5701         output_asm_insn ("nop", operands);
5702     }
5703   return "lp .L__GCC__LP%1";
5705   [(set_attr "type" "loop_setup")
5706    (set_attr_alternative "length"
5707      [(if_then_else (ne (symbol_ref "TARGET_ARC600") (const_int 0))
5708                     (const_int 16) (const_int 4))
5709       (if_then_else (ne (symbol_ref "flag_pic") (const_int 0))
5710                     (const_int 28) (const_int 16))
5711       (const_int 0)])]
5712   ;; ??? strictly speaking, we should branch shorten this insn, but then
5713   ;; we'd need a proper label first.  We could say it is always 24 bytes in
5714   ;; length, but that would be very pessimistic; also, when the loop insn
5715   ;; goes out of range, it is very likely that the same insns that have
5716   ;; done so will already have made all other small offset branches go out
5717   ;; of range, making the need for exact length information here mostly
5718   ;; academic.
5721 ; operand 0 is the loop count pseudo register
5722 ; operand 1 is the number of loop iterations or 0 if it is unknown
5723 ; operand 2 is the maximum number of loop iterations
5724 ; operand 3 is the number of levels of enclosed loops
5725 ; operand 4 is the label to jump to at the top of the loop
5726 ; operand 5 is nonzero if the loop is entered at its top.
5727 ; Use this for the ARC600 and ARC700.  For ARCtangent-A5, this is unsafe
5728 ; without further checking for nearby branches etc., and without proper
5729 ; annotation of shift patterns that clobber lp_count
5730 ; ??? ARC600 might want to check if the loop has few iteration and only a
5731 ; single insn - loop setup is expensive then.
5732 (define_expand "doloop_end"
5733   [(use (match_operand 0 "register_operand" ""))
5734    (use (match_operand:QI 1 "const_int_operand" ""))
5735    (use (match_operand:QI 2 "const_int_operand" ""))
5736    (use (match_operand:QI 3 "const_int_operand" ""))
5737    (use (label_ref (match_operand 4 "" "")))
5738    (use (match_operand:QI 5 "const_int_operand" ""))]
5739   "(TARGET_ARC600 || TARGET_ARC700) && arc_experimental_mask & 1"
5741   if (INTVAL (operands[3]) > 1)
5742     FAIL;
5743   /* Setting up the loop with two sr isntructions costs 6 cycles.  */
5744   if (TARGET_ARC700 && !INTVAL (operands[5])
5745       && INTVAL (operands[1]) && INTVAL (operands[1]) <= (flag_pic ? 6 : 3))
5746     FAIL;
5747   /* We could do smaller bivs with biv widening, and wider bivs by having
5748      a high-word counter in an outer loop - but punt on this for now.  */
5749   if (GET_MODE (operands[0]) != SImode)
5750     FAIL;
5751   emit_jump_insn (gen_doloop_end_i (operands[0], operands[4], const0_rtx));
5752   DONE;
5755 (define_insn_and_split "doloop_end_i"
5756   [(set (pc)
5757         (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
5758                            (const_int 1))
5759                       (label_ref (match_operand 1 "" ""))
5760                       (pc)))
5761    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5762    (use (reg:SI LP_START))
5763    (use (reg:SI LP_END))
5764    (use (match_operand 2 "const_int_operand" "n,???C_0,???X"))
5765    (clobber (match_scratch:SI 3 "=X,X,&????r"))]
5766   ""
5767   "*
5769   rtx prev = prev_nonnote_insn (insn);
5771   /* If there is an immediately preceding label, we must output a nop,
5772      lest a branch to that label will fall out of the loop.
5773      ??? We could try to avoid this by claiming to have a delay slot if there
5774      is a preceding label, and outputting the delay slot insn instead, if
5775      present.
5776      Or we could have some optimization that changes the source edge to update
5777      the loop count and jump to the loop start instead.  */
5778   /* For ARC600, we must also prevent jumps inside the loop and jumps where
5779      the loop counter value is live at the target from being directly at the
5780      loop end.  Being sure that the loop counter is dead at the target is
5781      too much hair - we can't rely on data flow information at this point -
5782      so insert a nop for all branches.
5783      The ARC600 also can't read the loop counter in the last insn of a loop.  */
5784   if (LABEL_P (prev))
5785     output_asm_insn (\"nop%?\", operands);
5786   return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
5788   "&& memory_operand (operands[0], SImode)"
5789   [(pc)]
5791   emit_move_insn (operands[3], operands[0]);
5792   emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
5793   DONE;
5795   [(set_attr "type" "loop_end")
5796    (set (attr "length")
5797         (if_then_else (ne (symbol_ref "LABEL_P (prev_nonnote_insn (insn))")
5798                           (const_int 0))
5799                       (const_int 4) (const_int 0)))]
5802 ; This pattern is generated by arc_reorg when there is no recognizable
5803 ; loop start.
5804 (define_insn "*doloop_fallback"
5805   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
5806                                 (const_int 1))
5807                            (label_ref (match_operand 1 "" ""))
5808                            (pc)))
5809    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
5810    ; avoid fooling the loop optimizer into assuming this is a special insn.
5811   "reload_completed"
5812   "*return get_attr_length (insn) == 8
5813    ? \"brne.d %0,1,%1\;sub %0,%0,1\"
5814    : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
5815   [(set (attr "length")
5816         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256)) 
5817                            (le (minus (match_dup 1) (pc)) (const_int 244)))
5818                       (const_int 8) (const_int 12)))
5819    (set_attr "type" "brcc_no_delay_slot")
5820    (set_attr "cond" "nocond")]
5823 ; reload can't make output reloads for jump insns, so we have to do this by hand.
5824 (define_insn "doloop_fallback_m"
5825   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
5826                                 (const_int 1))
5827                            (label_ref (match_operand 1 "" ""))
5828                            (pc)))
5829    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5830    (set (match_operand:SI 2 "memory_operand" "=m")
5831         (plus:SI (match_dup 0) (const_int -1)))]
5832    ; avoid fooling the loop optimizer into assuming this is a special insn.
5833   "reload_completed"
5834   "*return get_attr_length (insn) == 12
5835    ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5836    : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5837   [(set (attr "length")
5838         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252)) 
5839                            (le (minus (match_dup 1) (pc)) (const_int 244)))
5840                       (const_int 12) (const_int 16)))
5841    (set_attr "type" "brcc_no_delay_slot")
5842    (set_attr "cond" "nocond")]
5845 (define_expand "movmemsi"
5846   [(match_operand:BLK 0 "" "")
5847    (match_operand:BLK 1 "" "")
5848    (match_operand:SI 2 "nonmemory_operand" "")
5849    (match_operand 3 "immediate_operand" "")]
5850   ""
5851   "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5853 ;; See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 why we can't
5854 ;; get rid of this bogosity.
5855 (define_expand "cmpsf"
5856   [(set (reg:CC 61)
5857         (compare:CC (match_operand:SF 0 "general_operand" "")
5858                     (match_operand:SF 1 "general_operand" "")))]
5859   "TARGET_OPTFPE"
5860   "
5862   arc_compare_op0 = operands[0];
5863   arc_compare_op1 = operands[1];
5864   DONE;
5867 (define_expand "cmpdf"
5868   [(set (reg:CC 61)
5869         (compare:CC (match_operand:DF 0 "general_operand" "")
5870                     (match_operand:DF 1 "general_operand" "")))]
5871   "TARGET_OPTFPE && !TARGET_DPFP"
5872   "
5874   arc_compare_op0 = operands[0];
5875   arc_compare_op1 = operands[1];
5876   DONE;
5879 (define_expand "cmp_float"
5880   [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5881               (clobber (reg:SI 31))
5882               (clobber (reg:SI 12))])]
5883   ""
5884   "")
5886 (define_insn "*cmpsf_eq"
5887   [(set (reg:CC_Z 61) (compare:CC_Z (reg:SF 0) (reg:SF 1)))
5888    (clobber (reg:SI 31))
5889    (clobber (reg:SI 12))]
5890   "TARGET_OPTFPE && !TARGET_SPFP"
5891   "*return arc_output_libcall (\"__eqsf2\");"
5892   [(set_attr "is_sfunc" "yes")]
5894               
5895 (define_insn "*cmpdf_eq"
5896   [(set (reg:CC_Z 61) (compare:CC_Z (reg:DF 0) (reg:DF 2)))
5897    (clobber (reg:SI 31))
5898    (clobber (reg:SI 12))]
5899   "TARGET_OPTFPE && !TARGET_DPFP"
5900   "*return arc_output_libcall (\"__eqdf2\");"
5901   [(set_attr "is_sfunc" "yes")]
5903               
5904 (define_insn "*cmpsf_gt"
5905   [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:SF 0) (reg:SF 1)))
5906    (clobber (reg:SI 31))
5907    (clobber (reg:SI 12))]
5908   "TARGET_OPTFPE && !TARGET_SPFP"
5909   "*return arc_output_libcall (\"__gtsf2\");"
5910   [(set_attr "is_sfunc" "yes")]
5912               
5913 (define_insn "*cmpdf_gt"
5914   [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:DF 0) (reg:DF 2)))
5915    (clobber (reg:SI 31))
5916    (clobber (reg:SI 12))]
5917   "TARGET_OPTFPE && !TARGET_DPFP"
5918   "*return arc_output_libcall (\"__gtdf2\");"
5919   [(set_attr "is_sfunc" "yes")]
5921               
5922 (define_insn "*cmpsf_ge"
5923   [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:SF 0) (reg:SF 1)))
5924    (clobber (reg:SI 31))
5925    (clobber (reg:SI 12))]
5926   "TARGET_OPTFPE && !TARGET_SPFP"
5927   "*return arc_output_libcall (\"__gesf2\");"
5928   [(set_attr "is_sfunc" "yes")]
5930               
5931 (define_insn "*cmpdf_ge"
5932   [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:DF 0) (reg:DF 2)))
5933    (clobber (reg:SI 31))
5934    (clobber (reg:SI 12))]
5935   "TARGET_OPTFPE && !TARGET_DPFP"
5936   "*return arc_output_libcall (\"__gedf2\");"
5937   [(set_attr "is_sfunc" "yes")]
5939               
5940 (define_insn "*cmpsf_uneq"
5941   [(set (reg:CC_FP_UNEQ 61) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
5942    (clobber (reg:SI 31))
5943    (clobber (reg:SI 12))]
5944   "TARGET_OPTFPE && !TARGET_SPFP"
5945   "*return arc_output_libcall (\"__uneqsf2\");"
5946   [(set_attr "is_sfunc" "yes")]
5948               
5949 (define_insn "*cmpdf_uneq"
5950   [(set (reg:CC_FP_UNEQ 61) (compare:CC_FP_UNEQ (reg:DF 0) (reg:DF 2)))
5951    (clobber (reg:SI 31))
5952    (clobber (reg:SI 12))]
5953   "TARGET_OPTFPE && !TARGET_DPFP"
5954   "*return arc_output_libcall (\"__uneqdf2\");"
5955   [(set_attr "is_sfunc" "yes")]
5957               
5958 (define_insn "*cmpsf_ord"
5959   [(set (reg:CC_FP_ORD 61) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
5960    (clobber (reg:SI 31))
5961    (clobber (reg:SI 12))]
5962   "TARGET_OPTFPE && !TARGET_SPFP"
5963   "*return arc_output_libcall (\"__ordsf2\");"
5964   [(set_attr "is_sfunc" "yes")]
5966               
5967 ;; N.B. double precision fpx sets bit 31 for NaNs.  We need bit 51 set
5968 ;; for the floating point emulation to recognize the NaN.
5969 (define_insn "*cmpdf_ord"
5970   [(set (reg:CC_FP_ORD 61) (compare:CC_FP_ORD (reg:DF 0) (reg:DF 2)))
5971    (clobber (reg:SI 31))
5972    (clobber (reg:SI 12))]
5973   "TARGET_OPTFPE && !TARGET_DPFP"
5974   "*return arc_output_libcall (\"__orddf2\");"
5975   [(set_attr "is_sfunc" "yes")]
5978 (define_insn "abssf2"
5979   [(set (match_operand:SF 0 "dest_reg_operand"    "=Rcq#q,Rcw,w")
5980         (abs:SF (match_operand:SF 1 "register_operand" "0,  0,c")))]
5981   ""
5982   "bclr%? %0,%1,31%&"
5983   [(set_attr "type" "unary")
5984    (set_attr "iscompact" "maybe,false,false")
5985    (set_attr "length" "2,4,4")
5986    (set_attr "cond" "canuse,canuse,nocond")])
5987               
5988 (define_insn "negsf2"
5989   [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5990         (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5991   ""
5992   "bxor%? %0,%1,31"
5993   [(set_attr "type" "unary")
5994    (set_attr "cond" "canuse,nocond")])
5996 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5997 (define_insn "*millicode_thunk_st"
5998   [(match_parallel 0 "millicode_store_operation"
5999      [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
6000   ""
6002   output_asm_insn ("bl%* __st_r13_to_%0",
6003                    &SET_SRC (XVECEXP (operands[0], 0,
6004                                       XVECLEN (operands[0], 0) - 2)));
6005   return "";
6007   [(set_attr "type" "call")])
6008               
6009 (define_insn "*millicode_thunk_ld"
6010   [(match_parallel 0 "millicode_load_clob_operation"
6011      [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
6012   ""
6014   output_asm_insn ("bl%* __ld_r13_to_%0",
6015                    &SET_DEST (XVECEXP (operands[0], 0,
6016                                        XVECLEN (operands[0], 0) - 2)));
6017   return "";
6019   [(set_attr "type" "call")])
6021 (define_insn "*millicode_sibthunk_ld"
6022   [(match_parallel 0 "millicode_load_operation"
6023      [(return)
6024       (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
6025       (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
6026   ""
6028   output_asm_insn ("b%* __ld_r13_to_%0_ret",
6029                    &SET_DEST (XVECEXP (operands[0], 0,
6030                                        XVECLEN (operands[0], 0) - 1)));
6031   return "";
6033   [(set_attr "type" "call")
6034    (set_attr "is_SIBCALL" "yes")])
6035               
6036 ;; If hardware floating point is available, don't define a negdf pattern;
6037 ;; it would be something like:
6038 ;;(define_insn "negdf2"
6039 ;;  [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
6040 ;;      (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
6041 ;;   (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
6042 ;;  ""
6043 ;;  "@
6044 ;;   bxor%? %H0,%H1,31
6045 ;;   bxor %H0,%H1,31 ` mov %L0,%L1
6046 ;;   drsubh%F0%F1 0,0,0
6047 ;;   drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
6048 ;;  [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
6049 ;;   (set_attr "iscompact" "false,false,false,false")
6050 ;;   (set_attr "length" "4,4,8,12")
6051 ;;   (set_attr "cond" "canuse,nocond,nocond,nocond")])
6052 ;; and this suffers from always requiring a long immediate when using
6053 ;; the floating point hardware.
6054 ;; We then want the sub[sd]f patterns to be used, so that we can load the
6055 ;; constant zero efficiently into a register when we want to do the
6056 ;; computation using the floating point hardware.  There should be a special
6057 ;; subdf alternative that matches a zero operand 1, which then can allow
6058 ;; to use bxor to flip the high bit of an integer register.
6059 ;; ??? we actually can't use the floating point hardware for neg, because
6060 ;; this would not work right for -0.  OTOH optabs.c has already code
6061 ;; to synthesyze nagate by flipping the sign bit.
6063               
6064 ;; include the arc-FPX instructions
6065 (include "fpx.md")
6067 (include "simdext.md")