]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arc/arc.md
[ARC] Various instruction pattern fixes
[thirdparty/gcc.git] / gcc / config / arc / arc.md
1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2016 Free Software Foundation, Inc.
3
4 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 ;; behalf of Synopsys Inc.
6
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)
11 ;;
12 ;; Profiling support and performance improvements by
13 ;; Joern Rennecke (joern.rennecke@embecosm.com)
14 ;;
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)
19
20 ;; This file is part of GCC.
21
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.
26
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.
31
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/>.
35
36 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
37
38 ;; <op> dest, src Two operand instruction's syntax
39 ;; <op> dest, src1, src2 Three operand instruction's syntax
40
41 ;; ARC and ARCompact PREDICATES:
42 ;;
43 ;; comparison_operator LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE
44 ;; memory_operand memory [m]
45 ;; immediate_operand immediate constant [IKLMNOP]
46 ;; register_operand register [rq]
47 ;; general_operand register, memory, constant [rqmIKLMNOP]
48
49 ;; Note that the predicates are only used when selecting a pattern
50 ;; to determine if an operand is valid.
51
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.
55
56 ;; ARC and ARCompact CONSTRAINTS:
57 ;;
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
68 ;;
69 ;; H fp 16-bit constant
70 ;; I signed 12-bit immediate (for ARCompact)
71 ;; K unsigned 3-bit immediate (for ARCompact)
72 ;; L unsigned 6-bit immediate (for ARCompact)
73 ;; M unsinged 5-bit immediate (for ARCompact)
74 ;; O unsinged 7-bit immediate (for ARCompact)
75 ;; P unsinged 8-bit immediate (for ARCompact)
76 ;; N constant '1' (for ARCompact)
77
78
79 ;; TODO:
80 ;; -> prefetch instruction
81
82 ;; -----------------------------------------------------------------------------
83
84 ;; Include DFA scheduluers
85 (include ("arc600.md"))
86 (include ("arc700.md"))
87 (include ("arcEM.md"))
88 (include ("arcHS.md"))
89
90 ;; Predicates
91
92 (include ("predicates.md"))
93 (include ("constraints.md"))
94 ;; -----------------------------------------------------------------------------
95
96 ;; UNSPEC Usage:
97 ;; ~~~~~~~~~~~~
98 ;; -----------------------------------------------------------------------------
99 ;; Symbolic name Value Desc.
100 ;; -----------------------------------------------------------------------------
101 ;; UNSPEC_PLT 3 symbol to be referenced through the PLT
102 ;; UNSPEC_GOT 4 symbol to be rerenced through the GOT
103 ;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the
104 ;; GOTBASE.(Referenced as @GOTOFF)
105 ;; ----------------------------------------------------------------------------
106
107 (define_c_enum "unspec" [
108 DUMMY_0
109 DUMMY_1
110 DUMMY_2
111 ARC_UNSPEC_PLT
112 ARC_UNSPEC_GOT
113 ARC_UNSPEC_GOTOFF
114 UNSPEC_TLS_GD
115 UNSPEC_TLS_LD
116 UNSPEC_TLS_IE
117 UNSPEC_TLS_OFF
118 UNSPEC_ARC_NORM
119 UNSPEC_ARC_NORMW
120 UNSPEC_ARC_SWAP
121 UNSPEC_ARC_DIVAW
122 UNSPEC_ARC_DIRECT
123 UNSPEC_ARC_LP
124 UNSPEC_ARC_CASESI
125 UNSPEC_ARC_FFS
126 UNSPEC_ARC_FLS
127 UNSPEC_ARC_MEMBAR
128 UNSPEC_ARC_DMACH
129 UNSPEC_ARC_DMACHU
130 UNSPEC_ARC_DMACWH
131 UNSPEC_ARC_DMACWHU
132 UNSPEC_ARC_QMACH
133 UNSPEC_ARC_QMACHU
134 UNSPEC_ARC_QMPYH
135 UNSPEC_ARC_QMPYHU
136 UNSPEC_ARC_VMAC2H
137 UNSPEC_ARC_VMAC2HU
138 UNSPEC_ARC_VMPY2H
139 UNSPEC_ARC_VMPY2HU
140 ])
141
142 (define_c_enum "vunspec" [
143 VUNSPEC_ARC_RTIE
144 VUNSPEC_ARC_SYNC
145 VUNSPEC_ARC_BRK
146 VUNSPEC_ARC_FLAG
147 VUNSPEC_ARC_SLEEP
148 VUNSPEC_ARC_SWI
149 VUNSPEC_ARC_CORE_READ
150 VUNSPEC_ARC_CORE_WRITE
151 VUNSPEC_ARC_LR
152 VUNSPEC_ARC_SR
153 VUNSPEC_ARC_TRAP_S
154 VUNSPEC_ARC_UNIMP_S
155 VUNSPEC_ARC_KFLAG
156 VUNSPEC_ARC_CLRI
157 VUNSPEC_ARC_SETI
158 VUNSPEC_ARC_NOP
159 VUNSPEC_ARC_STACK_IRQ
160 VUNSPEC_ARC_DEXCL
161 VUNSPEC_ARC_DEXCL_NORES
162 VUNSPEC_ARC_LR_HIGH
163 VUNSPEC_ARC_EX
164 VUNSPEC_ARC_CAS
165 VUNSPEC_ARC_SC
166 VUNSPEC_ARC_LL
167 ])
168
169 (define_constants
170 [(UNSPEC_PROF 18) ; profile callgraph counter
171
172 (R0_REG 0)
173 (R1_REG 1)
174 (R2_REG 2)
175 (R3_REG 3)
176 (R10_REG 10)
177 (R12_REG 12)
178 (SP_REG 28)
179 (ILINK1_REGNUM 29)
180 (ILINK2_REGNUM 30)
181 (RETURN_ADDR_REGNUM 31)
182 (MUL64_OUT_REG 58)
183 (ARCV2_ACC 58)
184
185 (LP_COUNT 60)
186 (CC_REG 61)
187 (LP_START 144)
188 (LP_END 145)
189 ]
190 )
191
192 (define_attr "is_sfunc" "no,yes" (const_string "no"))
193
194 ;; Insn type. Used to default other attribute values.
195 ; While the attribute is_sfunc is set for any call of a special function,
196 ; the instruction type sfunc is used only for the special call sequence
197 ; that loads the (pc-relative) function address into r12 and then calls
198 ; via r12.
199
200 (define_attr "type"
201 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
202 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
203 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
204 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
205 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
206 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
207 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
208 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
209 simd_valign, simd_valign_with_acc, simd_vcontrol,
210 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
211 fpu"
212 (cond [(eq_attr "is_sfunc" "yes")
213 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
214 (match_test "flag_pic") (const_string "sfunc")]
215 (const_string "call_no_delay_slot"))]
216 (const_string "binary")))
217
218 ;; The following three attributes are mixed case so that they can be
219 ;; used conveniently with the CALL_ATTR macro.
220 (define_attr "is_CALL" "no,yes"
221 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
222 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
223 (const_string "no")))
224
225 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
226
227 (define_attr "is_NON_SIBCALL" "no,yes"
228 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
229 (eq_attr "is_CALL" "yes") (const_string "yes")]
230 (const_string "no")))
231
232
233 ;; Attribute describing the processor
234 (define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
235 (const (symbol_ref "arc_cpu_attr")))
236
237 ;; true for compact instructions (those with _s suffix)
238 ;; "maybe" means compact unless we conditionalize the insn.
239 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
240 (cond [(eq_attr "type" "sfunc")
241 (const_string "maybe")]
242 (const_string "false")))
243
244
245 ; Is there an instruction that we are actually putting into the delay slot?
246 (define_attr "delay_slot_filled" "no,yes"
247 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
248 (const_string "no")
249 (match_test "!TARGET_AT_DBR_CONDEXEC
250 && JUMP_P (insn)
251 && INSN_ANNULLED_BRANCH_P (insn)
252 && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
253 (const_string "no")]
254 (const_string "yes")))
255
256 ; Is a delay slot present for purposes of shorten_branches?
257 ; We have to take the length of this insn into account for forward branches
258 ; even if we don't put the insn actually into a delay slot.
259 (define_attr "delay_slot_present" "no,yes"
260 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
261 (const_string "no")]
262 (const_string "yes")))
263
264 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
265 ; length of a different insn with the same uid.
266 (define_attr "delay_slot_length" ""
267 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
268 (const_int 0)]
269 (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
270 - get_attr_length (insn)")))
271
272 ; for ARCv2 we need to disable/enable different instruction alternatives
273 (define_attr "cpu_facility" "std,av1,av2,fpx"
274 (const_string "std"))
275
276 ; We should consider all the instructions enabled until otherwise
277 (define_attr "enabled" "no,yes"
278 (cond [(and (eq_attr "cpu_facility" "av1")
279 (match_test "TARGET_V2"))
280 (const_string "no")
281
282 (and (eq_attr "cpu_facility" "av2")
283 (not (match_test "TARGET_V2")))
284 (const_string "no")
285
286 (and (eq_attr "cpu_facility" "fpx")
287 (match_test "TARGET_FP_DP_AX"))
288 (const_string "no")
289 ]
290 (const_string "yes")))
291
292 (define_attr "predicable" "no,yes" (const_string "no"))
293 ;; if 'predicable' were not so brain-dead, we would specify:
294 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
295 ;; (eq_attr "iscompact" "maybe") (const_string "no")]
296 ;; (const_string "yes"))
297 ;; and then for everything but calls, we could just set the cond attribute.
298
299 ;; Condition codes: this one is used by final_prescan_insn to speed up
300 ;; conditionalizing instructions. It saves having to scan the rtl to see if
301 ;; it uses or alters the condition codes.
302
303 ;; USE: This insn uses the condition codes (eg: a conditional branch).
304 ;; CANUSE: This insn can use the condition codes (for conditional execution).
305 ;; SET: All condition codes are set by this insn.
306 ;; SET_ZN: the Z and N flags are set by this insn.
307 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
308 ;; CLOB: The condition codes are set to unknown values by this insn.
309 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
310
311 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
312 (cond
313 [(and (eq_attr "predicable" "yes")
314 (eq_attr "is_sfunc" "no")
315 (eq_attr "delay_slot_filled" "no"))
316 (const_string "canuse")
317
318 (eq_attr "type" "call")
319 (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
320 (match_test "!flag_pic") (const_string "canuse_limm")]
321 (const_string "nocond"))
322
323 (eq_attr "iscompact" "maybe,false")
324 (cond [ (and (eq_attr "type" "move")
325 (match_operand 1 "immediate_operand" ""))
326 (if_then_else
327 (ior (match_operand 1 "u6_immediate_operand" "")
328 (match_operand 1 "long_immediate_operand" ""))
329 (const_string "canuse")
330 (const_string "canuse_limm"))
331
332 (eq_attr "type" "binary")
333 (cond [(ne (symbol_ref "REGNO (operands[0])")
334 (symbol_ref "REGNO (operands[1])"))
335 (const_string "nocond")
336 (match_operand 2 "register_operand" "")
337 (const_string "canuse")
338 (match_operand 2 "u6_immediate_operand" "")
339 (const_string "canuse")
340 (match_operand 2 "long_immediate_operand" "")
341 (const_string "canuse")
342 (match_operand 2 "const_int_operand" "")
343 (const_string "canuse_limm")]
344 (const_string "nocond"))
345
346 (eq_attr "type" "compare")
347 (const_string "set")
348
349 (eq_attr "type" "cmove,branch")
350 (const_string "use")
351
352 (eq_attr "is_sfunc" "yes")
353 (cond [(match_test "(TARGET_MEDIUM_CALLS
354 && !TARGET_LONG_CALLS_SET
355 && flag_pic)")
356 (const_string "canuse_limm_add")
357 (match_test "(TARGET_MEDIUM_CALLS
358 && !TARGET_LONG_CALLS_SET)")
359 (const_string "canuse_limm")]
360 (const_string "canuse"))
361
362 ]
363
364 (const_string "nocond"))]
365
366 (cond [(eq_attr "type" "compare")
367 (const_string "set")
368
369 (eq_attr "type" "cmove,branch")
370 (const_string "use")
371
372 ]
373
374 (const_string "nocond"))))
375
376 /* ??? Having all these patterns gives ifcvt more freedom to generate
377 inefficient code. It seem to operate on the premise that
378 register-register copies and registers are free. I see better code
379 with -fno-if-convert now than without. */
380 (define_cond_exec
381 [(match_operator 0 "proper_comparison_operator"
382 [(reg CC_REG) (const_int 0)])]
383 "true"
384 "")
385
386 ;; Length (in # of bytes, long immediate constants counted too).
387 ;; ??? There's a nasty interaction between the conditional execution fsm
388 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
389 (define_attr "length" ""
390 (cond
391 [(eq_attr "iscompact" "true,maybe")
392 (cond
393 [(eq_attr "type" "sfunc")
394 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
395 (const_int 12)]
396 (const_int 10))
397 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)]
398 (const_int 2))
399
400 (eq_attr "iscompact" "true_limm")
401 (const_int 6)
402
403 (eq_attr "iscompact" "maybe_limm")
404 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
405 (const_int 6))
406
407 (eq_attr "type" "load")
408 (if_then_else
409 (match_operand 1 "long_immediate_loadstore_operand" "")
410 (const_int 8) (const_int 4))
411
412 (eq_attr "type" "store")
413 (if_then_else
414 (ior (match_operand 0 "long_immediate_loadstore_operand" "")
415 (match_operand 1 "immediate_operand" ""))
416 (const_int 8) (const_int 4))
417
418 (eq_attr "type" "move,unary")
419 (cond
420 [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
421 (match_operand 1 "register_operand" "") (const_int 4)
422 (match_operand 1 "long_immediate_operand" "") (const_int 8)
423 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
424 (const_int 4))
425
426 (and (eq_attr "type" "shift")
427 (match_operand 1 "immediate_operand"))
428 (const_int 8)
429 (eq_attr "type" "binary,shift")
430 (if_then_else
431 (ior (match_operand 2 "long_immediate_operand" "")
432 (and (ne (symbol_ref "REGNO (operands[0])")
433 (symbol_ref "REGNO (operands[1])"))
434 (eq (match_operand 2 "u6_immediate_operand" "")
435 (const_int 0))))
436
437 (const_int 8) (const_int 4))
438
439 (eq_attr "type" "cmove")
440 (if_then_else (match_operand 1 "register_operand" "")
441 (const_int 4) (const_int 8))
442
443 (eq_attr "type" "call_no_delay_slot") (const_int 8)
444 ]
445
446 (const_int 4))
447 )
448
449 ;; The length here is the length of a single asm. Unfortunately it might be
450 ;; 4 or 8 so we must allow for 8. That's ok though. How often will users
451 ;; lament asm's not being put in delay slots?
452 ;;
453 (define_asm_attributes
454 [(set_attr "length" "8")
455 (set_attr "type" "multi")
456 (set_attr "cond" "clob") ])
457
458 ;; Delay slots.
459 ;; The first two cond clauses and the default are necessary for correctness;
460 ;; the remaining cond clause is mainly an optimization, as otherwise nops
461 ;; would be inserted; however, if we didn't do this optimization, we would
462 ;; have to be more conservative in our length calculations.
463
464 (define_attr "in_delay_slot" "false,true"
465 (cond [(eq_attr "type" "uncond_branch,jump,branch,
466 call,sfunc,call_no_delay_slot,
467 brcc, brcc_no_delay_slot,loop_setup,loop_end")
468 (const_string "false")
469 (match_test "arc_write_ext_corereg (insn)")
470 (const_string "false")
471 (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
472 next_active_insn (insn))")
473 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
474 + arc_hazard (insn, next_active_insn (insn)))"))
475 (const_string "false")
476 (eq_attr "iscompact" "maybe") (const_string "true")
477 ]
478
479 (if_then_else (eq_attr "length" "2,4")
480 (const_string "true")
481 (const_string "false"))))
482
483 ; must not put an insn inside that refers to blink.
484 (define_attr "in_call_delay_slot" "false,true"
485 (cond [(eq_attr "in_delay_slot" "false")
486 (const_string "false")
487 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
488 (const_string "false")]
489 (const_string "true")))
490
491 (define_attr "in_sfunc_delay_slot" "false,true"
492 (cond [(eq_attr "in_call_delay_slot" "false")
493 (const_string "false")
494 (match_test "arc_regno_use_in (12, PATTERN (insn))")
495 (const_string "false")]
496 (const_string "true")))
497
498 ;; Instructions that we can put into a delay slot and conditionalize.
499 (define_attr "cond_delay_insn" "no,yes"
500 (cond [(eq_attr "cond" "!canuse") (const_string "no")
501 (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
502 (const_string "no")
503 (eq_attr "length" "2,4") (const_string "yes")]
504 (const_string "no")))
505
506 (define_attr "in_ret_delay_slot" "no,yes"
507 (cond [(eq_attr "in_delay_slot" "false")
508 (const_string "no")
509 (match_test "regno_clobbered_p
510 (arc_return_address_regs
511 [arc_compute_function_type (cfun)],
512 insn, SImode, 1)")
513 (const_string "no")]
514 (const_string "yes")))
515
516 (define_attr "cond_ret_delay_insn" "no,yes"
517 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
518 (eq_attr "cond_delay_insn" "no") (const_string "no")]
519 (const_string "yes")))
520
521 (define_attr "annul_ret_delay_insn" "no,yes"
522 (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
523 (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
524 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
525 (const_string "yes")]
526 (const_string "no")))
527
528
529 ;; Delay slot definition for ARCompact ISA
530 ;; ??? FIXME:
531 ;; When outputting an annul-true insn elegible for cond-exec
532 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
533 ;; for ARC600; we could also use this for ARC700 if the branch can't be
534 ;; unaligned and is at least somewhat likely (add parameter for this).
535
536 (define_delay (eq_attr "type" "call")
537 [(eq_attr "in_call_delay_slot" "true")
538 (eq_attr "in_call_delay_slot" "true")
539 (nil)])
540
541 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
542 (eq_attr "type" "brcc"))
543 [(eq_attr "in_delay_slot" "true")
544 (eq_attr "in_delay_slot" "true")
545 (nil)])
546
547 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
548 (eq_attr "type" "brcc"))
549 [(eq_attr "in_delay_slot" "true")
550 (nil)
551 (nil)])
552
553 (define_delay
554 (eq_attr "type" "return")
555 [(eq_attr "in_ret_delay_slot" "yes")
556 (eq_attr "annul_ret_delay_insn" "yes")
557 (eq_attr "cond_ret_delay_insn" "yes")])
558
559 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
560 ;; non-taken case, so the only meaningful way to have an annull-true
561 ;; filled delay slot is to conditionalize the delay slot insn.
562 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
563 (eq_attr "type" "branch,uncond_branch,jump")
564 (match_test "!optimize_size"))
565 [(eq_attr "in_delay_slot" "true")
566 (eq_attr "cond_delay_insn" "yes")
567 (eq_attr "cond_delay_insn" "yes")])
568
569 ;; For ARC700, anything goes for annulled-true insns, since there is no
570 ;; penalty for the unexposed delay slot when the branch is not taken,
571 ;; however, we must avoid things that have a delay slot themselvese to
572 ;; avoid confusing gcc.
573 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
574 (eq_attr "type" "branch,uncond_branch,jump")
575 (match_test "!optimize_size"))
576 [(eq_attr "in_delay_slot" "true")
577 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
578 (eq_attr "cond_delay_insn" "yes")])
579
580 ;; -mlongcall -fpic sfuncs use r12 to load the function address
581 (define_delay (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.
590
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"))))
600
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")))
605
606 ;; Move instructions.
607 (define_expand "movqi"
608 [(set (match_operand:QI 0 "move_dest_operand" "")
609 (match_operand:QI 1 "general_operand" ""))]
610 ""
611 "if (prepare_move_operands (operands, QImode)) DONE;")
612
613 ; In order to allow the ccfsm machinery to do its work, the leading compact
614 ; alternatives say 'canuse' - there is another alternative that will match
615 ; when the condition codes are used.
616 ; Rcq won't match if the condition is actually used; to avoid a spurious match
617 ; via q, q is inactivated as constraint there.
618 ; Likewise, the length of an alternative that might be shifted to conditional
619 ; execution must reflect this, lest out-of-range branches are created.
620 ; The iscompact attribute allows the epilogue expander to know for which
621 ; insns it should lengthen the return insn.
622 (define_insn "*movqi_insn"
623 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w, w,Rcq, S,!*x, r,r, Ucm,m,???m")
624 (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))]
625 "register_operand (operands[0], QImode)
626 || register_operand (operands[1], QImode)"
627 "@
628 mov%? %0,%1%&
629 mov%? %0,%1%&
630 mov%? %0,%1%&
631 mov%? %0,%1%&
632 mov%? %0,%1
633 mov%? %0,%1
634 mov%? %0,%1
635 mov%? %0,%S1
636 ldb%? %0,%1%&
637 stb%? %1,%0%&
638 ldb%? %0,%1%&
639 xldb%U1 %0,%1
640 ldb%U1%V1 %0,%1
641 xstb%U0 %1,%0
642 stb%U0%V0 %1,%0
643 stb%U0%V0 %1,%0"
644 [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store")
645 (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,false,true,true,true,false,false,false,false,false")
646 (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,no,no,no,no,no,no,no,no")
647 (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*")])
648
649 (define_expand "movhi"
650 [(set (match_operand:HI 0 "move_dest_operand" "")
651 (match_operand:HI 1 "general_operand" ""))]
652 ""
653 "if (prepare_move_operands (operands, HImode)) DONE;")
654
655 (define_insn "*movhi_insn"
656 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w,Rcq#q, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc")
657 (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac, ?i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))]
658 "register_operand (operands[0], HImode)
659 || register_operand (operands[1], HImode)
660 || (CONSTANT_P (operands[1])
661 /* Don't use a LIMM that we could load with a single insn - we loose
662 delay-slot filling opportunities. */
663 && !satisfies_constraint_I (operands[1])
664 && satisfies_constraint_Usc (operands[0]))"
665 "@
666 mov%? %0,%1%&
667 mov%? %0,%1%&
668 mov%? %0,%1%&
669 mov%? %0,%1%&
670 mov%? %0,%1
671 mov%? %0,%1
672 mov%? %0,%1
673 mov%? %0,%S1%&
674 mov%? %0,%S1
675 ld%_%? %0,%1%&
676 st%_%? %1,%0%&
677 xld%_%U1 %0,%1
678 ld%_%U1%V1 %0,%1
679 xst%_%U0 %1,%0
680 st%_%U0%V0 %1,%0
681 st%_%U0%V0 %1,%0
682 st%_%U0%V0 %S1,%0
683 st%_%U0%V0 %S1,%0"
684 [(set_attr "type" "move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
685 (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false,false")
686 (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no")
687 (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
688
689 (define_expand "movsi"
690 [(set (match_operand:SI 0 "move_dest_operand" "")
691 (match_operand:SI 1 "general_operand" ""))]
692 ""
693 "if (prepare_move_operands (operands, SImode)) DONE;")
694
695 ; In order to allow the ccfsm machinery to do its work, the leading compact
696 ; alternatives say 'canuse' - there is another alternative that will match
697 ; when the condition codes are used.
698 ; Rcq won't match if the condition is actually used; to avoid a spurious match
699 ; via q, q is inactivated as constraint there.
700 ; Likewise, the length of an alternative that might be shifted to conditional
701 ; execution must reflect this, lest out-of-range branches are created.
702 ; the iscompact attribute allows the epilogue expander to know for which
703 ; insns it should lengthen the return insn.
704 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
705 (define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
706 [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc")
707 (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))]
708 "register_operand (operands[0], SImode)
709 || register_operand (operands[1], SImode)
710 || (CONSTANT_P (operands[1])
711 /* Don't use a LIMM that we could load with a single insn - we loose
712 delay-slot filling opportunities. */
713 && !satisfies_constraint_I (operands[1])
714 && satisfies_constraint_Usc (operands[0]))"
715 "@
716 mov%? %0,%1%& ;0
717 mov%? %0,%1%& ;1
718 mov%? %0,%1%& ;2
719 mov%? %0,%1%& ;3
720 mov%? %0,%1 ;4
721 mov%? %0,%1 ;5
722 ror %0,((%1*2+1) & 0x3f) ;6
723 movl.cl %0,%1 ;7
724 movh.cl %0,%L1>>16 ;8
725 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\";
726 mov%? %0,%1 ;10
727 add %0,%S1 ;11
728 * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
729 mov%? %0,%S1%& ;13
730 mov%? %0,%S1 ;14
731 ld%? %0,%1%& ;15
732 st%? %1,%0%& ;16
733 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
734 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
735 ld%? %0,%1%& ;19
736 xld%U1 %0,%1 ;20
737 ld%? %0,%1%& ;21
738 ld%? %0,%1%& ;22
739 ld%U1%V1 %0,%1 ;23
740 xst%U0 %1,%0 ;24
741 st%? %1,%0%& ;25
742 st%U0%V0 %1,%0 ;26
743 st%U0%V0 %1,%0 ;27
744 st%U0%V0 %1,%0 ;28
745 st%U0%V0 %S1,%0 ;29"
746 [(set_attr "type" "move,move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,load,load,store,store,store,store,store,store")
747 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false")
748 ; Use default length for iscompact to allow for COND_EXEC. But set length
749 ; of Crr to 4.
750 (set_attr "length" "*,*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8")
751 (set_attr "predicable" "yes,no,yes,no,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
752 (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
753
754 ;; Sometimes generated by the epilogue code. We don't want to
755 ;; recognize these addresses in general, because the limm is costly,
756 ;; and we can't use them for stores. */
757 (define_insn "*movsi_pre_mod"
758 [(set (match_operand:SI 0 "register_operand" "=w")
759 (mem:SI (pre_modify
760 (reg:SI SP_REG)
761 (plus:SI (reg:SI SP_REG)
762 (match_operand 1 "immediate_operand" "Cal")))))]
763 "reload_completed"
764 "ld.a %0,[sp,%1]"
765 [(set_attr "type" "load")
766 (set_attr "length" "8")])
767
768 ;; Store a value to directly to memory. The location might also be cached.
769 ;; Since the cached copy can cause a write-back at unpredictable times,
770 ;; we first write cached, then we write uncached.
771 (define_insn "store_direct"
772 [(set (match_operand:SI 0 "move_dest_operand" "=m")
773 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
774 UNSPEC_ARC_DIRECT))]
775 ""
776 "st%U0 %1,%0\;st%U0.di %1,%0"
777 [(set_attr "type" "store")])
778
779 (define_insn_and_split "*movsi_set_cc_insn"
780 [(set (match_operand:CC_ZN 2 "cc_set_register" "")
781 (match_operator:CC_ZN 3 "zn_compare_operator"
782 [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
783 (set (match_operand:SI 0 "register_operand" "=w,w,w")
784 (match_dup 1))]
785 ""
786 "mov%?.f %0,%S1"
787 ; splitting to 'tst' allows short insns and combination into brcc.
788 "reload_completed && operands_match_p (operands[0], operands[1])"
789 [(set (match_dup 2) (match_dup 3))]
790 ""
791 [(set_attr "type" "compare")
792 (set_attr "predicable" "no,yes,yes")
793 (set_attr "cond" "set_zn")
794 (set_attr "length" "4,4,8")])
795
796 (define_insn "unary_comparison"
797 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
798 (match_operator:CC_ZN 3 "zn_compare_operator"
799 [(match_operator:SI 2 "unary_operator"
800 [(match_operand:SI 1 "register_operand" "c")])
801 (const_int 0)]))]
802 ""
803 "%O2.f 0,%1"
804 [(set_attr "type" "compare")
805 (set_attr "cond" "set_zn")])
806
807
808 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
809 (define_insn "*unary_comparison_result_used"
810 [(set (match_operand 2 "cc_register" "")
811 (match_operator 4 "zn_compare_operator"
812 [(match_operator:SI 3 "unary_operator"
813 [(match_operand:SI 1 "register_operand" "c")])
814 (const_int 0)]))
815 (set (match_operand:SI 0 "register_operand" "=w")
816 (match_dup 3))]
817 ""
818 "%O3.f %0,%1"
819 [(set_attr "type" "compare")
820 (set_attr "cond" "set_zn")
821 (set_attr "length" "4")])
822
823 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
824 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
825 ; even if we don't need the clobber.
826 (define_insn_and_split "*tst_movb"
827 [(set
828 (match_operand 0 "cc_register" "")
829 (match_operator 4 "zn_compare_operator"
830 [(and:SI
831 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c")
832 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
833 (const_int 0)]))
834 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
835 "TARGET_NPS_BITOPS"
836 "movb.f.cl %3,%1,%p2,%p2,%s2"
837 "reload_completed
838 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
839 [(set (match_dup 0) (match_dup 4))])
840
841 (define_insn "*tst"
842 [(set
843 (match_operand 0 "cc_register" "")
844 (match_operator 3 "zn_compare_operator"
845 [(and:SI
846 (match_operand:SI 1 "register_operand"
847 "%Rcq,Rcq, c, c, c, c, c, c")
848 (match_operand:SI 2 "nonmemory_operand"
849 " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
850 (const_int 0)]))]
851 "reload_completed
852 || !satisfies_constraint_Cbf (operands[2])
853 || satisfies_constraint_C0p (operands[2])
854 || satisfies_constraint_I (operands[2])
855 || satisfies_constraint_C1p (operands[2])
856 || satisfies_constraint_Chs (operands[2])"
857 "*
858 switch (which_alternative)
859 {
860 case 0: case 2: case 3: case 7:
861 return \"tst%? %1,%2\";
862 case 1:
863 return \"btst%? %1,%z2\";
864 case 4:
865 return \"bmsk%?.f 0,%1,%Z2%&\";
866 case 5:
867 return \"bclr%?.f 0,%1,%M2%&\";
868 case 6:
869 return \"asr.f 0,%1,%p2\";
870 default:
871 gcc_unreachable ();
872 }
873 "
874 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
875 (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
876 (set_attr "length" "*,*,4,4,4,4,4,8")
877 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
878 (set_attr "cond" "set_zn")])
879
880 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
881 ; combine will do that and not try the AND.
882
883 ; It would take 66 constraint combinations to describe the zero_extract
884 ; constants that are covered by the 12-bit signed constant for tst
885 ; (excluding the ones that are better done by mov or btst).
886 ; so we rather use an extra pattern for tst;
887 ; since this is about constants, reload shouldn't care.
888 (define_insn "*tst_bitfield_tst"
889 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
890 (match_operator 4 "zn_compare_operator"
891 [(zero_extract:SI
892 (match_operand:SI 1 "register_operand" "c")
893 (match_operand:SI 2 "const_int_operand" "n")
894 (match_operand:SI 3 "const_int_operand" "n"))
895 (const_int 0)]))]
896 "INTVAL (operands[2]) > 1
897 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
898 || (INTVAL (operands[3]) <= 11
899 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
900 "tst %1,(1<<%2)-1<<%3"
901 [(set_attr "type" "compare")
902 (set_attr "cond" "set_zn")
903 (set_attr "length" "4")])
904
905 ; Likewise for asr.f.
906 (define_insn "*tst_bitfield_asr"
907 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
908 (match_operator 4 "zn_compare_operator"
909 [(zero_extract:SI
910 (match_operand:SI 1 "register_operand" "c")
911 (match_operand:SI 2 "const_int_operand" "n")
912 (match_operand:SI 3 "const_int_operand" "n"))
913 (const_int 0)]))]
914 "INTVAL (operands[2]) > 1
915 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
916 "asr.f 0,%1,%3"
917 [(set_attr "type" "shift")
918 (set_attr "cond" "set_zn")
919 (set_attr "length" "4")])
920
921 (define_insn "*tst_bitfield"
922 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
923 (match_operator 5 "zn_compare_operator"
924 [(zero_extract:SI
925 (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c")
926 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
927 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
928 (const_int 0)]))
929 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
930 ""
931 "@
932 btst%? %1,%3
933 btst %1,%3
934 bmsk.f 0,%1,%2-1
935 movb.f.cl %4,%1,%3,%3,%2
936 and.f 0,%1,((1<<%2)-1)<<%3"
937 [(set_attr "iscompact" "maybe,false,false,false,false")
938 (set_attr "type" "compare,compare,compare,shift,compare")
939 (set_attr "cond" "set_zn")
940 (set_attr "length" "*,4,4,4,8")])
941
942 (define_insn "*commutative_binary_comparison"
943 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
944 (match_operator:CC_ZN 5 "zn_compare_operator"
945 [(match_operator:SI 4 "commutative_operator"
946 [(match_operand:SI 1 "register_operand" "%c,c,c")
947 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
948 (const_int 0)]))
949 (clobber (match_scratch:SI 3 "=X,1,X"))]
950 ""
951 "%O4.f 0,%1,%2"
952 [(set_attr "type" "compare")
953 (set_attr "cond" "set_zn")
954 (set_attr "length" "4,4,8")])
955
956 ; for flag setting 'add' instructions like if (a+b) { ...}
957 ; the combiner needs this pattern
958 (define_insn "*addsi_compare"
959 [(set (reg:CC_ZN CC_REG)
960 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
961 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
962 ""
963 "add.f 0,%0,%1"
964 [(set_attr "cond" "set")
965 (set_attr "type" "compare")
966 (set_attr "length" "4")])
967
968 ; for flag setting 'add' instructions like if (a+b < a) { ...}
969 ; the combiner needs this pattern
970 (define_insn "addsi_compare_2"
971 [(set (reg:CC_C CC_REG)
972 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
973 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
974 (match_dup 0)))]
975 ""
976 "add.f 0,%0,%1"
977 [(set_attr "cond" "set")
978 (set_attr "type" "compare")
979 (set_attr "length" "4,8")])
980
981 (define_insn "*addsi_compare_3"
982 [(set (reg:CC_C CC_REG)
983 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
984 (match_operand:SI 1 "register_operand" "c"))
985 (match_dup 1)))]
986 ""
987 "add.f 0,%0,%1"
988 [(set_attr "cond" "set")
989 (set_attr "type" "compare")
990 (set_attr "length" "4")])
991
992 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
993 (define_insn "*commutative_binary_comparison_result_used"
994 [(set (match_operand 3 "cc_register" "")
995 (match_operator 5 "zn_compare_operator"
996 ; We can accept any commutative operator except mult because
997 ; our 'w' class below could try to use LP_COUNT.
998 [(match_operator:SI 4 "commutative_operator_sans_mult"
999 [(match_operand:SI 1 "register_operand" "c,0,c")
1000 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1001 (const_int 0)]))
1002 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1003 (match_dup 4))]
1004 ""
1005 "%O4.f %0,%1,%2 ; non-mult commutative"
1006 [(set_attr "type" "compare,compare,compare")
1007 (set_attr "cond" "set_zn,set_zn,set_zn")
1008 (set_attr "length" "4,4,8")])
1009
1010 ; a MULT-specific version of this pattern to avoid touching the
1011 ; LP_COUNT register
1012 (define_insn "*commutative_binary_mult_comparison_result_used"
1013 [(set (match_operand 3 "cc_register" "")
1014 (match_operator 5 "zn_compare_operator"
1015 [(match_operator:SI 4 "mult_operator"
1016 [(match_operand:SI 1 "register_operand" "c,0,c")
1017 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1018 (const_int 0)]))
1019 ; Make sure to use the W class to not touch LP_COUNT.
1020 (set (match_operand:SI 0 "register_operand" "=W,W,W")
1021 (match_dup 4))]
1022 "!TARGET_ARC600_FAMILY"
1023 "%O4.f %0,%1,%2 ; mult commutative"
1024 [(set_attr "type" "compare,compare,compare")
1025 (set_attr "cond" "set_zn,set_zn,set_zn")
1026 (set_attr "length" "4,4,8")])
1027
1028 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
1029 (define_insn "*noncommutative_binary_comparison_result_used"
1030 [(set (match_operand 3 "cc_register" "")
1031 (match_operator 5 "zn_compare_operator"
1032 [(match_operator:SI 4 "noncommutative_operator"
1033 [(match_operand:SI 1 "register_operand" "c,0,c")
1034 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1035 (const_int 0)]))
1036 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1037 (match_dup 4 ))]
1038 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1039 "%O4.f %0,%1,%2"
1040 [(set_attr "type" "compare,compare,compare")
1041 (set_attr "cond" "set_zn,set_zn,set_zn")
1042 (set_attr "length" "4,4,8")])
1043
1044 (define_insn "*noncommutative_binary_comparison"
1045 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1046 (match_operator:CC_ZN 5 "zn_compare_operator"
1047 [(match_operator:SI 4 "noncommutative_operator"
1048 [(match_operand:SI 1 "register_operand" "c,c,c")
1049 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1050 (const_int 0)]))
1051 (clobber (match_scratch:SI 3 "=X,1,X"))]
1052 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1053 "%O4.f 0,%1,%2"
1054 [(set_attr "type" "compare")
1055 (set_attr "cond" "set_zn")
1056 (set_attr "length" "4,4,8")])
1057
1058 (define_expand "bic_f_zn"
1059 [(parallel
1060 [(set (reg:CC_ZN CC_REG)
1061 (compare:CC_ZN
1062 (and:SI (match_operand:SI 1 "register_operand" "")
1063 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1064 (const_int 0)))
1065 (set (match_operand:SI 0 "register_operand" "")
1066 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1067 "")
1068
1069 (define_insn "*bic_f"
1070 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
1071 (match_operator 4 "zn_compare_operator"
1072 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1073 (not:SI
1074 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1075 (const_int 0)]))
1076 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1077 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1078 ""
1079 "bic.f %0,%1,%2"
1080 [(set_attr "type" "compare,compare,compare")
1081 (set_attr "cond" "set_zn,set_zn,set_zn")
1082 (set_attr "length" "4,4,8")])
1083
1084 (define_expand "movdi"
1085 [(set (match_operand:DI 0 "move_dest_operand" "")
1086 (match_operand:DI 1 "general_operand" ""))]
1087 ""
1088 "
1089 {
1090 /* Everything except mem = const or mem = mem can be done easily. */
1091
1092 if (GET_CODE (operands[0]) == MEM)
1093 operands[1] = force_reg (DImode, operands[1]);
1094 }")
1095
1096 (define_insn_and_split "*movdi_insn"
1097 [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m")
1098 (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
1099 "register_operand (operands[0], DImode)
1100 || register_operand (operands[1], DImode)"
1101 "*
1102 {
1103 switch (which_alternative)
1104 {
1105 default:
1106 return \"#\";
1107
1108 case 2:
1109 if (TARGET_LL64
1110 && ((even_register_operand (operands[0], DImode)
1111 && memory_operand (operands[1], DImode))
1112 || (memory_operand (operands[0], DImode)
1113 && even_register_operand (operands[1], DImode))))
1114 return \"ldd%U1%V1 %0,%1%&\";
1115 return \"#\";
1116
1117 case 3:
1118 if (TARGET_LL64
1119 && ((even_register_operand (operands[0], DImode)
1120 && memory_operand (operands[1], DImode))
1121 || (memory_operand (operands[0], DImode)
1122 && even_register_operand (operands[1], DImode))))
1123 return \"std%U0%V0 %1,%0\";
1124 return \"#\";
1125 }
1126 }"
1127 "reload_completed"
1128 [(const_int 0)]
1129 {
1130 arc_split_move (operands);
1131 DONE;
1132 }
1133 [(set_attr "type" "move,move,load,store")
1134 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1135 (set_attr "length" "8,16,*,*")])
1136
1137
1138 ;; Floating point move insns.
1139
1140 (define_expand "movsf"
1141 [(set (match_operand:SF 0 "general_operand" "")
1142 (match_operand:SF 1 "general_operand" ""))]
1143 ""
1144 "if (prepare_move_operands (operands, SFmode)) DONE;")
1145
1146 (define_insn "*movsf_insn"
1147 [(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m")
1148 (match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))]
1149 "register_operand (operands[0], SFmode)
1150 || register_operand (operands[1], SFmode)"
1151 "@
1152 mov%? %0,%1
1153 mov%? %0,%1
1154 mov%? %0,%1 ; %A1
1155 ld%U1%V1 %0,%1
1156 st%U0%V0 %1,%0"
1157 [(set_attr "type" "move,move,move,load,store")
1158 (set_attr "predicable" "no,yes,yes,no,no")
1159 (set_attr "iscompact" "true,false,false,false,false")])
1160
1161 (define_expand "movdf"
1162 [(set (match_operand:DF 0 "nonimmediate_operand" "")
1163 (match_operand:DF 1 "general_operand" ""))]
1164 ""
1165 "if (prepare_move_operands (operands, DFmode)) DONE;")
1166
1167 (define_insn_and_split "*movdf_insn"
1168 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m")
1169 (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1170 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1171 "*
1172 {
1173 switch (which_alternative)
1174 {
1175 default:
1176 return \"#\";
1177 case 4:
1178 if (TARGET_LL64
1179 && ((even_register_operand (operands[0], DFmode)
1180 && memory_operand (operands[1], DFmode))
1181 || (memory_operand (operands[0], DFmode)
1182 && even_register_operand (operands[1], DFmode))))
1183 return \"ldd%U1%V1 %0,%1%&\";
1184 return \"#\";
1185
1186 case 5:
1187 if (TARGET_LL64
1188 && ((even_register_operand (operands[0], DFmode)
1189 && memory_operand (operands[1], DFmode))
1190 || (memory_operand (operands[0], DFmode)
1191 && even_register_operand (operands[1], DFmode))))
1192 return \"std%U0%V0 %1,%0\";
1193 return \"#\";
1194 }
1195 }"
1196 "reload_completed"
1197 [(const_int 0)]
1198 {
1199 arc_split_move (operands);
1200 DONE;
1201 }
1202 [(set_attr "type" "move,move,move,move,load,store")
1203 (set_attr "predicable" "no,no,yes,yes,no,no")
1204 ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1205 (set_attr "length" "4,16,8,16,16,16")])
1206
1207 (define_insn_and_split "*movdf_insn_nolrsr"
1208 [(set (match_operand:DF 0 "register_operand" "=r")
1209 (match_operand:DF 1 "arc_double_register_operand" "D"))
1210 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1211 ]
1212 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1213 "#"
1214 "&& 1"
1215 [
1216 ; mov r0, 0
1217 (set (match_dup 0) (match_dup 3))
1218
1219 ; daddh?? r1, r0, r0
1220 (parallel [
1221 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1222 (use (const_int 1))
1223 (use (const_int 1))
1224 (use (match_dup 0)) ; used to block can_combine_p
1225 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1226 ])
1227
1228 ; We have to do this twice, once to read the value into R0 and
1229 ; second time to put back the contents which the first DEXCLx
1230 ; will have overwritten
1231 ; dexcl2 r0, r1, r0
1232 (set (match_dup 4) ; aka r0result
1233 ; aka DF, r1, r0
1234 (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL ))
1235 ; Generate the second, which makes sure operand5 and operand4 values
1236 ; are put back in the Dx register properly.
1237 (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL_NORES )
1238
1239 ; Note: we cannot use a (clobber (match_scratch)) here because
1240 ; the combine pass will end up replacing uses of it with 0
1241 ]
1242 "operands[3] = CONST0_RTX (DFmode);
1243 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1244 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1245 [(set_attr "type" "move")])
1246
1247 ;; Load/Store with update instructions.
1248 ;;
1249 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1250 ;; hardware can also do cases where the increment is not the size of the
1251 ;; object.
1252 ;;
1253 ;; In all these cases, we use operands 0 and 1 for the register being
1254 ;; incremented because those are the operands that local-alloc will
1255 ;; tie and these are the pair most likely to be tieable (and the ones
1256 ;; that will benefit the most).
1257 ;;
1258 ;; We use match_operator here because we need to know whether the memory
1259 ;; object is volatile or not.
1260
1261
1262 ;; Note: loadqi_update has no 16-bit variant
1263 (define_insn "*loadqi_update"
1264 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1265 (match_operator:QI 4 "any_mem_operand"
1266 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1267 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1268 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1269 (plus:SI (match_dup 1) (match_dup 2)))]
1270 ""
1271 "ldb.a%V4 %3,[%0,%S2]"
1272 [(set_attr "type" "load,load")
1273 (set_attr "length" "4,8")])
1274
1275 (define_insn "*load_zeroextendqisi_update"
1276 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1277 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1278 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1279 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1280 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1281 (plus:SI (match_dup 1) (match_dup 2)))]
1282 ""
1283 "ldb.a%V4 %3,[%0,%S2]"
1284 [(set_attr "type" "load,load")
1285 (set_attr "length" "4,8")])
1286
1287 (define_insn "*load_signextendqisi_update"
1288 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1289 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1290 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1291 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1292 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1293 (plus:SI (match_dup 1) (match_dup 2)))]
1294 ""
1295 "ldb.x.a%V4 %3,[%0,%S2]"
1296 [(set_attr "type" "load,load")
1297 (set_attr "length" "4,8")])
1298
1299 (define_insn "*storeqi_update"
1300 [(set (match_operator:QI 4 "any_mem_operand"
1301 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1302 (match_operand:SI 2 "short_immediate_operand" "I"))])
1303 (match_operand:QI 3 "register_operand" "c"))
1304 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1305 (plus:SI (match_dup 1) (match_dup 2)))]
1306 ""
1307 "stb.a%V4 %3,[%0,%2]"
1308 [(set_attr "type" "store")
1309 (set_attr "length" "4")])
1310
1311 ;; ??? pattern may have to be re-written
1312 ;; Note: no 16-bit variant for this pattern
1313 (define_insn "*loadhi_update"
1314 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1315 (match_operator:HI 4 "any_mem_operand"
1316 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1317 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1318 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1319 (plus:SI (match_dup 1) (match_dup 2)))]
1320 ""
1321 "ld%_.a%V4 %3,[%0,%S2]"
1322 [(set_attr "type" "load,load")
1323 (set_attr "length" "4,8")])
1324
1325 (define_insn "*load_zeroextendhisi_update"
1326 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1327 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1328 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1329 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1330 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1331 (plus:SI (match_dup 1) (match_dup 2)))]
1332 ""
1333 "ld%_.a%V4 %3,[%0,%S2]"
1334 [(set_attr "type" "load,load")
1335 (set_attr "length" "4,8")])
1336
1337 ;; Note: no 16-bit variant for this instruction
1338 (define_insn "*load_signextendhisi_update"
1339 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1340 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1341 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1342 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1343 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1344 (plus:SI (match_dup 1) (match_dup 2)))]
1345 ""
1346 "ld%_.x.a%V4 %3,[%0,%S2]"
1347 [(set_attr "type" "load,load")
1348 (set_attr "length" "4,8")])
1349
1350 (define_insn "*storehi_update"
1351 [(set (match_operator:HI 4 "any_mem_operand"
1352 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1353 (match_operand:SI 2 "short_immediate_operand" "I"))])
1354 (match_operand:HI 3 "register_operand" "c"))
1355 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1356 (plus:SI (match_dup 1) (match_dup 2)))]
1357 ""
1358 "st%_.a%V4 %3,[%0,%2]"
1359 [(set_attr "type" "store")
1360 (set_attr "length" "4")])
1361
1362 ;; No 16-bit variant for this instruction pattern
1363 (define_insn "*loadsi_update"
1364 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1365 (match_operator:SI 4 "any_mem_operand"
1366 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1367 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1368 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1369 (plus:SI (match_dup 1) (match_dup 2)))]
1370 ""
1371 "ld.a%V4 %3,[%0,%S2]"
1372 [(set_attr "type" "load,load")
1373 (set_attr "length" "4,8")])
1374
1375 (define_insn "*storesi_update"
1376 [(set (match_operator:SI 4 "any_mem_operand"
1377 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1378 (match_operand:SI 2 "short_immediate_operand" "I"))])
1379 (match_operand:SI 3 "register_operand" "c"))
1380 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1381 (plus:SI (match_dup 1) (match_dup 2)))]
1382 ""
1383 "st.a%V4 %3,[%0,%2]"
1384 [(set_attr "type" "store")
1385 (set_attr "length" "4")])
1386
1387 (define_insn "*loadsf_update"
1388 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1389 (match_operator:SF 4 "any_mem_operand"
1390 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1391 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1392 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1393 (plus:SI (match_dup 1) (match_dup 2)))]
1394 ""
1395 "ld.a%V4 %3,[%0,%S2]"
1396 [(set_attr "type" "load,load")
1397 (set_attr "length" "4,8")])
1398
1399 (define_insn "*storesf_update"
1400 [(set (match_operator:SF 4 "any_mem_operand"
1401 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1402 (match_operand:SI 2 "short_immediate_operand" "I"))])
1403 (match_operand:SF 3 "register_operand" "c"))
1404 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1405 (plus:SI (match_dup 1) (match_dup 2)))]
1406 ""
1407 "st.a%V4 %3,[%0,%2]"
1408 [(set_attr "type" "store")
1409 (set_attr "length" "4")])
1410
1411 ;; Conditional move instructions.
1412
1413 (define_expand "movsicc"
1414 [(set (match_operand:SI 0 "dest_reg_operand" "")
1415 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1416 (match_operand:SI 2 "nonmemory_operand" "")
1417 (match_operand:SI 3 "register_operand" "")))]
1418 ""
1419 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1420
1421
1422 (define_expand "movdicc"
1423 [(set (match_operand:DI 0 "dest_reg_operand" "")
1424 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1425 (match_operand:DI 2 "nonmemory_operand" "")
1426 (match_operand:DI 3 "register_operand" "")))]
1427 ""
1428 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1429
1430
1431 (define_expand "movsfcc"
1432 [(set (match_operand:SF 0 "dest_reg_operand" "")
1433 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1434 (match_operand:SF 2 "nonmemory_operand" "")
1435 (match_operand:SF 3 "register_operand" "")))]
1436 ""
1437 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1438
1439 (define_expand "movdfcc"
1440 [(set (match_operand:DF 0 "dest_reg_operand" "")
1441 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1442 (match_operand:DF 2 "nonmemory_operand" "")
1443 (match_operand:DF 3 "register_operand" "")))]
1444 ""
1445 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1446
1447 (define_insn "*movsicc_insn"
1448 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1449 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1450 [(match_operand 4 "cc_register" "") (const_int 0)])
1451 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1452 (match_operand:SI 2 "register_operand" "0,0")))]
1453 ""
1454 {
1455 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1456 && satisfies_constraint_Rcq (operands[0]))
1457 return "sub%?.ne %0,%0,%0";
1458 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1459 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1460 && rtx_equal_p (operands[1], constm1_rtx)
1461 && GET_CODE (operands[3]) == LTU)
1462 return "sbc.cs %0,%0,%0";
1463 return "mov.%d3 %0,%S1";
1464 }
1465 [(set_attr "type" "cmove,cmove")
1466 (set_attr "length" "4,8")])
1467
1468 ; Try to generate more short moves, and/or less limms, by substituting a
1469 ; conditional move with a conditional sub.
1470 (define_peephole2
1471 [(set (match_operand:SI 0 "compact_register_operand")
1472 (match_operand:SI 1 "const_int_operand"))
1473 (set (match_dup 0)
1474 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1475 [(match_operand 4 "cc_register" "") (const_int 0)])
1476 (match_operand:SI 2 "const_int_operand" "")
1477 (match_dup 0)))]
1478 "!satisfies_constraint_P (operands[1])
1479 && satisfies_constraint_P (operands[2])
1480 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1481 [(set (match_dup 0) (match_dup 2))
1482 (cond_exec
1483 (match_dup 3)
1484 (set (match_dup 0)
1485 (plus:SI (match_dup 0) (match_dup 1))))]
1486 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1487 GET_MODE (operands[4])),
1488 VOIDmode, operands[4], const0_rtx);
1489 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1490
1491 (define_insn "*movdicc_insn"
1492 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1493 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1494 [(match_operand 4 "cc_register" "") (const_int 0)])
1495 (match_operand:DI 1 "nonmemory_operand" "c,i")
1496 (match_operand:DI 2 "register_operand" "0,0")))]
1497 ""
1498 "*
1499 {
1500 switch (which_alternative)
1501 {
1502 default:
1503 case 0 :
1504 /* We normally copy the low-numbered register first. However, if
1505 the first register operand 0 is the same as the second register of
1506 operand 1, we must copy in the opposite order. */
1507 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1508 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1509 else
1510 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1511 case 1 :
1512 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1513
1514
1515 }
1516 }"
1517 [(set_attr "type" "cmove,cmove")
1518 (set_attr "length" "8,16")])
1519
1520
1521 (define_insn "*movsfcc_insn"
1522 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1523 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1524 [(match_operand 4 "cc_register" "") (const_int 0)])
1525 (match_operand:SF 1 "nonmemory_operand" "c,E")
1526 (match_operand:SF 2 "register_operand" "0,0")))]
1527 ""
1528 "@
1529 mov.%d3 %0,%1
1530 mov.%d3 %0,%1 ; %A1"
1531 [(set_attr "type" "cmove,cmove")])
1532
1533 (define_insn "*movdfcc_insn"
1534 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1535 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1536 [(match_operand 4 "cc_register" "") (const_int 0)])
1537 (match_operand:DF 2 "nonmemory_operand" "c,E")
1538 (match_operand:DF 3 "register_operand" "0,0")))]
1539 ""
1540 "*
1541 {
1542 switch (which_alternative)
1543 {
1544 default:
1545 case 0 :
1546 /* We normally copy the low-numbered register first. However, if
1547 the first register operand 0 is the same as the second register of
1548 operand 1, we must copy in the opposite order. */
1549 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1550 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1551 else
1552 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1553 case 1 :
1554 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1555
1556 }
1557 }"
1558 [(set_attr "type" "cmove,cmove")
1559 (set_attr "length" "8,16")])
1560
1561
1562 (define_insn "*zero_extendqihi2_i"
1563 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
1564 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
1565 ""
1566 "@
1567 extb%? %0,%1%&
1568 extb%? %0,%1%&
1569 bmsk%? %0,%1,7
1570 extb %0,%1
1571 xldb%U1 %0,%1
1572 ldb%U1 %0,%1"
1573 [(set_attr "type" "unary,unary,unary,unary,load,load")
1574 (set_attr "iscompact" "maybe,true,false,false,false,false")
1575 (set_attr "predicable" "no,no,yes,no,no,no")])
1576
1577 (define_expand "zero_extendqihi2"
1578 [(set (match_operand:HI 0 "dest_reg_operand" "")
1579 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1580 ""
1581 "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1582 )
1583
1584 (define_insn "*zero_extendqisi2_ac"
1585 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
1586 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
1587 ""
1588 "@
1589 extb%? %0,%1%&
1590 extb%? %0,%1%&
1591 bmsk%? %0,%1,7
1592 extb %0,%1
1593 ldb%? %0,%1%&
1594 ldb%? %0,%1%&
1595 xldb%U1 %0,%1
1596 ldb%U1 %0,%1"
1597 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1598 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1599 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1600
1601 (define_expand "zero_extendqisi2"
1602 [(set (match_operand:SI 0 "dest_reg_operand" "")
1603 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1604 ""
1605 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1606 )
1607
1608 (define_insn "*zero_extendhisi2_i"
1609 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
1610 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))]
1611 ""
1612 "@
1613 ext%_%? %0,%1%&
1614 ext%_%? %0,%1%&
1615 bmsk%? %0,%1,15
1616 ext%_ %0,%1
1617 ld%_%? %0,%1%&
1618 ld%_%U1 %0,%1
1619 * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
1620 ld%_%U1%V1 %0,%1"
1621 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1622 (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
1623 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1624
1625
1626 (define_expand "zero_extendhisi2"
1627 [(set (match_operand:SI 0 "dest_reg_operand" "")
1628 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1629 ""
1630 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1631 )
1632
1633 ;; Sign extension instructions.
1634
1635 (define_insn "*extendqihi2_i"
1636 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
1637 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
1638 ""
1639 "@
1640 sexb%? %0,%1%&
1641 sexb %0,%1
1642 ldb.x%U1 %0,%1
1643 ldb.x%U1 %0,%1"
1644 [(set_attr "type" "unary,unary,load,load")
1645 (set_attr "iscompact" "true,false,false,false")
1646 (set_attr "length" "*,*,*,8")])
1647
1648
1649 (define_expand "extendqihi2"
1650 [(set (match_operand:HI 0 "dest_reg_operand" "")
1651 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1652 ""
1653 "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1654 )
1655
1656 (define_insn "*extendqisi2_ac"
1657 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
1658 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
1659 ""
1660 "@
1661 sexb%? %0,%1%&
1662 sexb %0,%1
1663 ldb.x%U1 %0,%1
1664 ldb.x%U1 %0,%1"
1665 [(set_attr "type" "unary,unary,load,load")
1666 (set_attr "iscompact" "true,false,false,false")
1667 (set_attr "length" "*,*,*,8")])
1668
1669 (define_expand "extendqisi2"
1670 [(set (match_operand:SI 0 "dest_reg_operand" "")
1671 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1672 ""
1673 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1674 )
1675
1676 (define_insn "*extendhisi2_i"
1677 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r")
1678 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
1679 ""
1680 "@
1681 sex%_%? %0,%1%&
1682 sex%_ %0,%1
1683 ldh%?.x %0,%1%&
1684 ld%_.x%U1%V1 %0,%1
1685 ld%_.x%U1%V1 %0,%1"
1686 [(set_attr "type" "unary,unary,load,load,load")
1687 (set_attr "iscompact" "true,false,true,false,false")
1688 (set_attr "length" "*,*,*,4,8")])
1689
1690 (define_expand "extendhisi2"
1691 [(set (match_operand:SI 0 "dest_reg_operand" "")
1692 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1693 ""
1694 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1695 )
1696
1697 ;; Unary arithmetic insns
1698
1699 ;; We allow constant operands to enable late constant propagation, but it is
1700 ;; not worth while to have more than one dedicated alternative to output them -
1701 ;; if we are really worried about getting these the maximum benefit of all
1702 ;; the available alternatives, we should add an extra pass to fold such
1703 ;; operations to movsi.
1704
1705 ;; Absolute instructions
1706
1707 (define_insn "*abssi2_mixed"
1708 [(set (match_operand:SI 0 "compact_register_operand" "=q")
1709 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1710 "TARGET_MIXED_CODE"
1711 "abs%? %0,%1%&"
1712 [(set_attr "type" "two_cycle_core")
1713 (set_attr "iscompact" "true")])
1714
1715 (define_insn "abssi2"
1716 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1717 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1718 ""
1719 "abs%? %0,%1%&"
1720 [(set_attr "type" "two_cycle_core")
1721 (set_attr "length" "*,4,8")
1722 (set_attr "iscompact" "true,false,false")])
1723
1724 ;; Maximum and minimum insns
1725
1726 (define_insn "smaxsi3"
1727 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1728 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1729 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1730 ""
1731 "max%? %0,%1,%2"
1732 [(set_attr "type" "two_cycle_core")
1733 (set_attr "length" "4,4,8")
1734 (set_attr "predicable" "yes,no,no")]
1735 )
1736
1737 (define_insn "sminsi3"
1738 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1739 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1740 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1741 ""
1742 "min%? %0,%1,%2"
1743 [(set_attr "type" "two_cycle_core")
1744 (set_attr "length" "4,4,8")
1745 (set_attr "predicable" "yes,no,no")]
1746 )
1747
1748 ;; Arithmetic instructions.
1749
1750 ; We say an insn can be conditionalized if this doesn't introduce a long
1751 ; immediate. We set the type such that we still have good scheduling if the
1752 ; insn is conditionalized.
1753 ; ??? It would make sense to allow introduction of long immediates, but
1754 ; we'd need to communicate to the ccfsm machinery the extra cost.
1755 ; The alternatives in the constraints still serve three purposes:
1756 ; - estimate insn size assuming conditional execution
1757 ; - guide reload to re-order the second and third operand to get a better fit.
1758 ; - give tentative insn type to guide scheduling
1759 ; N.B. "%" for commutativity doesn't help when there is another matching
1760 ; (but longer) alternative.
1761 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1762 ; register class 'W' instead of 'w'.
1763 (define_insn_and_split "*addsi3_mixed"
1764 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
1765 [(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")
1766 (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")
1767 (match_operand:SI 2 "nonmemory_operand" "cL, 0, cL, 0,CL2,Csp,CM4,cCca,RcqqK, cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1768 ""
1769 {
1770 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1771 return "";
1772 }
1773 "&& reload_completed && get_attr_length (insn) == 8
1774 && satisfies_constraint_I (operands[2])
1775 && GET_CODE (PATTERN (insn)) != COND_EXEC"
1776 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1777 "split_addsi (operands);"
1778 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*")
1779 (set (attr "iscompact")
1780 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1781 (const_string "false")
1782 (match_operand 2 "long_immediate_operand" "")
1783 (const_string "maybe_limm")]
1784 (const_string "maybe")))
1785 (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8")
1786 (set_attr "predicable" "no,no,yes,yes,no,no,no,yes,no,no,no,no,no,no,no,yes,no")
1787 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1788 ])
1789
1790 ;; ARCv2 MPYW and MPYUW
1791 (define_expand "mulhisi3"
1792 [(set (match_operand:SI 0 "register_operand" "")
1793 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1794 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1795 "TARGET_MPYW"
1796 "{
1797 if (CONSTANT_P (operands[2]))
1798 {
1799 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1800 DONE;
1801 }
1802 }"
1803 )
1804
1805 (define_insn "mulhisi3_imm"
1806 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
1807 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
1808 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
1809 "TARGET_MPYW"
1810 "mpyw%? %0,%1,%2"
1811 [(set_attr "length" "4,4,4,8,8")
1812 (set_attr "iscompact" "false")
1813 (set_attr "type" "mul16_em")
1814 (set_attr "predicable" "yes,no,no,yes,no")
1815 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1816 ])
1817
1818 (define_insn "mulhisi3_reg"
1819 [(set (match_operand:SI 0 "register_operand" "=Rcqq,r,r")
1820 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " 0,0,r"))
1821 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1822 "TARGET_MPYW"
1823 "mpyw%? %0,%1,%2"
1824 [(set_attr "length" "*,4,4")
1825 (set_attr "iscompact" "maybe,false,false")
1826 (set_attr "type" "mul16_em")
1827 (set_attr "predicable" "yes,yes,no")
1828 (set_attr "cond" "canuse,canuse,nocond")
1829 ])
1830
1831 (define_expand "umulhisi3"
1832 [(set (match_operand:SI 0 "register_operand" "")
1833 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1834 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
1835 "TARGET_MPYW"
1836 "{
1837 if (CONSTANT_P (operands[2]))
1838 {
1839 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1840 DONE;
1841 }
1842 }"
1843 )
1844
1845 (define_insn "umulhisi3_imm"
1846 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
1847 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
1848 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
1849 "TARGET_MPYW"
1850 "mpyuw%? %0,%1,%2"
1851 [(set_attr "length" "4,4,4,8,8")
1852 (set_attr "iscompact" "false")
1853 (set_attr "type" "mul16_em")
1854 (set_attr "predicable" "yes,no,no,yes,no")
1855 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1856 ])
1857
1858 (define_insn "umulhisi3_reg"
1859 [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r")
1860 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " %0, 0, r"))
1861 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1862 "TARGET_MPYW"
1863 "mpyuw%? %0,%1,%2"
1864 [(set_attr "length" "*,4,4")
1865 (set_attr "iscompact" "maybe,false,false")
1866 (set_attr "type" "mul16_em")
1867 (set_attr "predicable" "yes,yes,no")
1868 (set_attr "cond" "canuse,canuse,nocond")
1869 ])
1870
1871 ;; ARC700/ARC600/V2 multiply
1872 ;; SI <- SI * SI
1873
1874 (define_expand "mulsi3"
1875 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1876 (mult:SI (match_operand:SI 1 "register_operand" "")
1877 (match_operand:SI 2 "nonmemory_operand" "")))]
1878 ""
1879 {
1880 if (TARGET_MPY)
1881 {
1882 if (!register_operand (operands[0], SImode))
1883 {
1884 rtx result = gen_reg_rtx (SImode);
1885
1886 emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1887 emit_move_insn (operands[0], result);
1888 DONE;
1889 }
1890 }
1891 else if (TARGET_MUL64_SET)
1892 {
1893 emit_insn (gen_mulsi_600 (operands[1], operands[2],
1894 gen_mlo (), gen_mhi ()));
1895 emit_move_insn (operands[0], gen_mlo ());
1896 DONE;
1897 }
1898 else if (TARGET_MULMAC_32BY16_SET)
1899 {
1900 if (immediate_operand (operands[2], SImode)
1901 && INTVAL (operands[2]) >= 0
1902 && INTVAL (operands[2]) <= 65535)
1903 {
1904 emit_insn (gen_umul_600 (operands[1], operands[2],
1905 gen_acc2 (), gen_acc1 ()));
1906 emit_move_insn (operands[0], gen_acc2 ());
1907 DONE;
1908 }
1909 operands[2] = force_reg (SImode, operands[2]);
1910 emit_insn (gen_umul_600 (operands[1], operands[2],
1911 gen_acc2 (), gen_acc1 ()));
1912 emit_insn (gen_mac_600 (operands[1], operands[2],
1913 gen_acc2 (), gen_acc1 ()));
1914 emit_move_insn (operands[0], gen_acc2 ());
1915 DONE;
1916 }
1917 else
1918 {
1919 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1920 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1921 emit_insn (gen_mulsi3_600_lib ());
1922 emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1923 DONE;
1924 }
1925 })
1926
1927 ; mululw conditional execution without a LIMM clobbers an input register;
1928 ; we'd need a different pattern to describe this.
1929 ; To make the conditional execution valid for the LIMM alternative, we
1930 ; have to emit the LIMM before the register operand.
1931 (define_insn "umul_600"
1932 [(set (match_operand:SI 2 "acc2_operand" "")
1933 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1934 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
1935 "c,L,Cal")
1936 (const_int 16)
1937 (const_int 0))))
1938 (clobber (match_operand:SI 3 "acc1_operand" ""))]
1939 "TARGET_MULMAC_32BY16_SET"
1940 "@mululw 0, %0, %1
1941 mululw 0, %0, %1
1942 mululw%? 0, %1, %0"
1943 [(set_attr "length" "4,4,8")
1944 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1945 (set_attr "predicable" "no, no, yes")
1946 (set_attr "cond" "nocond, canuse_limm, canuse")])
1947
1948 (define_insn "mac_600"
1949 [(set (match_operand:SI 2 "acc2_operand" "")
1950 (plus:SI
1951 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1952 (ashift:SI
1953 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
1954 (const_int 16)
1955 (const_int 16))
1956 (const_int 16)))
1957 (match_dup 2)))
1958 (clobber (match_operand:SI 3 "acc1_operand" ""))]
1959 "TARGET_MULMAC_32BY16_SET"
1960 "machlw%? 0, %0, %1"
1961 [(set_attr "length" "4,4,8")
1962 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1963 (set_attr "predicable" "no, no, yes")
1964 (set_attr "cond" "nocond, canuse_limm, canuse")])
1965
1966 (define_insn "mulsi_600"
1967 [(set (match_operand:SI 2 "mlo_operand" "")
1968 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")
1969 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
1970 (clobber (match_operand:SI 3 "mhi_operand" ""))]
1971 "TARGET_MUL64_SET"
1972 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
1973 ; using a machine code pattern that only allows "L" constraint constants.
1974 ; "mul64%? \t0, %0, %1%&"
1975 {
1976 if (satisfies_constraint_I (operands[1])
1977 && !satisfies_constraint_L (operands[1]))
1978 {
1979 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */
1980 int n = true_regnum (operands[0]);
1981 int i = INTVAL (operands[1]);
1982 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
1983 asm_fprintf (asm_out_file, "\t.short %d`",
1984 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
1985 return "; mul64%? \t0, %0, %1%&";
1986 }
1987 return "mul64%? \t0, %0, %1%&";
1988 }
1989 [(set_attr "length" "*,4,4,8")
1990 (set_attr "iscompact" "maybe,false,false,false")
1991 (set_attr "type" "multi,multi,multi,multi")
1992 (set_attr "predicable" "yes,yes,no,yes")
1993 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1994
1995 ; If we compile without an mul option enabled, but link with libraries
1996 ; for a mul option, we'll see clobbers of multiplier output registers.
1997 ; There is also an implementation using norm that clobbers the loop registers.
1998 (define_insn "mulsi3_600_lib"
1999 [(set (reg:SI R0_REG)
2000 (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
2001 (clobber (reg:SI RETURN_ADDR_REGNUM))
2002 (clobber (reg:SI R1_REG))
2003 (clobber (reg:SI R2_REG))
2004 (clobber (reg:SI R3_REG))
2005 (clobber (reg:DI MUL64_OUT_REG))
2006 (clobber (reg:SI LP_COUNT))
2007 (clobber (reg:SI LP_START))
2008 (clobber (reg:SI LP_END))
2009 (clobber (reg:CC CC_REG))]
2010 "!TARGET_ANY_MPY
2011 && SFUNC_CHECK_PREDICABLE"
2012 "*return arc_output_libcall (\"__mulsi3\");"
2013 [(set_attr "is_sfunc" "yes")
2014 (set_attr "predicable" "yes")])
2015
2016 (define_insn "mulsidi_600"
2017 [(set (reg:DI MUL64_OUT_REG)
2018 (mult:DI (sign_extend:DI
2019 (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c"))
2020 (sign_extend:DI
2021 ; assembler issue for "I", see mulsi_600
2022 ; (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,Cal"))))]
2023 (match_operand:SI 1 "register_operand" "Rcq#q,cL,L,C32"))))]
2024 "TARGET_MUL64_SET"
2025 "mul64%? \t0, %0, %1%&"
2026 [(set_attr "length" "*,4,4,8")
2027 (set_attr "iscompact" "maybe,false,false,false")
2028 (set_attr "type" "multi,multi,multi,multi")
2029 (set_attr "predicable" "yes,yes,no,yes")
2030 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2031
2032 (define_insn "umulsidi_600"
2033 [(set (reg:DI MUL64_OUT_REG)
2034 (mult:DI (zero_extend:DI
2035 (match_operand:SI 0 "register_operand" "%c,c,c"))
2036 (sign_extend:DI
2037 ; assembler issue for "I", see mulsi_600
2038 ; (match_operand:SI 1 "register_operand" "cL,I,Cal"))))]
2039 (match_operand:SI 1 "register_operand" "cL,L,C32"))))]
2040 "TARGET_MUL64_SET"
2041 "mulu64%? \t0, %0, %1%&"
2042 [(set_attr "length" "4,4,8")
2043 (set_attr "iscompact" "false")
2044 (set_attr "type" "umulti")
2045 (set_attr "predicable" "yes,no,yes")
2046 (set_attr "cond" "canuse,canuse_limm,canuse")])
2047
2048 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2049 ; may not be used as destination constraint.
2050
2051 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2052 ; but mpyu is faster for the standard multiplier.
2053 ; Note: we must make sure LP_COUNT is not one of the destination
2054 ; registers, since it cannot be the destination of a multi-cycle insn
2055 ; like MPY or MPYU.
2056 (define_insn "mulsi3_700"
2057 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r")
2058 (mult:SI (match_operand:SI 1 "register_operand" " 0,c,0,0,c")
2059 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2060 "TARGET_ARC700_MPY"
2061 "mpyu%? %0,%1,%2"
2062 [(set_attr "length" "4,4,4,8,8")
2063 (set_attr "type" "umulti")
2064 (set_attr "predicable" "yes,no,no,yes,no")
2065 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2066
2067 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2068 ; short variant. LP_COUNT constraints are still valid.
2069 (define_insn "mulsi3_v2"
2070 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r")
2071 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c")
2072 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
2073 "TARGET_MULTI"
2074 "mpy%? %0,%1,%2"
2075 [(set_attr "length" "*,4,4,4,8,8")
2076 (set_attr "iscompact" "maybe,false,false,false,false,false")
2077 (set_attr "type" "umulti")
2078 (set_attr "predicable" "no,yes,no,no,yes,no")
2079 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2080
2081 (define_expand "mulsidi3"
2082 [(set (match_operand:DI 0 "register_operand" "")
2083 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2084 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2085 "TARGET_ANY_MPY"
2086 "
2087 {
2088 if (TARGET_MPY)
2089 {
2090 operands[2] = force_reg (SImode, operands[2]);
2091 if (!register_operand (operands[0], DImode))
2092 {
2093 rtx result = gen_reg_rtx (DImode);
2094
2095 operands[2] = force_reg (SImode, operands[2]);
2096 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2097 emit_move_insn (operands[0], result);
2098 DONE;
2099 }
2100 }
2101 else if (TARGET_MUL64_SET)
2102 {
2103 operands[2] = force_reg (SImode, operands[2]);
2104 emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
2105 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2106 DONE;
2107 }
2108 else if (TARGET_MULMAC_32BY16_SET)
2109 {
2110 rtx result_hi = gen_highpart(SImode, operands[0]);
2111 rtx result_low = gen_lowpart(SImode, operands[0]);
2112
2113 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2114 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2115 emit_move_insn (result_low, gen_acc2 ());
2116 DONE;
2117 }
2118 }")
2119
2120 (define_insn "mul64_600"
2121 [(set (reg:DI 56)
2122 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2123 "c,c,c"))
2124 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2125 "c,L,Cal")
2126 (const_int 16)
2127 (const_int 0))))
2128 ]
2129 "TARGET_MULMAC_32BY16_SET"
2130 "mullw%? 0, %0, %1"
2131 [(set_attr "length" "4,4,8")
2132 (set_attr "type" "mulmac_600")
2133 (set_attr "predicable" "no,no,yes")
2134 (set_attr "cond" "nocond, canuse_limm, canuse")])
2135
2136
2137 ;; ??? check if this is canonical rtl
2138 (define_insn "mac64_600"
2139 [(set (reg:DI 56)
2140 (plus:DI
2141 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2142 (ashift:DI
2143 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2144 (const_int 16) (const_int 16))
2145 (const_int 16)))
2146 (reg:DI 56)))
2147 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2148 (zero_extract:SI
2149 (plus:DI
2150 (mult:DI (sign_extend:DI (match_dup 1))
2151 (ashift:DI
2152 (sign_extract:DI (match_dup 2)
2153 (const_int 16) (const_int 16))
2154 (const_int 16)))
2155 (reg:DI 56))
2156 (const_int 32) (const_int 32)))]
2157 "TARGET_MULMAC_32BY16_SET"
2158 "machlw%? %0, %1, %2"
2159 [(set_attr "length" "4,4,8")
2160 (set_attr "type" "mulmac_600")
2161 (set_attr "predicable" "no,no,yes")
2162 (set_attr "cond" "nocond, canuse_limm, canuse")])
2163
2164
2165 ;; DI <- DI(signed SI) * DI(signed SI)
2166 (define_insn_and_split "mulsidi3_700"
2167 [(set (match_operand:DI 0 "register_operand" "=&r")
2168 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2169 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2170 "TARGET_MPY"
2171 "#"
2172 "&& reload_completed"
2173 [(const_int 0)]
2174 {
2175 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2176 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2177 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2178 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2179 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2180 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2181 DONE;
2182 }
2183 [(set_attr "type" "multi")
2184 (set_attr "length" "8")])
2185
2186 (define_insn "mulsi3_highpart"
2187 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2188 (truncate:SI
2189 (lshiftrt:DI
2190 (mult:DI
2191 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2192 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2193 (const_int 32))))]
2194 "TARGET_MPY"
2195 "mpy%+%? %0,%1,%2"
2196 [(set_attr "length" "4,4,8,8")
2197 (set_attr "type" "multi")
2198 (set_attr "predicable" "yes,no,yes,no")
2199 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2200
2201 ; Note that mpyhu has the same latency as mpy / mpyh,
2202 ; thus we use the type multi.
2203 (define_insn "*umulsi3_highpart_i"
2204 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2205 (truncate:SI
2206 (lshiftrt:DI
2207 (mult:DI
2208 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2209 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2210 (const_int 32))))]
2211 "TARGET_MPY"
2212 "mpy%+u%? %0,%1,%2"
2213 [(set_attr "length" "4,4,8,8")
2214 (set_attr "type" "multi")
2215 (set_attr "predicable" "yes,no,yes,no")
2216 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2217
2218 ; Implementations include additional labels for umulsidi3, so we got all
2219 ; the same clobbers - plus one for the result low part. */
2220 (define_insn "umulsi3_highpart_600_lib_le"
2221 [(set (reg:SI R1_REG)
2222 (truncate:SI
2223 (lshiftrt:DI
2224 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2225 (zero_extend:DI (reg:SI R1_REG)))
2226 (const_int 32))))
2227 (clobber (reg:SI RETURN_ADDR_REGNUM))
2228 (clobber (reg:SI R0_REG))
2229 (clobber (reg:DI R2_REG))
2230 (clobber (reg:SI R12_REG))
2231 (clobber (reg:DI MUL64_OUT_REG))
2232 (clobber (reg:CC CC_REG))]
2233 "!TARGET_BIG_ENDIAN
2234 && !TARGET_ANY_MPY
2235 && SFUNC_CHECK_PREDICABLE"
2236 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2237 [(set_attr "is_sfunc" "yes")
2238 (set_attr "predicable" "yes")])
2239
2240 (define_insn "umulsi3_highpart_600_lib_be"
2241 [(set (reg:SI R0_REG)
2242 (truncate:SI
2243 (lshiftrt:DI
2244 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2245 (zero_extend:DI (reg:SI R1_REG)))
2246 (const_int 32))))
2247 (clobber (reg:SI RETURN_ADDR_REGNUM))
2248 (clobber (reg:SI R1_REG))
2249 (clobber (reg:DI R2_REG))
2250 (clobber (reg:SI R12_REG))
2251 (clobber (reg:DI MUL64_OUT_REG))
2252 (clobber (reg:CC CC_REG))]
2253 "TARGET_BIG_ENDIAN
2254 && !TARGET_ANY_MPY
2255 && SFUNC_CHECK_PREDICABLE"
2256 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2257 [(set_attr "is_sfunc" "yes")
2258 (set_attr "predicable" "yes")])
2259
2260 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2261 ;; need a separate pattern for immediates
2262 ;; ??? This is fine for combine, but not for reload.
2263 (define_insn "umulsi3_highpart_int"
2264 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r")
2265 (truncate:SI
2266 (lshiftrt:DI
2267 (mult:DI
2268 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c"))
2269 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2270 (const_int 32))))]
2271 "TARGET_MPY"
2272 "mpy%+u%? %0,%1,%2"
2273 [(set_attr "length" "4,4,4,8,8")
2274 (set_attr "type" "multi")
2275 (set_attr "predicable" "yes,no,no,yes,no")
2276 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2277
2278 (define_expand "umulsi3_highpart"
2279 [(set (match_operand:SI 0 "general_operand" "")
2280 (truncate:SI
2281 (lshiftrt:DI
2282 (mult:DI
2283 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2284 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2285 (const_int 32))))]
2286 "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2287 "
2288 {
2289 rtx target = operands[0];
2290
2291 if (!TARGET_MPY)
2292 {
2293 emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2294 emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2295 if (TARGET_BIG_ENDIAN)
2296 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2297 else
2298 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2299 emit_move_insn (target, gen_rtx_REG (SImode, 0));
2300 DONE;
2301 }
2302
2303 if (!register_operand (target, SImode))
2304 target = gen_reg_rtx (SImode);
2305
2306 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2307 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2308 operands[2], SImode);
2309 else if (!immediate_operand (operands[2], SImode))
2310 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2311 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2312 if (target != operands[0])
2313 emit_move_insn (operands[0], target);
2314 DONE;
2315 }")
2316
2317 (define_expand "umulsidi3"
2318 [(set (match_operand:DI 0 "register_operand" "")
2319 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2320 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2321 ""
2322 {
2323 if (TARGET_MPY)
2324 {
2325 operands[2] = force_reg (SImode, operands[2]);
2326 if (!register_operand (operands[0], DImode))
2327 {
2328 rtx result = gen_reg_rtx (DImode);
2329
2330 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2331 emit_move_insn (operands[0], result);
2332 DONE;
2333 }
2334 }
2335 else if (TARGET_MUL64_SET)
2336 {
2337 operands[2] = force_reg (SImode, operands[2]);
2338 emit_insn (gen_umulsidi_600 (operands[1], operands[2]));
2339 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2340 DONE;
2341 }
2342 else if (TARGET_MULMAC_32BY16_SET)
2343 {
2344 rtx result_hi = gen_reg_rtx (SImode);
2345 rtx result_low = gen_reg_rtx (SImode);
2346
2347 result_hi = gen_highpart(SImode , operands[0]);
2348 result_low = gen_lowpart(SImode , operands[0]);
2349
2350 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2351 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2352 emit_move_insn (result_low, gen_acc2 ());
2353 DONE;
2354 }
2355 else
2356 {
2357 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2358 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2359 emit_insn (gen_umulsidi3_600_lib ());
2360 emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2361 DONE;
2362 }
2363 })
2364
2365 (define_insn "umul64_600"
2366 [(set (reg:DI 56)
2367 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2368 "c,c,c"))
2369 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2370 "c,L,Cal")
2371 (const_int 16)
2372 (const_int 0))))
2373 ]
2374 "TARGET_MULMAC_32BY16_SET"
2375 "@mululw 0, %0, %1
2376 mululw 0, %0, %1
2377 mululw%? 0, %1, %0"
2378 [(set_attr "length" "4,4,8")
2379 (set_attr "type" "mulmac_600")
2380 (set_attr "predicable" "no,no,yes")
2381 (set_attr "cond" "nocond, canuse_limm, canuse")])
2382
2383
2384 (define_insn "umac64_600"
2385 [(set (reg:DI 56)
2386 (plus:DI
2387 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2388 (ashift:DI
2389 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2390 (const_int 16) (const_int 16))
2391 (const_int 16)))
2392 (reg:DI 56)))
2393 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2394 (zero_extract:SI
2395 (plus:DI
2396 (mult:DI (zero_extend:DI (match_dup 1))
2397 (ashift:DI
2398 (zero_extract:DI (match_dup 2)
2399 (const_int 16) (const_int 16))
2400 (const_int 16)))
2401 (reg:DI 56))
2402 (const_int 32) (const_int 32)))]
2403 "TARGET_MULMAC_32BY16_SET"
2404 "machulw%? %0, %1, %2"
2405 [(set_attr "length" "4,4,8")
2406 (set_attr "type" "mulmac_600")
2407 (set_attr "predicable" "no,no,yes")
2408 (set_attr "cond" "nocond, canuse_limm, canuse")])
2409
2410
2411
2412 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2413 (define_insn_and_split "umulsidi3_700"
2414 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2415 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2416 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2417 "TARGET_MPY"
2418 "#"
2419 "reload_completed"
2420 [(const_int 0)]
2421 {
2422 int hi = !TARGET_BIG_ENDIAN;
2423 int lo = !hi;
2424 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2425 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2426 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2427 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2428 DONE;
2429 }
2430 [(set_attr "type" "umulti")
2431 (set_attr "length" "8")])
2432
2433 (define_insn "umulsidi3_600_lib"
2434 [(set (reg:DI R0_REG)
2435 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2436 (zero_extend:DI (reg:SI R1_REG))))
2437 (clobber (reg:SI RETURN_ADDR_REGNUM))
2438 (clobber (reg:DI R2_REG))
2439 (clobber (reg:SI R12_REG))
2440 (clobber (reg:DI MUL64_OUT_REG))
2441 (clobber (reg:CC CC_REG))]
2442 "!TARGET_ANY_MPY
2443 && SFUNC_CHECK_PREDICABLE"
2444 "*return arc_output_libcall (\"__umulsidi3\");"
2445 [(set_attr "is_sfunc" "yes")
2446 (set_attr "predicable" "yes")])
2447
2448 (define_peephole2
2449 [(parallel
2450 [(set (reg:DI R0_REG)
2451 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2452 (zero_extend:DI (reg:SI R1_REG))))
2453 (clobber (reg:SI RETURN_ADDR_REGNUM))
2454 (clobber (reg:DI R2_REG))
2455 (clobber (reg:SI R12_REG))
2456 (clobber (reg:DI MUL64_OUT_REG))
2457 (clobber (reg:CC CC_REG))])]
2458 "!TARGET_ANY_MPY
2459 && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2460 [(pc)]
2461 {
2462 if (TARGET_BIG_ENDIAN)
2463 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2464 else
2465 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2466 DONE;
2467 })
2468
2469 (define_expand "addsi3"
2470 [(set (match_operand:SI 0 "dest_reg_operand" "")
2471 (plus:SI (match_operand:SI 1 "register_operand" "")
2472 (match_operand:SI 2 "nonmemory_operand" "")))]
2473 ""
2474 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2475 {
2476 operands[2]=force_reg(SImode, operands[2]);
2477 }
2478 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2479 {
2480 operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2481 }
2482
2483 ")
2484
2485 (define_expand "adddi3"
2486 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2487 (plus:DI (match_operand:DI 1 "register_operand" "")
2488 (match_operand:DI 2 "nonmemory_operand" "")))
2489 (clobber (reg:CC CC_REG))])]
2490 ""
2491 {
2492 if (TARGET_EXPAND_ADDDI)
2493 {
2494 rtx l0 = gen_lowpart (SImode, operands[0]);
2495 rtx h0 = disi_highpart (operands[0]);
2496 rtx l1 = gen_lowpart (SImode, operands[1]);
2497 rtx h1 = disi_highpart (operands[1]);
2498 rtx l2 = gen_lowpart (SImode, operands[2]);
2499 rtx h2 = disi_highpart (operands[2]);
2500 rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2501
2502 if (CONST_INT_P (h2) && INTVAL (h2) < 0 && SIGNED_INT12 (INTVAL (h2)))
2503 {
2504 emit_insn (gen_sub_f (l0, l1, gen_int_mode (-INTVAL (l2), SImode)));
2505 emit_insn (gen_sbc (h0, h1,
2506 gen_int_mode (-INTVAL (h2) - (l1 != 0), SImode),
2507 cc_c));
2508 DONE;
2509 }
2510 emit_insn (gen_add_f (l0, l1, l2));
2511 emit_insn (gen_adc (h0, h1, h2));
2512 DONE;
2513 }
2514 })
2515
2516 ; This assumes that there can be no strictly partial overlap between
2517 ; operands[1] and operands[2].
2518 (define_insn_and_split "*adddi3_i"
2519 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2520 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2521 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2522 (clobber (reg:CC CC_REG))]
2523 ""
2524 "#"
2525 "reload_completed"
2526 [(const_int 0)]
2527 {
2528 int hi = !TARGET_BIG_ENDIAN;
2529 int lo = !hi;
2530 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2531 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2532 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2533 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2534 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2535 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2536
2537
2538 if (l2 == const0_rtx)
2539 {
2540 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2541 emit_move_insn (l0, l1);
2542 emit_insn (gen_addsi3 (h0, h1, h2));
2543 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2544 emit_move_insn (l0, l1);
2545 DONE;
2546 }
2547 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2548 && INTVAL (operands[2]) >= -0x7fffffff)
2549 {
2550 emit_insn (gen_subdi3_i (operands[0], operands[1],
2551 GEN_INT (-INTVAL (operands[2]))));
2552 DONE;
2553 }
2554 if (rtx_equal_p (l0, h1))
2555 {
2556 if (h2 != const0_rtx)
2557 emit_insn (gen_addsi3 (h0, h1, h2));
2558 else if (!rtx_equal_p (h0, h1))
2559 emit_move_insn (h0, h1);
2560 emit_insn (gen_add_f (l0, l1, l2));
2561 emit_insn
2562 (gen_rtx_COND_EXEC
2563 (VOIDmode,
2564 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2565 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2566 DONE;
2567 }
2568 emit_insn (gen_add_f (l0, l1, l2));
2569 emit_insn (gen_adc (h0, h1, h2));
2570 DONE;
2571 }
2572 [(set_attr "cond" "clob")
2573 (set_attr "type" "binary")
2574 (set_attr "length" "16,16,20")])
2575
2576 (define_insn "add_f"
2577 [(set (reg:CC_C CC_REG)
2578 (compare:CC_C
2579 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2580 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2581 (match_dup 1)))
2582 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2583 (plus:SI (match_dup 1) (match_dup 2)))]
2584 ""
2585 "add.f %0,%1,%2"
2586 [(set_attr "cond" "set")
2587 (set_attr "type" "compare")
2588 (set_attr "length" "4,4,8")])
2589
2590 (define_insn "*add_f_2"
2591 [(set (reg:CC_C CC_REG)
2592 (compare:CC_C
2593 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2594 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2595 (match_dup 2)))
2596 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2597 (plus:SI (match_dup 1) (match_dup 2)))]
2598 ""
2599 "add.f %0,%1,%2"
2600 [(set_attr "cond" "set")
2601 (set_attr "type" "compare")
2602 (set_attr "length" "4,4,8")])
2603
2604 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2605 ; needlessly prioritizing the matching constraint.
2606 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2607 ; execution is used where possible.
2608 (define_insn_and_split "adc"
2609 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2610 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2611 (match_operand:SI 1 "nonmemory_operand"
2612 "%c,0,c,0,cCal"))
2613 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2614 "register_operand (operands[1], SImode)
2615 || register_operand (operands[2], SImode)"
2616 "@
2617 adc %0,%1,%2
2618 add.cs %0,%1,1
2619 adc %0,%1,%2
2620 adc %0,%1,%2
2621 adc %0,%1,%2"
2622 ; if we have a bad schedule after sched2, split.
2623 "reload_completed
2624 && !optimize_size && (!TARGET_ARC600_FAMILY)
2625 && arc_scheduling_not_expected ()
2626 && arc_sets_cc_p (prev_nonnote_insn (insn))
2627 /* If next comes a return or other insn that needs a delay slot,
2628 expect the adc to get into the delay slot. */
2629 && next_nonnote_insn (insn)
2630 && !arc_need_delay (next_nonnote_insn (insn))
2631 /* Restore operands before emitting. */
2632 && (extract_insn_cached (insn), 1)"
2633 [(set (match_dup 0) (match_dup 3))
2634 (cond_exec
2635 (ltu (reg:CC_C CC_REG) (const_int 0))
2636 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2637 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2638 [(set_attr "cond" "use")
2639 (set_attr "type" "cc_arith")
2640 (set_attr "length" "4,4,4,4,8")])
2641
2642 ; combiner-splitter cmp / scc -> cmp / adc
2643 (define_split
2644 [(set (match_operand:SI 0 "dest_reg_operand" "")
2645 (gtu:SI (match_operand:SI 1 "register_operand" "")
2646 (match_operand:SI 2 "register_operand" "")))
2647 (clobber (reg CC_REG))]
2648 ""
2649 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2650 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2651
2652 ; combine won't work when an intermediate result is used later...
2653 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2654 (define_peephole2
2655 [(set (match_operand:SI 0 "dest_reg_operand" "")
2656 (plus:SI (match_operand:SI 1 "register_operand" "")
2657 (match_operand:SI 2 "nonmemory_operand" "")))
2658 (set (reg:CC_C CC_REG)
2659 (compare:CC_C (match_dup 0)
2660 (match_operand:SI 3 "nonmemory_operand" "")))]
2661 "rtx_equal_p (operands[1], operands[3])
2662 || rtx_equal_p (operands[2], operands[3])"
2663 [(parallel
2664 [(set (reg:CC_C CC_REG)
2665 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2666 (set (match_dup 0)
2667 (plus:SI (match_dup 1) (match_dup 2)))])])
2668
2669 ; ??? need to delve into combine to find out why this is not useful.
2670 ; We'd like to be able to grok various C idioms for carry bit usage.
2671 ;(define_insn "*adc_0"
2672 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2673 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2674 ; (match_operand:SI 1 "register_operand" "c")))]
2675 ; ""
2676 ; "adc %0,%1,0"
2677 ; [(set_attr "cond" "use")
2678 ; (set_attr "type" "cc_arith")
2679 ; (set_attr "length" "4")])
2680 ;
2681 ;(define_split
2682 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2683 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2684 ; (match_operand:SI 2 "register_operand" "c"))
2685 ; (match_operand:SI 3 "register_operand" "c")))
2686 ; (clobber (reg CC_REG))]
2687 ; ""
2688 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2689 ; (set (match_dup 0)
2690 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2691 ; (match_dup 3)))])
2692
2693 (define_expand "subsi3"
2694 [(set (match_operand:SI 0 "dest_reg_operand" "")
2695 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2696 (match_operand:SI 2 "nonmemory_operand" "")))]
2697 ""
2698 "
2699 {
2700 int c = 1;
2701
2702 if (!register_operand (operands[2], SImode))
2703 {
2704 operands[1] = force_reg (SImode, operands[1]);
2705 c = 2;
2706 }
2707 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2708 operands[c] = force_reg (SImode, operands[c]);
2709 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2710 operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2711 }")
2712
2713 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2714 ; combine should make such an insn go away.
2715 (define_insn_and_split "subsi3_insn"
2716 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,w,w,w, w, w, w")
2717 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0, 0, cL,c,L,I,Cal,Cal, c")
2718 (match_operand:SI 2 "nonmemory_operand" "Rcqq, c, 0,c,c,0, 0, c,Cal")))]
2719 "register_operand (operands[1], SImode)
2720 || register_operand (operands[2], SImode)"
2721 "@
2722 sub%? %0,%1,%2%&
2723 sub%? %0,%1,%2
2724 rsub%? %0,%2,%1
2725 sub %0,%1,%2
2726 rsub %0,%2,%1
2727 rsub %0,%2,%1
2728 rsub%? %0,%2,%1
2729 rsub %0,%2,%1
2730 sub %0,%1,%2"
2731 "reload_completed && get_attr_length (insn) == 8
2732 && satisfies_constraint_I (operands[1])
2733 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2734 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2735 "split_subsi (operands);"
2736 [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false")
2737 (set_attr "length" "*,4,4,4,4,4,8,8,8")
2738 (set_attr "predicable" "yes,yes,yes,no,no,no,yes,no,no")
2739 (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2740
2741 (define_expand "subdi3"
2742 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2743 (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2744 (match_operand:DI 2 "nonmemory_operand" "")))
2745 (clobber (reg:CC CC_REG))])]
2746 ""
2747 {
2748 if (!register_operand (operands[2], DImode))
2749 operands[1] = force_reg (DImode, operands[1]);
2750 if (TARGET_EXPAND_ADDDI)
2751 {
2752 rtx l0 = gen_lowpart (SImode, operands[0]);
2753 rtx h0 = disi_highpart (operands[0]);
2754 rtx l1 = gen_lowpart (SImode, operands[1]);
2755 rtx h1 = disi_highpart (operands[1]);
2756 rtx l2 = gen_lowpart (SImode, operands[2]);
2757 rtx h2 = disi_highpart (operands[2]);
2758 rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2759
2760 emit_insn (gen_sub_f (l0, l1, l2));
2761 emit_insn (gen_sbc (h0, h1, h2, cc_c));
2762 DONE;
2763 }
2764 })
2765
2766 (define_insn_and_split "subdi3_i"
2767 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2768 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2769 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2770 (clobber (reg:CC CC_REG))]
2771 "register_operand (operands[1], DImode)
2772 || register_operand (operands[2], DImode)"
2773 "#"
2774 "reload_completed"
2775 [(const_int 0)]
2776 {
2777 int hi = !TARGET_BIG_ENDIAN;
2778 int lo = !hi;
2779 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2780 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2781 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2782 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2783 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2784 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2785
2786 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2787 {
2788 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2789 if (!rtx_equal_p (h0, h1))
2790 emit_insn (gen_rtx_SET (h0, h1));
2791 emit_insn (gen_sub_f (l0, l1, l2));
2792 emit_insn
2793 (gen_rtx_COND_EXEC
2794 (VOIDmode,
2795 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2796 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2797 DONE;
2798 }
2799 emit_insn (gen_sub_f (l0, l1, l2));
2800 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2801 DONE;
2802 }
2803 [(set_attr "cond" "clob")
2804 (set_attr "length" "16,16,16,20,20")])
2805
2806 (define_insn "*sbc_0"
2807 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2808 (minus:SI (match_operand:SI 1 "register_operand" "c")
2809 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2810 (const_int 0))))]
2811 ""
2812 "sbc %0,%1,0"
2813 [(set_attr "cond" "use")
2814 (set_attr "type" "cc_arith")
2815 (set_attr "length" "4")])
2816
2817 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2818 ; needlessly prioritizing the matching constraint.
2819 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2820 ; is used where possible.
2821 (define_insn_and_split "sbc"
2822 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2823 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2824 "c,0,c,0,cCal")
2825 (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2826 (const_int 0)))
2827 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2828 "register_operand (operands[1], SImode)
2829 || register_operand (operands[2], SImode)"
2830 "@
2831 sbc %0,%1,%2
2832 sub.cs %0,%1,1
2833 sbc %0,%1,%2
2834 sbc %0,%1,%2
2835 sbc %0,%1,%2"
2836 ; if we have a bad schedule after sched2, split.
2837 "reload_completed
2838 && !optimize_size && (!TARGET_ARC600_FAMILY)
2839 && arc_scheduling_not_expected ()
2840 && arc_sets_cc_p (prev_nonnote_insn (insn))
2841 /* If next comes a return or other insn that needs a delay slot,
2842 expect the adc to get into the delay slot. */
2843 && next_nonnote_insn (insn)
2844 && !arc_need_delay (next_nonnote_insn (insn))
2845 /* Restore operands before emitting. */
2846 && (extract_insn_cached (insn), 1)"
2847 [(set (match_dup 0) (match_dup 4))
2848 (cond_exec
2849 (ltu (reg:CC_C CC_REG) (const_int 0))
2850 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2851 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2852 [(set_attr "cond" "use")
2853 (set_attr "type" "cc_arith")
2854 (set_attr "length" "4,4,4,4,8")])
2855
2856 (define_insn "sub_f"
2857 [(set (reg:CC CC_REG)
2858 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2859 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2860 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2861 (minus:SI (match_dup 1) (match_dup 2)))]
2862 "register_operand (operands[1], SImode)
2863 || register_operand (operands[2], SImode)"
2864 "@
2865 sub.f %0,%1,%2
2866 rsub.f %0,%2,%1
2867 sub.f %0,%1,%2
2868 rsub.f %0,%2,%1
2869 sub.f %0,%1,%2
2870 sub.f %0,%1,%2"
2871 [(set_attr "type" "compare")
2872 (set_attr "length" "4,4,4,4,8,8")])
2873
2874 ; combine won't work when an intermediate result is used later...
2875 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2876 (define_peephole2
2877 [(set (reg:CC CC_REG)
2878 (compare:CC (match_operand:SI 1 "register_operand" "")
2879 (match_operand:SI 2 "nonmemory_operand" "")))
2880 (set (match_operand:SI 0 "dest_reg_operand" "")
2881 (minus:SI (match_dup 1) (match_dup 2)))]
2882 ""
2883 [(parallel
2884 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2885 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
2886
2887 (define_peephole2
2888 [(set (reg:CC CC_REG)
2889 (compare:CC (match_operand:SI 1 "register_operand" "")
2890 (match_operand:SI 2 "nonmemory_operand" "")))
2891 (set (match_operand 3 "" "") (match_operand 4 "" ""))
2892 (set (match_operand:SI 0 "dest_reg_operand" "")
2893 (minus:SI (match_dup 1) (match_dup 2)))]
2894 "!reg_overlap_mentioned_p (operands[3], operands[1])
2895 && !reg_overlap_mentioned_p (operands[3], operands[2])
2896 && !reg_overlap_mentioned_p (operands[0], operands[4])
2897 && !reg_overlap_mentioned_p (operands[0], operands[3])"
2898 [(parallel
2899 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2900 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2901 (set (match_dup 3) (match_dup 4))])
2902
2903 (define_insn "*add_n"
2904 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
2905 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
2906 (match_operand:SI 2 "_2_4_8_operand" ""))
2907 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
2908 ""
2909 "add%z2%? %0,%3,%1%&"
2910 [(set_attr "type" "shift")
2911 (set_attr "length" "*,4,4,8,4,8")
2912 (set_attr "predicable" "yes,yes,no,no,no,no")
2913 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
2914 (set_attr "iscompact" "maybe,false,false,false,false,false")])
2915
2916 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
2917 ;; what synth_mult likes.
2918 (define_insn "*sub_n"
2919 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2920 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
2921 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
2922 (match_operand:SI 3 "_2_4_8_operand" ""))))]
2923 ""
2924 "sub%z3%? %0,%1,%2"
2925 [(set_attr "type" "shift")
2926 (set_attr "length" "4,4,8")
2927 (set_attr "predicable" "yes,no,no")
2928 (set_attr "cond" "canuse,nocond,nocond")
2929 (set_attr "iscompact" "false")])
2930
2931 ; ??? check if combine matches this.
2932 (define_insn "*bset"
2933 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2934 (ior:SI (ashift:SI (const_int 1)
2935 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2936 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2937 ""
2938 "bset%? %0,%2,%1"
2939 [(set_attr "length" "4,4,8")
2940 (set_attr "predicable" "yes,no,no")
2941 (set_attr "cond" "canuse,nocond,nocond")]
2942 )
2943
2944 ; ??? check if combine matches this.
2945 (define_insn "*bxor"
2946 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2947 (xor:SI (ashift:SI (const_int 1)
2948 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2949 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2950 ""
2951 "bxor%? %0,%2,%1"
2952 [(set_attr "length" "4,4,8")
2953 (set_attr "predicable" "yes,no,no")
2954 (set_attr "cond" "canuse,nocond,nocond")]
2955 )
2956
2957 ; ??? check if combine matches this.
2958 (define_insn "*bclr"
2959 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2960 (and:SI (not:SI (ashift:SI (const_int 1)
2961 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
2962 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2963 ""
2964 "bclr%? %0,%2,%1"
2965 [(set_attr "length" "4,4,8")
2966 (set_attr "predicable" "yes,no,no")
2967 (set_attr "cond" "canuse,nocond,nocond")]
2968 )
2969
2970 ; ??? FIXME: find combine patterns for bmsk.
2971
2972 ;;Following are the define_insns added for the purpose of peephole2's
2973
2974 ; see also iorsi3 for use with constant bit number.
2975 (define_insn "*bset_insn"
2976 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2977 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2978 (ashift:SI (const_int 1)
2979 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2980 ""
2981 "@
2982 bset%? %0,%1,%2 ;;peep2, constr 1
2983 bset %0,%1,%2 ;;peep2, constr 2
2984 bset %0,%S1,%2 ;;peep2, constr 3"
2985 [(set_attr "length" "4,4,8")
2986 (set_attr "predicable" "yes,no,no")
2987 (set_attr "cond" "canuse,nocond,nocond")]
2988 )
2989
2990 ; see also xorsi3 for use with constant bit number.
2991 (define_insn "*bxor_insn"
2992 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2993 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2994 (ashift:SI (const_int 1)
2995 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2996 ""
2997 "@
2998 bxor%? %0,%1,%2
2999 bxor %0,%1,%2
3000 bxor %0,%S1,%2"
3001 [(set_attr "length" "4,4,8")
3002 (set_attr "predicable" "yes,no,no")
3003 (set_attr "cond" "canuse,nocond,nocond")]
3004 )
3005
3006 ; see also andsi3 for use with constant bit number.
3007 (define_insn "*bclr_insn"
3008 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3009 (and:SI (not:SI (ashift:SI (const_int 1)
3010 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
3011 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
3012 ""
3013 "@
3014 bclr%? %0,%1,%2
3015 bclr %0,%1,%2
3016 bclr %0,%S1,%2"
3017 [(set_attr "length" "4,4,8")
3018 (set_attr "predicable" "yes,no,no")
3019 (set_attr "cond" "canuse,nocond,nocond")]
3020 )
3021
3022 ; see also andsi3 for use with constant bit number.
3023 (define_insn "*bmsk_insn"
3024 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3025 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3026 (plus:SI (ashift:SI (const_int 1)
3027 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3028 (const_int 1)))
3029 (const_int -1))))]
3030 ""
3031 "@
3032 bmsk%? %0,%S1,%2
3033 bmsk %0,%1,%2
3034 bmsk %0,%S1,%2"
3035 [(set_attr "length" "4,4,8")
3036 (set_attr "predicable" "yes,no,no")
3037 (set_attr "cond" "canuse,nocond,nocond")]
3038 )
3039
3040 ;;Instructions added for peephole2s end
3041
3042 ;; Boolean instructions.
3043
3044 (define_expand "andsi3"
3045 [(set (match_operand:SI 0 "dest_reg_operand" "")
3046 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3047 (match_operand:SI 2 "nonmemory_operand" "")))]
3048 ""
3049 "if (!satisfies_constraint_Cux (operands[2]))
3050 operands[1] = force_reg (SImode, operands[1]);
3051 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
3052 operands[1] = arc_rewrite_small_data (operands[1]);")
3053
3054 (define_insn "andsi3_i"
3055 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw, Rcw,Rcw,Rcw,Rcw, w, w, w, w,Rrq,w,Rcw, w,W")
3056 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,Rrq,0, 0, c,o")
3057 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C1p, Ccp, Cux, cL, 0,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
3058 "(register_operand (operands[1], SImode)
3059 && nonmemory_operand (operands[2], SImode))
3060 || (memory_operand (operands[1], SImode)
3061 && satisfies_constraint_Cux (operands[2]))"
3062 {
3063 switch (which_alternative)
3064 {
3065 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3066 return "and%? %0,%1,%2%&";
3067 case 1: case 6:
3068 return "and%? %0,%2,%1%&";
3069 case 2:
3070 return "bmsk%? %0,%1,%Z2%&";
3071 case 7: case 12:
3072 if (satisfies_constraint_C2p (operands[2]))
3073 {
3074 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3075 return "bmskn%? %0,%1,%Z2%&";
3076 }
3077 else
3078 {
3079 return "bmsk%? %0,%1,%Z2%&";
3080 }
3081 case 3: case 8: case 13:
3082 return "bclr%? %0,%1,%M2%&";
3083 case 4:
3084 return (INTVAL (operands[2]) == 0xff
3085 ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3086 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3087 case 15:
3088 return "movb.cl %0,%1,%p2,%p2,%s2";
3089
3090 case 19:
3091 const char *tmpl;
3092
3093 if (satisfies_constraint_Ucm (operands[1]))
3094 tmpl = (INTVAL (operands[2]) == 0xff
3095 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3096 else
3097 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3098
3099 if (TARGET_BIG_ENDIAN)
3100 {
3101 rtx xop[2];
3102
3103 xop[0] = operands[0];
3104 xop[1] = adjust_address (operands[1], QImode,
3105 INTVAL (operands[2]) == 0xff ? 3 : 2);
3106 output_asm_insn (tmpl, xop);
3107 return "";
3108 }
3109 return tmpl;
3110 default:
3111 gcc_unreachable ();
3112 }
3113 }
3114 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3115 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3116 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3117 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3118 (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
3119
3120 ; combiner splitter, pattern found in ldtoa.c .
3121 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3122 (define_split
3123 [(set (reg:CC_Z CC_REG)
3124 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3125 (match_operand 1 "const_int_operand" ""))
3126 (match_operand 2 "const_int_operand" "")))
3127 (clobber (match_operand:SI 3 "register_operand" ""))]
3128 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3129 [(set (match_dup 3)
3130 (plus:SI (match_dup 0) (match_dup 4)))
3131 (set (reg:CC_Z CC_REG)
3132 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3133 (const_int 0)))]
3134 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3135
3136 ;;bic define_insn that allows limm to be the first operand
3137 (define_insn "*bicsi3_insn"
3138 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3139 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3140 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3141 ""
3142 "@
3143 bic%? %0, %2, %1%& ;;constraint 0
3144 bic%? %0,%2,%1 ;;constraint 1
3145 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3146 bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3147 bic %0,%2,%1 ;;constraint 4
3148 bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
3149 bic %0,%S2,%1 ;;constraint 6"
3150 [(set_attr "length" "*,4,4,8,4,8,8")
3151 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3152 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3153 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3154
3155 (define_insn "iorsi3"
3156 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w")
3157 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c")
3158 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3159 ""
3160 "*
3161 switch (which_alternative)
3162 {
3163 case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3164 return \"or%? %0,%1,%2%&\";
3165 case 1: case 4:
3166 return \"or%? %0,%2,%1%&\";
3167 case 2: case 5: case 8:
3168 return \"bset%? %0,%1,%z2%&\";
3169 default:
3170 gcc_unreachable ();
3171 }"
3172 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3173 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3174 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3175 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3176
3177 (define_insn "xorsi3"
3178 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w")
3179 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c")
3180 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3181 ""
3182 "*
3183 switch (which_alternative)
3184 {
3185 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3186 return \"xor%? %0,%1,%2%&\";
3187 case 1: case 3:
3188 return \"xor%? %0,%2,%1%&\";
3189 case 4: case 7:
3190 return \"bxor%? %0,%1,%z2\";
3191 default:
3192 gcc_unreachable ();
3193 }
3194 "
3195 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3196 (set_attr "type" "binary")
3197 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3198 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3199 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3200
3201 (define_insn "negsi2"
3202 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3203 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3204 ""
3205 "neg%? %0,%1%&"
3206 [(set_attr "type" "unary")
3207 (set_attr "iscompact" "maybe,true,false,false")
3208 (set_attr "predicable" "no,no,yes,no")])
3209
3210 (define_insn "one_cmplsi2"
3211 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3212 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3213 ""
3214 "not%? %0,%1%&"
3215 [(set_attr "type" "unary,unary")
3216 (set_attr "iscompact" "true,false")])
3217
3218 (define_insn_and_split "one_cmpldi2"
3219 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3220 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3221 ""
3222 "#"
3223 "&& reload_completed"
3224 [(set (match_dup 2) (not:SI (match_dup 3)))
3225 (set (match_dup 4) (not:SI (match_dup 5)))]
3226 {
3227 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3228
3229 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3230 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3231 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3232 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3233 }
3234 [(set_attr "type" "unary,unary")
3235 (set_attr "cond" "nocond,nocond")
3236 (set_attr "length" "4,8")])
3237
3238 ;; Shift instructions.
3239
3240 (define_expand "ashlsi3"
3241 [(set (match_operand:SI 0 "dest_reg_operand" "")
3242 (ashift:SI (match_operand:SI 1 "register_operand" "")
3243 (match_operand:SI 2 "nonmemory_operand" "")))]
3244 ""
3245 "
3246 {
3247 if (!TARGET_BARREL_SHIFTER)
3248 {
3249 emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3250 DONE;
3251 }
3252 }")
3253
3254 (define_expand "ashrsi3"
3255 [(set (match_operand:SI 0 "dest_reg_operand" "")
3256 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3257 (match_operand:SI 2 "nonmemory_operand" "")))]
3258 ""
3259 "
3260 {
3261 if (!TARGET_BARREL_SHIFTER)
3262 {
3263 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3264 DONE;
3265 }
3266 }")
3267
3268 (define_expand "lshrsi3"
3269 [(set (match_operand:SI 0 "dest_reg_operand" "")
3270 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3271 (match_operand:SI 2 "nonmemory_operand" "")))]
3272 ""
3273 "
3274 {
3275 if (!TARGET_BARREL_SHIFTER)
3276 {
3277 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3278 DONE;
3279 }
3280 }")
3281
3282 (define_insn "shift_si3"
3283 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3284 (match_operator:SI 3 "shift4_operator"
3285 [(match_operand:SI 1 "register_operand" "0")
3286 (match_operand:SI 2 "const_int_operand" "n")]))
3287 (clobber (match_scratch:SI 4 "=&r"))
3288 (clobber (reg:CC CC_REG))
3289 ]
3290 "!TARGET_BARREL_SHIFTER"
3291 "* return output_shift (operands);"
3292 [(set_attr "type" "shift")
3293 (set_attr "length" "16")])
3294
3295 (define_insn "shift_si3_loop"
3296 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3297 (match_operator:SI 3 "shift_operator"
3298 [(match_operand:SI 1 "register_operand" "0,0")
3299 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3300 (clobber (match_scratch:SI 4 "=X,X"))
3301 (clobber (reg:SI LP_COUNT))
3302 (clobber (reg:SI LP_START))
3303 (clobber (reg:SI LP_END))
3304 (clobber (reg:CC CC_REG))
3305 ]
3306 "!TARGET_BARREL_SHIFTER"
3307 "* return output_shift (operands);"
3308 [(set_attr "type" "shift")
3309 (set_attr "length" "16,20")])
3310
3311 ; asl, asr, lsr patterns:
3312 ; There is no point in including an 'I' alternative since only the lowest 5
3313 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3314 ; is defined in an external symbol, as we don't have special relocations
3315 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3316 ; provide one alternatice for this, without condexec support.
3317 (define_insn "*ashlsi3_insn"
3318 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3319 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3320 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3321 "TARGET_BARREL_SHIFTER
3322 && (register_operand (operands[1], SImode)
3323 || register_operand (operands[2], SImode))"
3324 "asl%? %0,%1,%2%&"
3325 [(set_attr "type" "shift")
3326 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3327 (set_attr "predicable" "no,no,no,yes,no,no")
3328 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3329
3330 (define_insn "*ashrsi3_insn"
3331 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3332 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3333 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3334 "TARGET_BARREL_SHIFTER
3335 && (register_operand (operands[1], SImode)
3336 || register_operand (operands[2], SImode))"
3337 "asr%? %0,%1,%2%&"
3338 [(set_attr "type" "shift")
3339 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3340 (set_attr "predicable" "no,no,no,yes,no,no")
3341 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3342
3343 (define_insn "*lshrsi3_insn"
3344 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3345 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3346 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))]
3347 "TARGET_BARREL_SHIFTER
3348 && (register_operand (operands[1], SImode)
3349 || register_operand (operands[2], SImode))"
3350 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3351 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3352 [(set_attr "type" "shift")
3353 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3354 (set_attr "predicable" "no,no,no,yes,no,no")
3355 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3356
3357 (define_insn "rotrsi3"
3358 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
3359 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
3360 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3361 "TARGET_BARREL_SHIFTER"
3362 "ror%? %0,%1,%2"
3363 [(set_attr "type" "shift,shift,shift")
3364 (set_attr "predicable" "yes,no,no")
3365 (set_attr "length" "4,4,8")])
3366
3367 ;; Compare / branch instructions.
3368
3369 (define_expand "cbranchsi4"
3370 [(set (reg:CC CC_REG)
3371 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3372 (match_operand:SI 2 "nonmemory_operand" "")))
3373 (set (pc)
3374 (if_then_else
3375 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3376 (const_int 0)])
3377 (label_ref (match_operand 3 "" ""))
3378 (pc)))]
3379 ""
3380 {
3381 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3382 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3383 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3384 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3385 DONE;
3386 })
3387
3388 ;; ??? Could add a peephole to generate compare with swapped operands and
3389 ;; modifed cc user if second, but not first operand is a compact register.
3390 (define_insn "cmpsi_cc_insn_mixed"
3391 [(set (reg:CC CC_REG)
3392 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q, h, c, c,qRcq,c")
3393 (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI,cL, Cal,Cal")))]
3394 ""
3395 "cmp%? %0,%B1%&"
3396 [(set_attr "type" "compare")
3397 (set_attr "iscompact" "true,true,false,false,true_limm,false")
3398 (set_attr "predicable" "no,no,no,yes,no,yes")
3399 (set_attr "cond" "set")
3400 (set_attr "length" "*,*,4,4,*,8")])
3401
3402 (define_insn "*cmpsi_cc_zn_insn"
3403 [(set (reg:CC_ZN CC_REG)
3404 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c")
3405 (const_int 0)))]
3406 ""
3407 "tst%? %0,%0%&"
3408 [(set_attr "type" "compare,compare")
3409 (set_attr "iscompact" "true,false")
3410 (set_attr "predicable" "no,yes")
3411 (set_attr "cond" "set_zn")
3412 (set_attr "length" "*,4")])
3413
3414 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3415 (define_insn "*btst"
3416 [(set (reg:CC_ZN CC_REG)
3417 (compare:CC_ZN
3418 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3419 (const_int 1)
3420 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3421 (const_int 0)))]
3422 ""
3423 "btst%? %0,%1"
3424 [(set_attr "iscompact" "true,false")
3425 (set_attr "predicable" "no,yes")
3426 (set_attr "cond" "set")
3427 (set_attr "type" "compare")
3428 (set_attr "length" "*,4")])
3429
3430 ; combine suffers from 'simplifications' that replace a one-bit zero
3431 ; extract with a shift if it can prove that the upper bits are zero.
3432 ; arc_reorg sees the code after sched2, which can have caused our
3433 ; inputs to be clobbered even if they were not clobbered before.
3434 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3435 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3436 ; bbit (i.e. bad scheduling) and missed conditional execution,
3437 ; so make this an option.
3438 (define_peephole2
3439 [(set (reg:CC_ZN CC_REG)
3440 (compare:CC_ZN
3441 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3442 (const_int 1)
3443 (match_operand:SI 1 "nonmemory_operand" ""))
3444 (const_int 0)))
3445 (set (pc)
3446 (if_then_else (match_operator 3 "equality_comparison_operator"
3447 [(reg:CC_ZN CC_REG) (const_int 0)])
3448 (label_ref (match_operand 2 "" ""))
3449 (pc)))]
3450 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3451 [(parallel [(set (pc)
3452 (if_then_else
3453 (match_op_dup 3
3454 [(zero_extract:SI (match_dup 0)
3455 (const_int 1) (match_dup 1))
3456 (const_int 0)])
3457 (label_ref (match_dup 2))
3458 (pc)))
3459 (clobber (reg:CC_ZN CC_REG))])])
3460
3461 (define_insn "*cmpsi_cc_z_insn"
3462 [(set (reg:CC_Z CC_REG)
3463 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c")
3464 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3465 ""
3466 "@
3467 cmp%? %0,%1%&
3468 bxor.f 0,%0,%z1"
3469 [(set_attr "type" "compare,compare")
3470 (set_attr "iscompact" "true,false")
3471 (set_attr "cond" "set,set_zn")
3472 (set_attr "length" "*,4")])
3473
3474 (define_insn "*cmpsi_cc_c_insn"
3475 [(set (reg:CC_C CC_REG)
3476 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, h, c,Rcqq, c")
3477 (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI, Cal,Cal")))]
3478 ""
3479 "cmp%? %0,%S1%&"
3480 [(set_attr "type" "compare")
3481 (set_attr "iscompact" "true,true,false,true_limm,false")
3482 (set_attr "cond" "set")
3483 (set_attr "length" "*,*,4,*,8")])
3484
3485 ;; Next come the scc insns.
3486
3487 (define_expand "cstoresi4"
3488 [(set (match_operand:SI 0 "dest_reg_operand" "")
3489 (match_operator:SI 1 "ordered_comparison_operator"
3490 [(match_operand:SI 2 "nonmemory_operand" "")
3491 (match_operand:SI 3 "nonmemory_operand" "")]))]
3492 ""
3493 {
3494 if (!TARGET_CODE_DENSITY)
3495 {
3496 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3497 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3498 operands[1] = gen_compare_reg (operands[1], SImode);
3499 emit_insn (gen_scc_insn (operands[0], operands[1]));
3500 DONE;
3501 }
3502 if (!register_operand (operands[2], SImode))
3503 operands[2] = force_reg (SImode, operands[2]);
3504
3505 })
3506
3507 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3508 (DF "TARGET_OPTFPE")])
3509
3510 (define_expand "cstore<mode>4"
3511 [(set (reg:CC CC_REG)
3512 (compare:CC (match_operand:SDF 2 "register_operand" "")
3513 (match_operand:SDF 3 "register_operand" "")))
3514 (set (match_operand:SI 0 "dest_reg_operand" "")
3515 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3516 (const_int 0)]))]
3517
3518 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
3519 {
3520 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3521 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3522 operands[1] = gen_compare_reg (operands[1], SImode);
3523 emit_insn (gen_scc_insn (operands[0], operands[1]));
3524 DONE;
3525 })
3526
3527 ; We need a separate expander for this lest we loose the mode of CC_REG
3528 ; when match_operator substitutes the literal operand into the comparison.
3529 (define_expand "scc_insn"
3530 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3531
3532 (define_insn_and_split "*scc_insn"
3533 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3534 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3535 ""
3536 "#"
3537 "reload_completed"
3538 [(set (match_dup 0) (const_int 1))
3539 (cond_exec
3540 (match_dup 1)
3541 (set (match_dup 0) (const_int 0)))]
3542 {
3543 operands[1]
3544 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3545 GET_MODE (XEXP (operands[1], 0))),
3546 VOIDmode,
3547 XEXP (operands[1], 0), XEXP (operands[1], 1));
3548 }
3549 [(set_attr "type" "unary")])
3550
3551 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3552 ;; that is one lower if the carry flag is set.
3553
3554 ;; ??? Look up negscc insn. See pa.md for example.
3555 (define_insn "*neg_scc_insn"
3556 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3557 (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3558 [(reg CC_REG) (const_int 0)])))]
3559 ""
3560 "mov %0,-1\;sub.%D1 %0,%0,%0"
3561 [(set_attr "type" "unary")
3562 (set_attr "length" "8")])
3563
3564 (define_insn "*not_scc_insn"
3565 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3566 (not:SI (match_operator:SI 1 "proper_comparison_operator"
3567 [(reg CC_REG) (const_int 0)])))]
3568 ""
3569 "mov %0,1\;sub.%d1 %0,%0,%0"
3570 [(set_attr "type" "unary")
3571 (set_attr "length" "8")])
3572
3573 ; cond_exec patterns
3574 (define_insn "*movsi_ne"
3575 [(cond_exec
3576 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0))
3577 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w")
3578 (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))]
3579 ""
3580 "@
3581 * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3582 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3583 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3584 mov.ne %0,%1
3585 mov.ne %0,%S1"
3586 [(set_attr "type" "cmove")
3587 (set_attr "iscompact" "true,true,true_limm,false,false")
3588 (set_attr "length" "2,2,6,4,8")
3589 (set_attr "cpu_facility" "*,av2,av2,*,*")])
3590
3591 (define_insn "*movsi_cond_exec"
3592 [(cond_exec
3593 (match_operator 3 "proper_comparison_operator"
3594 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3595 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3596 (match_operand:SI 1 "nonmemory_operand" "Lc,?Cal")))]
3597 ""
3598 "mov.%d3 %0,%S1"
3599 [(set_attr "type" "cmove")
3600 (set_attr "length" "4,8")])
3601
3602 (define_insn "*commutative_cond_exec"
3603 [(cond_exec
3604 (match_operator 5 "proper_comparison_operator"
3605 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3606 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3607 (match_operator:SI 3 "commutative_operator"
3608 [(match_operand:SI 1 "register_operand" "%0,0")
3609 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3610 ""
3611 {
3612 arc_output_commutative_cond_exec (operands, true);
3613 return "";
3614 }
3615 [(set_attr "cond" "use")
3616 (set_attr "type" "cmove")
3617 (set_attr_alternative "length"
3618 [(const_int 4)
3619 (cond
3620 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3621 (const_int 4))
3622 (const_int 4)]
3623 (const_int 8))])])
3624
3625 (define_insn "*sub_cond_exec"
3626 [(cond_exec
3627 (match_operator 4 "proper_comparison_operator"
3628 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3629 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3630 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3631 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3632 ""
3633 "@
3634 sub.%d4 %0,%1,%2
3635 rsub.%d4 %0,%2,%1
3636 rsub.%d4 %0,%2,%1"
3637 [(set_attr "cond" "use")
3638 (set_attr "type" "cmove")
3639 (set_attr "length" "4,4,8")])
3640
3641 (define_insn "*noncommutative_cond_exec"
3642 [(cond_exec
3643 (match_operator 5 "proper_comparison_operator"
3644 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3645 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3646 (match_operator:SI 3 "noncommutative_operator"
3647 [(match_operand:SI 1 "register_operand" "0,0")
3648 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3649 ""
3650 "%O3.%d5 %0,%1,%2"
3651 [(set_attr "cond" "use")
3652 (set_attr "type" "cmove")
3653 (set_attr "length" "4,8")])
3654
3655 ;; These control RTL generation for conditional jump insns
3656 ;; Match both normal and inverted jump.
3657
3658 ; We need a separate expander for this lest we loose the mode of CC_REG
3659 ; when match_operator substitutes the literal operand into the comparison.
3660 (define_expand "branch_insn"
3661 [(set (pc)
3662 (if_then_else (match_operand 1 "" "")
3663 (label_ref (match_operand 0 "" ""))
3664 (pc)))])
3665
3666 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3667 ; are three reasons why we need to consider branches to be length 6:
3668 ; - annull-false delay slot insns are implemented using conditional execution,
3669 ; thus preventing short insn formation where used.
3670 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3671 ; using conditional execution, preventing short insn formation where used.
3672 ; - for ARC700: likely or somewhat likely taken branches are made long and
3673 ; unaligned if possible to avoid branch penalty.
3674 (define_insn "*branch_insn"
3675 [(set (pc)
3676 (if_then_else (match_operator 1 "proper_comparison_operator"
3677 [(reg CC_REG) (const_int 0)])
3678 (label_ref (match_operand 0 "" ""))
3679 (pc)))]
3680 ""
3681 "*
3682 {
3683 if (arc_ccfsm_branch_deleted_p ())
3684 {
3685 arc_ccfsm_record_branch_deleted ();
3686 return \"; branch deleted, next insns conditionalized\";
3687 }
3688 else
3689 {
3690 arc_ccfsm_record_condition (operands[1], false, insn, 0);
3691 if (get_attr_length (insn) == 2)
3692 return \"b%d1%? %^%l0%&\";
3693 else
3694 return \"b%d1%# %^%l0\";
3695 }
3696 }"
3697 [(set_attr "type" "branch")
3698 (set
3699 (attr "length")
3700 (cond [
3701 (eq_attr "delay_slot_filled" "yes")
3702 (const_int 4)
3703
3704 (ne
3705 (if_then_else
3706 (match_operand 1 "equality_comparison_operator" "")
3707 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3708 (gt (minus (match_dup 0) (pc))
3709 (minus (const_int 506)
3710 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3711 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3712 (lt (minus (match_dup 0) (pc)) (const_int -64))
3713 (gt (minus (match_dup 0) (pc))
3714 (minus (const_int 58)
3715 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3716 (const_int 0))
3717 (const_int 4)]
3718 (const_int 2)))
3719
3720 (set (attr "iscompact")
3721 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3722 (const_string "false")))])
3723
3724 (define_insn "*rev_branch_insn"
3725 [(set (pc)
3726 (if_then_else (match_operator 1 "proper_comparison_operator"
3727 [(reg CC_REG) (const_int 0)])
3728 (pc)
3729 (label_ref (match_operand 0 "" ""))))]
3730 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3731 "*
3732 {
3733 if (arc_ccfsm_branch_deleted_p ())
3734 {
3735 arc_ccfsm_record_branch_deleted ();
3736 return \"; branch deleted, next insns conditionalized\";
3737 }
3738 else
3739 {
3740 arc_ccfsm_record_condition (operands[1], true, insn, 0);
3741 if (get_attr_length (insn) == 2)
3742 return \"b%D1%? %^%l0\";
3743 else
3744 return \"b%D1%# %^%l0\";
3745 }
3746 }"
3747 [(set_attr "type" "branch")
3748 (set
3749 (attr "length")
3750 (cond [
3751 (eq_attr "delay_slot_filled" "yes")
3752 (const_int 4)
3753
3754 (ne
3755 (if_then_else
3756 (match_operand 1 "equality_comparison_operator" "")
3757 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3758 (gt (minus (match_dup 0) (pc))
3759 (minus (const_int 506)
3760 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3761 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3762 (lt (minus (match_dup 0) (pc)) (const_int -64))
3763 (gt (minus (match_dup 0) (pc))
3764 (minus (const_int 58)
3765 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3766 (const_int 0))
3767 (const_int 4)]
3768 (const_int 2)))
3769
3770 (set (attr "iscompact")
3771 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3772 (const_string "false")))])
3773
3774 ;; Unconditional and other jump instructions.
3775
3776 (define_expand "jump"
3777 [(set (pc) (label_ref (match_operand 0 "" "")))]
3778 ""
3779 "")
3780
3781 (define_insn "jump_i"
3782 [(set (pc) (label_ref (match_operand 0 "" "")))]
3783 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3784 "b%!%* %^%l0%&"
3785 [(set_attr "type" "uncond_branch")
3786 (set (attr "iscompact")
3787 (if_then_else (match_test "get_attr_length (insn) == 2")
3788 (const_string "true") (const_string "false")))
3789 (set_attr "cond" "canuse")
3790 (set (attr "length")
3791 (cond [
3792 ; In arc_reorg we just guesstimate; might be more or less than 4.
3793 (match_test "arc_branch_size_unknown_p ()")
3794 (const_int 4)
3795
3796 (eq_attr "delay_slot_filled" "yes")
3797 (const_int 4)
3798
3799 (match_test "CROSSING_JUMP_P (insn)")
3800 (const_int 4)
3801
3802 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3803 (gt (minus (match_dup 0) (pc))
3804 (minus (const_int 506)
3805 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3806 (const_int 4)]
3807 (const_int 2)))])
3808
3809 (define_insn "indirect_jump"
3810 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3811 ""
3812 "@
3813 j%!%* %0%&
3814 j%!%* %0%&
3815 j%!%* %0%&
3816 j%!%* [%0]%&
3817 j%!%* [%0]%&"
3818 [(set_attr "type" "jump")
3819 (set_attr "iscompact" "false,false,false,maybe,false")
3820 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3821
3822 ;; Implement a switch statement.
3823
3824 (define_expand "casesi"
3825 [(set (match_dup 5)
3826 (minus:SI (match_operand:SI 0 "register_operand" "")
3827 (match_operand:SI 1 "nonmemory_operand" "")))
3828 (set (reg:CC CC_REG)
3829 (compare:CC (match_dup 5)
3830 (match_operand:SI 2 "nonmemory_operand" "")))
3831 (set (pc)
3832 (if_then_else (gtu (reg:CC CC_REG)
3833 (const_int 0))
3834 (label_ref (match_operand 4 "" ""))
3835 (pc)))
3836 (set (match_dup 6)
3837 (unspec:SI [(match_operand 3 "" "")
3838 (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
3839 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
3840 ""
3841 "
3842 {
3843 rtx x;
3844
3845 operands[5] = gen_reg_rtx (SImode);
3846 operands[6] = gen_reg_rtx (SImode);
3847 operands[7] = operands[3];
3848 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
3849 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
3850 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
3851 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
3852 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
3853 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
3854 if (TARGET_COMPACT_CASESI)
3855 {
3856 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
3857 }
3858 else
3859 {
3860 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3861 if (flag_pic || !cse_not_expected)
3862 operands[3] = force_reg (Pmode, operands[3]);
3863 emit_insn (gen_casesi_load (operands[6],
3864 operands[3], operands[5], operands[7]));
3865 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
3866 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
3867 emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
3868 }
3869 DONE;
3870 }")
3871
3872 (define_insn "casesi_load"
3873 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
3874 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
3875 (match_operand:SI 2 "register_operand" "Rcq,c,c")
3876 (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
3877 ""
3878 "*
3879 {
3880 rtx diff_vec = PATTERN (next_nonnote_insn (operands[3]));
3881
3882 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
3883 {
3884 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
3885 gcc_assert (GET_MODE (diff_vec) == SImode);
3886 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
3887 }
3888
3889 switch (GET_MODE (diff_vec))
3890 {
3891 case SImode:
3892 return \"ld.as %0,[%1,%2]%&\";
3893 case HImode:
3894 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3895 return \"ld%_.as %0,[%1,%2]\";
3896 return \"ld%_.x.as %0,[%1,%2]\";
3897 case QImode:
3898 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3899 return \"ldb%? %0,[%1,%2]%&\";
3900 return \"ldb.x %0,[%1,%2]\";
3901 default:
3902 gcc_unreachable ();
3903 }
3904 }"
3905 [(set_attr "type" "load")
3906 (set_attr_alternative "iscompact"
3907 [(cond
3908 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn (operands[3])))")
3909 (symbol_ref "QImode"))
3910 (const_string "false")
3911 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn (operands[3]))).offset_unsigned")
3912 (const_string "false")]
3913 (const_string "true"))
3914 (const_string "false")
3915 (const_string "false")])
3916 (set_attr_alternative "length"
3917 [(cond
3918 [(eq_attr "iscompact" "false") (const_int 4)
3919 ; We have to mention (match_dup 3) to convince genattrtab.c that this
3920 ; is a varying length insn.
3921 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
3922 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
3923 (const_int 2))
3924 (const_int 4)
3925 (const_int 8)])])
3926
3927 ; Unlike the canonical tablejump, this pattern always uses a jump address,
3928 ; even for CASE_VECTOR_PC_RELATIVE.
3929 (define_insn "casesi_jump"
3930 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
3931 (use (label_ref (match_operand 1 "" "")))]
3932 ""
3933 "j%!%* [%0]%&"
3934 [(set_attr "type" "jump")
3935 (set_attr "iscompact" "false,maybe,false")
3936 (set_attr "cond" "canuse")])
3937
3938 (define_insn "casesi_compact_jump"
3939 [(set (pc)
3940 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
3941 UNSPEC_ARC_CASESI))
3942 (use (label_ref (match_operand 1 "" "")))
3943 (clobber (match_scratch:SI 2 "=q,0"))]
3944 "TARGET_COMPACT_CASESI"
3945 "*
3946 {
3947 rtx diff_vec = PATTERN (next_nonnote_insn (operands[1]));
3948 int unalign = arc_get_unalign ();
3949 rtx xop[3];
3950 const char *s;
3951
3952 xop[0] = operands[0];
3953 xop[2] = operands[2];
3954 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
3955
3956 switch (GET_MODE (diff_vec))
3957 {
3958 case SImode:
3959 /* Max length can be 12 in this case, but this is OK because
3960 2 of these are for alignment, and are anticipated in the length
3961 of the ADDR_DIFF_VEC. */
3962 if (unalign && !satisfies_constraint_Rcq (xop[0]))
3963 s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
3964 else if (unalign)
3965 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
3966 else
3967 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
3968 arc_clear_unalign ();
3969 break;
3970 case HImode:
3971 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3972 {
3973 if (satisfies_constraint_Rcq (xop[0]))
3974 {
3975 s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
3976 xop[1] = GEN_INT ((10 - unalign) / 2U);
3977 }
3978 else
3979 {
3980 s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
3981 xop[1] = GEN_INT (10 + unalign);
3982 }
3983 }
3984 else
3985 {
3986 if (satisfies_constraint_Rcq (xop[0]))
3987 {
3988 s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
3989 xop[1] = GEN_INT ((10 - unalign) / 2U);
3990 }
3991 else
3992 {
3993 s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
3994 xop[1] = GEN_INT (10 + unalign);
3995 }
3996 }
3997 arc_toggle_unalign ();
3998 break;
3999 case QImode:
4000 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4001 {
4002 if ((rtx_equal_p (xop[2], xop[0])
4003 || find_reg_note (insn, REG_DEAD, xop[0]))
4004 && satisfies_constraint_Rcq (xop[0]))
4005 {
4006 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4007 xop[1] = GEN_INT (8 + unalign);
4008 }
4009 else
4010 {
4011 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4012 xop[1] = GEN_INT (10 + unalign);
4013 arc_toggle_unalign ();
4014 }
4015 }
4016 else if ((rtx_equal_p (xop[0], xop[2])
4017 || find_reg_note (insn, REG_DEAD, xop[0]))
4018 && satisfies_constraint_Rcq (xop[0]))
4019 {
4020 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4021 xop[1] = GEN_INT (10 - unalign);
4022 arc_toggle_unalign ();
4023 }
4024 else
4025 {
4026 /* ??? Length is 12. */
4027 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4028 xop[1] = GEN_INT (8 + unalign);
4029 }
4030 break;
4031 default:
4032 gcc_unreachable ();
4033 }
4034 output_asm_insn (s, xop);
4035 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4036 }"
4037 [(set_attr "length" "10")
4038 (set_attr "type" "jump")
4039 (set_attr "iscompact" "true")
4040 (set_attr "cond" "nocond")])
4041
4042 (define_expand "call"
4043 ;; operands[1] is stack_size_rtx
4044 ;; operands[2] is next_arg_register
4045 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4046 (match_operand 1 "" ""))
4047 (clobber (reg:SI 31))])]
4048 ""
4049 "{
4050 rtx callee;
4051
4052 gcc_assert (MEM_P (operands[0]));
4053 callee = XEXP (operands[0], 0);
4054 if (crtl->profile && arc_profile_call (callee))
4055 {
4056 emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
4057 \"_mcount_call\"),
4058 operands[1]));
4059 DONE;
4060 }
4061 /* This is to decide if we should generate indirect calls by loading the
4062 32 bit address of the callee into a register before performing the
4063 branch and link - this exposes cse opportunities.
4064 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4065 if (GET_CODE (callee) != REG
4066 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4067 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4068 }
4069 ")
4070
4071
4072 ; Rcq, which is used in alternative 0, checks for conditional execution.
4073 ; At instruction output time, if it doesn't match and we end up with
4074 ; alternative 1 ("q"), that means that we can't use the short form.
4075 (define_insn "*call_i"
4076 [(call (mem:SI (match_operand:SI 0
4077 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4078 (match_operand 1 "" ""))
4079 (clobber (reg:SI 31))]
4080 ""
4081 "@
4082 jl%!%* [%0]%&
4083 jl%!%* [%0]%&
4084 jl%!%* [%0]
4085 bl%!%* %P0
4086 bl%!%* %P0
4087 jl%!%* %S0
4088 jl%* %S0
4089 jl%! %S0"
4090 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4091 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4092 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4093 (set_attr "length" "*,*,4,4,4,4,4,8")])
4094
4095 (define_insn "call_prof"
4096 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal"))
4097 (match_operand 1 "" ""))
4098 (clobber (reg:SI 31))
4099 (use (reg:SI 8))
4100 (use (reg:SI 9))]
4101 ""
4102 "@
4103 bl%!%* %P0;2
4104 jl%! %^%S0"
4105 [(set_attr "type" "call,call_no_delay_slot")
4106 (set_attr "predicable" "yes,yes")
4107 (set_attr "length" "4,8")])
4108
4109 (define_expand "call_value"
4110 ;; operand 2 is stack_size_rtx
4111 ;; operand 3 is next_arg_register
4112 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4113 (call (match_operand:SI 1 "call_operand" "")
4114 (match_operand 2 "" "")))
4115 (clobber (reg:SI 31))])]
4116 ""
4117 "
4118 {
4119 rtx callee;
4120
4121 gcc_assert (MEM_P (operands[1]));
4122 callee = XEXP (operands[1], 0);
4123 if (crtl->profile && arc_profile_call (callee))
4124 {
4125 emit_call_insn (gen_call_value_prof (operands[0],
4126 gen_rtx_SYMBOL_REF (Pmode,
4127 \"_mcount_call\"),
4128 operands[2]));
4129 DONE;
4130 }
4131 /* See the comment in define_expand \"call\". */
4132 if (GET_CODE (callee) != REG
4133 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4134 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4135 }")
4136
4137
4138 ; Rcq, which is used in alternative 0, checks for conditional execution.
4139 ; At instruction output time, if it doesn't match and we end up with
4140 ; alternative 1 ("q"), that means that we can't use the short form.
4141 (define_insn "*call_value_i"
4142 [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w,w,w, w")
4143 (call (mem:SI (match_operand:SI 1
4144 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4145 (match_operand 2 "" "")))
4146 (clobber (reg:SI 31))]
4147 ""
4148 "@
4149 jl%!%* [%1]%&
4150 jl%!%* [%1]%&
4151 jl%!%* [%1]
4152 bl%!%* %P1;1
4153 bl%!%* %P1;1
4154 jl%!%* %S1
4155 jl%* %S1
4156 jl%! %S1"
4157 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4158 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4159 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4160 (set_attr "length" "*,*,4,4,4,4,4,8")])
4161
4162 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4163 ; use it for lack of inter-procedural branch shortening.
4164 ; Link-time relaxation would help...
4165
4166
4167 (define_insn "call_value_prof"
4168 [(set (match_operand 0 "dest_reg_operand" "=r,r")
4169 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal"))
4170 (match_operand 2 "" "")))
4171 (clobber (reg:SI 31))
4172 (use (reg:SI 8))
4173 (use (reg:SI 9))]
4174 ""
4175 "@
4176 bl%!%* %P1;1
4177 jl%! %^%S1"
4178 [(set_attr "type" "call,call_no_delay_slot")
4179 (set_attr "predicable" "yes,yes")
4180 (set_attr "length" "4,8")])
4181
4182 (define_insn "nop"
4183 [(const_int 0)]
4184 ""
4185 "nop%?"
4186 [(set_attr "type" "misc")
4187 (set_attr "iscompact" "true")
4188 (set_attr "cond" "canuse")
4189 (set_attr "length" "2")])
4190
4191 (define_insn "nopv"
4192 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4193 ""
4194 "nop%?"
4195 [(set_attr "type" "misc")
4196 (set_attr "iscompact" "true")
4197 (set_attr "length" "2")])
4198
4199 ;; Special pattern to flush the icache.
4200 ;; ??? Not sure what to do here. Some ARC's are known to support this.
4201
4202 (define_insn "flush_icache"
4203 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4204 ""
4205 "* return \"\";"
4206 [(set_attr "type" "misc")])
4207
4208 ;; Split up troublesome insns for better scheduling.
4209
4210 ;; Peepholes go at the end.
4211 ;;asl followed by add can be replaced by an add{1,2,3}
4212 ;; Three define_peepholes have been added for this optimization
4213 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4214 ;; can be generated by combine. Check if these peepholes still provide
4215 ;; any benefit.
4216
4217 ;; -------------------------------------------------------------
4218 ;; Pattern 1 : r0 = r1 << {i}
4219 ;; r3 = r4/INT + r0 ;;and commutative
4220 ;; ||
4221 ;; \/
4222 ;; add{i} r3,r4/INT,r1
4223 ;; -------------------------------------------------------------
4224 ;; ??? This should be covered by combine, alas, at times combine gets
4225 ;; too clever for it's own good: when the shifted input is known to be
4226 ;; either 0 or 1, the operation will be made into an if-then-else, and
4227 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4228 ;; newlib/libc/time/mktm_r.c .
4229
4230 (define_peephole2
4231 [(set (match_operand:SI 0 "dest_reg_operand" "")
4232 (ashift:SI (match_operand:SI 1 "register_operand" "")
4233 (match_operand:SI 2 "const_int_operand" "")))
4234 (set (match_operand:SI 3 "dest_reg_operand" "")
4235 (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4236 (match_operand:SI 5 "nonmemory_operand" "")))]
4237 "(INTVAL (operands[2]) == 1
4238 || INTVAL (operands[2]) == 2
4239 || INTVAL (operands[2]) == 3)
4240 && (true_regnum (operands[4]) == true_regnum (operands[0])
4241 || true_regnum (operands[5]) == true_regnum (operands[0]))
4242 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4243 ;; the preparation statements take care to put proper operand in operands[4]
4244 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4245 [(set (match_dup 3)
4246 (plus:SI (mult:SI (match_dup 1)
4247 (match_dup 2))
4248 (match_dup 4)))]
4249 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4250 operands[4] = operands[5];
4251 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4252 )
4253
4254 ;; -------------------------------------------------------------
4255 ;; Pattern 1 : r0 = r1 << {i}
4256 ;; r3 = r4 - r0
4257 ;; ||
4258 ;; \/
4259 ;; sub{i} r3,r4,r1
4260 ;; -------------------------------------------------------------
4261 ;; ??? This should be covered by combine, alas, at times combine gets
4262 ;; too clever for it's own good: when the shifted input is known to be
4263 ;; either 0 or 1, the operation will be made into an if-then-else, and
4264 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4265 ;; newlib/libm/math/e_jn.c .
4266
4267 (define_peephole2
4268 [(set (match_operand:SI 0 "dest_reg_operand" "")
4269 (ashift:SI (match_operand:SI 1 "register_operand" "")
4270 (match_operand:SI 2 "const_int_operand" "")))
4271 (set (match_operand:SI 3 "dest_reg_operand" "")
4272 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4273 (match_dup 0)))]
4274 "(INTVAL (operands[2]) == 1
4275 || INTVAL (operands[2]) == 2
4276 || INTVAL (operands[2]) == 3)
4277 && (peep2_reg_dead_p (2, operands[0])
4278 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4279 [(set (match_dup 3)
4280 (minus:SI (match_dup 4)
4281 (mult:SI (match_dup 1)
4282 (match_dup 2))))]
4283 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4284 )
4285
4286
4287
4288 ; When using the high single bit, the result of a multiply is either
4289 ; the original number or zero. But MPY costs 4 cycles, which we
4290 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4291 (define_peephole2
4292 [(set (match_operand:SI 0 "dest_reg_operand" "")
4293 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4294 (const_int 31)))
4295 (set (match_operand:SI 4 "register_operand" "")
4296 (mult:SI (match_operand:SI 2 "register_operand")
4297 (match_operand:SI 3 "nonmemory_operand" "")))]
4298 "TARGET_ARC700_MPY
4299 && (rtx_equal_p (operands[0], operands[2])
4300 || rtx_equal_p (operands[0], operands[3]))
4301 && peep2_regno_dead_p (0, CC_REG)
4302 && (rtx_equal_p (operands[0], operands[4])
4303 || (peep2_reg_dead_p (2, operands[0])
4304 && peep2_reg_dead_p (1, operands[4])))"
4305 [(parallel [(set (reg:CC_Z CC_REG)
4306 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4307 (const_int 0)))
4308 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4309 (cond_exec
4310 (ne (reg:CC_Z CC_REG) (const_int 0))
4311 (set (match_dup 4) (match_dup 5)))]
4312 {
4313 if (!rtx_equal_p (operands[0], operands[2]))
4314 operands[5] = operands[2];
4315 else if (!rtx_equal_p (operands[0], operands[3]))
4316 operands[5] = operands[3];
4317 else
4318 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4319 })
4320
4321 (define_peephole2
4322 [(set (match_operand:SI 0 "dest_reg_operand" "")
4323 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4324 (const_int 31)))
4325 (set (match_operand:SI 4 "register_operand" "")
4326 (mult:SI (match_operand:SI 2 "register_operand")
4327 (match_operand:SI 3 "nonmemory_operand" "")))]
4328 "TARGET_ARC700_MPY
4329 && (rtx_equal_p (operands[0], operands[2])
4330 || rtx_equal_p (operands[0], operands[3]))
4331 && peep2_regno_dead_p (2, CC_REG)"
4332 [(parallel [(set (reg:CC_Z CC_REG)
4333 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4334 (const_int 0)))
4335 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4336 (set (match_dup 4) (match_dup 5))
4337 (cond_exec
4338 (eq (reg:CC_Z CC_REG) (const_int 0))
4339 (set (match_dup 4) (const_int 0)))]
4340 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4341
4342 ;; Instructions generated through builtins
4343
4344 (define_insn "clrsbsi2"
4345 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4346 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4347 "TARGET_NORM"
4348 "@
4349 norm \t%0, %1
4350 norm \t%0, %S1"
4351 [(set_attr "length" "4,8")
4352 (set_attr "type" "two_cycle_core,two_cycle_core")])
4353
4354 (define_insn "norm_f"
4355 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4356 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4357 (set (reg:CC_ZN CC_REG)
4358 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4359 "TARGET_NORM"
4360 "@
4361 norm.f\t%0, %1
4362 norm.f\t%0, %S1"
4363 [(set_attr "length" "4,8")
4364 (set_attr "type" "two_cycle_core,two_cycle_core")])
4365
4366 (define_insn_and_split "clrsbhi2"
4367 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4368 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4369 "TARGET_NORM"
4370 "#"
4371 "reload_completed"
4372 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4373 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4374
4375 (define_insn "normw"
4376 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4377 (zero_extend:SI
4378 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4379 "TARGET_NORM"
4380 "@
4381 norm%_ \t%0, %1
4382 norm%_ \t%0, %S1"
4383 [(set_attr "length" "4,8")
4384 (set_attr "type" "two_cycle_core,two_cycle_core")])
4385
4386 (define_expand "clzsi2"
4387 [(set (match_operand:SI 0 "dest_reg_operand" "")
4388 (clz:SI (match_operand:SI 1 "register_operand" "")))]
4389 "TARGET_NORM"
4390 {
4391 emit_insn (gen_norm_f (operands[0], operands[1]));
4392 emit_insn
4393 (gen_rtx_COND_EXEC
4394 (VOIDmode,
4395 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4396 gen_rtx_SET (operands[0], const0_rtx)));
4397 emit_insn
4398 (gen_rtx_COND_EXEC
4399 (VOIDmode,
4400 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4401 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4402 DONE;
4403 })
4404
4405 (define_expand "ctzsi2"
4406 [(set (match_operand:SI 0 "register_operand" "")
4407 (ctz:SI (match_operand:SI 1 "register_operand" "")))]
4408 "TARGET_NORM"
4409 {
4410 rtx temp = operands[0];
4411
4412 if (reg_overlap_mentioned_p (temp, operands[1])
4413 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4414 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4415 REGNO (temp))))
4416 temp = gen_reg_rtx (SImode);
4417 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4418 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4419 emit_insn (gen_clrsbsi2 (temp, temp));
4420 emit_insn
4421 (gen_rtx_COND_EXEC
4422 (VOIDmode,
4423 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4424 gen_rtx_SET (operands[0], GEN_INT (32))));
4425 emit_insn
4426 (gen_rtx_COND_EXEC
4427 (VOIDmode,
4428 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4429 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31), temp))));
4430 DONE;
4431 })
4432
4433
4434 (define_insn "swap"
4435 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4436 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4437 UNSPEC_ARC_SWAP))]
4438 "TARGET_SWAP"
4439 "@
4440 swap \t%0, %1
4441 swap \t%0, %S1
4442 swap \t%0, %1"
4443 [(set_attr "length" "4,8,4")
4444 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4445
4446 (define_insn "divaw"
4447 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4448 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4449 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4450 UNSPEC_ARC_DIVAW))]
4451 "TARGET_ARC700 || TARGET_EA_SET"
4452 "@
4453 divaw \t%0, %1, %2
4454 divaw \t%0, %S1, %2
4455 divaw \t%0, %1, %S2"
4456 [(set_attr "length" "4,8,8")
4457 (set_attr "type" "divaw,divaw,divaw")])
4458
4459 (define_insn "flag"
4460 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4461 VUNSPEC_ARC_FLAG)]
4462 ""
4463 "@
4464 flag%? %0
4465 flag %0
4466 flag%? %S0"
4467 [(set_attr "length" "4,4,8")
4468 (set_attr "type" "misc,misc,misc")
4469 (set_attr "predicable" "yes,no,yes")
4470 (set_attr "cond" "clob,clob,clob")])
4471
4472 (define_insn "brk"
4473 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4474 VUNSPEC_ARC_BRK)]
4475 ""
4476 "brk"
4477 [(set_attr "length" "4")
4478 (set_attr "type" "misc")])
4479
4480 (define_insn "rtie"
4481 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4482 VUNSPEC_ARC_RTIE)]
4483 ""
4484 "rtie"
4485 [(set_attr "length" "4")
4486 (set_attr "type" "misc")
4487 (set_attr "cond" "clob")])
4488
4489 (define_insn "sync"
4490 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4491 VUNSPEC_ARC_SYNC)]
4492 ""
4493 "sync"
4494 [(set_attr "length" "4")
4495 (set_attr "type" "misc")])
4496
4497 (define_insn "swi"
4498 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4499 VUNSPEC_ARC_SWI)]
4500 ""
4501 "*
4502 {
4503 if(TARGET_ARC700)
4504 return \"trap0\";
4505 else
4506 return \"swi\";
4507 }"
4508 [(set_attr "length" "4")
4509 (set_attr "type" "misc")])
4510
4511
4512 (define_insn "sleep"
4513 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4514 VUNSPEC_ARC_SLEEP)]
4515 "check_if_valid_sleep_operand(operands,0)"
4516 "sleep %0"
4517 [(set_attr "length" "4")
4518 (set_attr "type" "misc")])
4519
4520 (define_insn "core_read"
4521 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4522 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4523 VUNSPEC_ARC_CORE_READ))]
4524 ""
4525 "*
4526 if (check_if_valid_regno_const (operands, 1))
4527 return \"mov \t%0, r%1\";
4528 return \"mov \t%0, r%1\";
4529 "
4530 [(set_attr "length" "4")
4531 (set_attr "type" "unary")])
4532
4533 (define_insn "core_write"
4534 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4535 (match_operand:SI 1 "general_operand" "Hn,!r")]
4536 VUNSPEC_ARC_CORE_WRITE)]
4537 ""
4538 "*
4539 if (check_if_valid_regno_const (operands, 1))
4540 return \"mov \tr%1, %0\";
4541 return \"mov \tr%1, %0\";
4542 "
4543 [(set_attr "length" "4")
4544 (set_attr "type" "unary")])
4545
4546 (define_insn "lr"
4547 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4548 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4549 VUNSPEC_ARC_LR))]
4550 ""
4551 "lr\t%0, [%1]"
4552 [(set_attr "length" "4,8,4,8")
4553 (set_attr "type" "lr,lr,lr,lr")])
4554
4555 (define_insn "sr"
4556 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4557 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4558 VUNSPEC_ARC_SR)]
4559 ""
4560 "sr\t%S0, [%1]"
4561 [(set_attr "length" "8,4,8,4")
4562 (set_attr "type" "sr,sr,sr,sr")])
4563
4564 (define_insn "trap_s"
4565 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4566 VUNSPEC_ARC_TRAP_S)]
4567 "!TARGET_ARC600_FAMILY"
4568 {
4569 if (which_alternative == 0)
4570 {
4571 arc_toggle_unalign ();
4572 return \"trap_s %0\";
4573 }
4574
4575 /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4576 because *.md files do not get scanned by exgettext. */
4577 fatal_error (input_location,
4578 \"operand to trap_s should be an unsigned 6-bit value\");
4579 }
4580 [(set_attr "length" "2")
4581 (set_attr "type" "misc")])
4582
4583 (define_insn "unimp_s"
4584 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4585 VUNSPEC_ARC_UNIMP_S)]
4586 "!TARGET_ARC600_FAMILY"
4587 "unimp_s"
4588 [(set_attr "length" "4")
4589 (set_attr "type" "misc")])
4590
4591 ;; End of instructions generated through builtins
4592
4593 ; Since the demise of REG_N_SETS as reliable data readily available to the
4594 ; target, it is no longer possible to find out
4595 ; in the prologue / epilogue expanders how many times blink is set.
4596 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4597 ; any explicit use of blink will cause it to be saved; hence we cannot
4598 ; represent the blink use in return / sibcall instructions themselves, and
4599 ; instead have to show it in EPILOGUE_USES and must explicitly
4600 ; forbid instructions that change blink in the return / sibcall delay slot.
4601 (define_expand "sibcall"
4602 [(parallel [(call (match_operand 0 "memory_operand" "")
4603 (match_operand 1 "general_operand" ""))
4604 (simple_return)
4605 (use (match_operand 2 "" ""))])]
4606 ""
4607 "
4608 {
4609 rtx callee = XEXP (operands[0], 0);
4610
4611 if (operands[2] == NULL_RTX)
4612 operands[2] = const0_rtx;
4613 if (crtl->profile && arc_profile_call (callee))
4614 {
4615 emit_insn (gen_sibcall_prof
4616 (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4617 operands[1], operands[2]));
4618 DONE;
4619 }
4620 if (GET_CODE (callee) != REG
4621 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4622 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4623 }"
4624 )
4625
4626 (define_expand "sibcall_value"
4627 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4628 (call (match_operand 1 "memory_operand" "")
4629 (match_operand 2 "general_operand" "")))
4630 (simple_return)
4631 (use (match_operand 3 "" ""))])]
4632 ""
4633 "
4634 {
4635 rtx callee = XEXP (operands[1], 0);
4636
4637 if (operands[3] == NULL_RTX)
4638 operands[3] = const0_rtx;
4639 if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
4640 {
4641 emit_insn (gen_sibcall_value_prof
4642 (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4643 operands[2], operands[3]));
4644 DONE;
4645 }
4646 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4647 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4648 }"
4649 )
4650
4651 (define_insn "*sibcall_insn"
4652 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4653 "Cbp,Cbr,Rs5,Rsc,Cal"))
4654 (match_operand 1 "" ""))
4655 (simple_return)
4656 (use (match_operand 2 "" ""))]
4657 ""
4658 "@
4659 b%!%* %P0
4660 b%!%* %P0
4661 j%!%* [%0]%&
4662 j%!%* [%0]
4663 j%! %P0"
4664 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4665 (set_attr "predicable" "yes,no,no,yes,yes")
4666 (set_attr "iscompact" "false,false,maybe,false,false")
4667 (set_attr "is_SIBCALL" "yes")]
4668 )
4669
4670 (define_insn "*sibcall_value_insn"
4671 [(set (match_operand 0 "dest_reg_operand" "")
4672 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4673 "Cbp,Cbr,Rs5,Rsc,Cal"))
4674 (match_operand 2 "" "")))
4675 (simple_return)
4676 (use (match_operand 3 "" ""))]
4677 ""
4678 "@
4679 b%!%* %P1
4680 b%!%* %P1
4681 j%!%* [%1]%&
4682 j%!%* [%1]
4683 j%! %P1"
4684 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4685 (set_attr "predicable" "yes,no,no,yes,yes")
4686 (set_attr "iscompact" "false,false,maybe,false,false")
4687 (set_attr "is_SIBCALL" "yes")]
4688 )
4689
4690 (define_insn "sibcall_prof"
4691 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal"))
4692 (match_operand 1 "" ""))
4693 (simple_return)
4694 (use (match_operand 2 "" ""))
4695 (use (reg:SI 8))
4696 (use (reg:SI 9))]
4697 ""
4698 "@
4699 b%!%* %P0;2
4700 j%! %^%S0;2"
4701 [(set_attr "type" "call,call_no_delay_slot")
4702 (set_attr "predicable" "yes")
4703 (set_attr "is_SIBCALL" "yes")]
4704 )
4705
4706 (define_insn "sibcall_value_prof"
4707 [(set (match_operand 0 "dest_reg_operand" "")
4708 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal"))
4709 (match_operand 2 "" "")))
4710 (simple_return)
4711 (use (match_operand 3 "" ""))
4712 (use (reg:SI 8))
4713 (use (reg:SI 9))]
4714 ""
4715 "@
4716 b%!%* %P1;1
4717 j%! %^%S1;1"
4718 [(set_attr "type" "call,call_no_delay_slot")
4719 (set_attr "predicable" "yes")
4720 (set_attr "is_SIBCALL" "yes")]
4721 )
4722
4723 (define_expand "prologue"
4724 [(pc)]
4725 ""
4726 {
4727 arc_expand_prologue ();
4728 DONE;
4729 })
4730
4731 (define_expand "epilogue"
4732 [(pc)]
4733 ""
4734 {
4735 arc_expand_epilogue (0);
4736 DONE;
4737 })
4738
4739 (define_expand "sibcall_epilogue"
4740 [(pc)]
4741 ""
4742 {
4743 arc_expand_epilogue (1);
4744 DONE;
4745 })
4746
4747 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4748 ; in the prologue / epilogue expanders how many times blink is set.
4749 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4750 ; any explicit use of blink will cause it to be saved; hence we cannot
4751 ; represent the blink use in return / sibcall instructions themselves, and
4752 ; instead have to show it in EPILOGUE_USES and must explicitly
4753 ; forbid instructions that change blink in the return / sibcall delay slot.
4754 (define_insn "simple_return"
4755 [(simple_return)]
4756 "reload_completed"
4757 {
4758 rtx reg
4759 = gen_rtx_REG (Pmode,
4760 arc_return_address_regs[arc_compute_function_type (cfun)]);
4761
4762 if (arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1
4763 && TARGET_V2)
4764 {
4765 return \"rtie\";
4766 }
4767 if (TARGET_PAD_RETURN)
4768 arc_pad_return ();
4769 output_asm_insn (\"j%!%* [%0]%&\", &reg);
4770 return \"\";
4771 }
4772 [(set_attr "type" "return")
4773 ; predicable won't help here since the canonical rtl looks different
4774 ; for branches.
4775 (set (attr "cond")
4776 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4777 (symbol_ref "ARC_FUNCTION_ILINK1"))
4778 (match_test "TARGET_V2"))
4779 (const_string "nocond")]
4780 (const_string "canuse")))
4781 (set (attr "iscompact")
4782 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4783 (symbol_ref "ARC_FUNCTION_NORMAL"))
4784 (const_string "maybe")]
4785 (const_string "false")))
4786 (set (attr "length")
4787 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4788 (symbol_ref "ARC_FUNCTION_NORMAL"))
4789 (const_int 4)]
4790 (const_int 2)))])
4791
4792 (define_insn "p_return_i"
4793 [(set (pc)
4794 (if_then_else (match_operator 0 "proper_comparison_operator"
4795 [(reg CC_REG) (const_int 0)])
4796 (simple_return) (pc)))]
4797 "reload_completed
4798 && !(TARGET_V2
4799 && arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1)"
4800 {
4801 rtx xop[2];
4802 xop[0] = operands[0];
4803 xop[1]
4804 = gen_rtx_REG (Pmode,
4805 arc_return_address_regs[arc_compute_function_type (cfun)]);
4806
4807 if (TARGET_PAD_RETURN)
4808 arc_pad_return ();
4809 output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4810 /* record the condition in case there is a delay insn. */
4811 arc_ccfsm_record_condition (xop[0], false, insn, 0);
4812 return \"\";
4813 }
4814 [(set_attr "type" "return")
4815 (set_attr "cond" "use")
4816 (set (attr "iscompact")
4817 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4818 (symbol_ref "ARC_FUNCTION_NORMAL"))
4819 (const_string "maybe")]
4820 (const_string "false")))
4821 (set (attr "length")
4822 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4823 (symbol_ref "ARC_FUNCTION_NORMAL"))
4824 (const_int 4)
4825 (not (match_operand 0 "equality_comparison_operator" ""))
4826 (const_int 4)
4827 (eq_attr "delay_slot_filled" "yes")
4828 (const_int 4)]
4829 (const_int 2)))])
4830
4831 (define_insn_and_split "eh_return"
4832 [(eh_return)
4833 (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4834 (clobber (match_scratch:SI 1 "=X,r"))
4835 (clobber (match_scratch:SI 2 "=&r,r"))]
4836 ""
4837 "#"
4838 "reload_completed"
4839 [(set (match_dup 2) (match_dup 0))]
4840 {
4841 int offs = arc_return_slot_offset ();
4842
4843 if (offs < 0)
4844 operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4845 else
4846 {
4847 if (!register_operand (operands[0], Pmode)
4848 && !satisfies_constraint_C32 (operands[0]))
4849 {
4850 emit_move_insn (operands[1], operands[0]);
4851 operands[0] = operands[1];
4852 }
4853 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4854 if (!strict_memory_address_p (Pmode, addr))
4855 {
4856 emit_move_insn (operands[2], addr);
4857 addr = operands[2];
4858 }
4859 operands[2] = gen_frame_mem (Pmode, addr);
4860 }
4861 }
4862 [(set_attr "length" "12")])
4863
4864 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4865 ;; non-constant predicate.
4866 (define_expand "return"
4867 [(return)]
4868 "optimize < 0")
4869
4870 ;; Comment in final.c (insn_current_reference_address) says
4871 ;; forward branch addresses are calculated from the next insn after branch
4872 ;; and for backward branches, it is calculated from the branch insn start.
4873 ;; The shortening logic here is tuned to accomodate this behavior
4874 ;; ??? This should be grokked by the ccfsm machinery.
4875 (define_insn "cbranchsi4_scratch"
4876 [(set (pc)
4877 (if_then_else (match_operator 0 "proper_comparison_operator"
4878 [(match_operand:SI 1 "register_operand" "c,c, c")
4879 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4880 (label_ref (match_operand 3 "" ""))
4881 (pc)))
4882 (clobber (match_operand 4 "cc_register" ""))]
4883 "(reload_completed
4884 || (TARGET_EARLY_CBRANCHSI
4885 && brcc_nolimm_operator (operands[0], VOIDmode)))
4886 && !CROSSING_JUMP_P (insn)"
4887 "*
4888 switch (get_attr_length (insn))
4889 {
4890 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4891 case 4: return \"br%d0%* %1, %B2, %^%l3\";
4892 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4893 return \"br%d0%* %1, %B2, %^%l3\";
4894 case 6: case 10:
4895 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\";
4896 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4897 }
4898 "
4899 [(set_attr "cond" "clob, clob, clob")
4900 (set (attr "type")
4901 (if_then_else
4902 (match_test "valid_brcc_with_delay_p (operands)")
4903 (const_string "brcc")
4904 (const_string "brcc_no_delay_slot")))
4905 ; For forward branches, we need to account not only for the distance to
4906 ; the target, but also the difference between pcl and pc, the instruction
4907 ; length, and any delay insn, if present.
4908 (set
4909 (attr "length")
4910 (cond ; the outer cond does a test independent of branch shortening.
4911 [(match_operand 0 "brcc_nolimm_operator" "")
4912 (cond
4913 [(and (match_operand:CC_Z 4 "cc_register")
4914 (eq_attr "delay_slot_filled" "no")
4915 (ge (minus (match_dup 3) (pc)) (const_int -128))
4916 (le (minus (match_dup 3) (pc))
4917 (minus (const_int 122)
4918 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4919 (const_int 2)
4920 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4921 (le (minus (match_dup 3) (pc))
4922 (minus (const_int 244)
4923 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4924 (const_int 4)
4925 (match_operand:SI 1 "compact_register_operand" "")
4926 (const_int 6)]
4927 (const_int 8))]
4928 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
4929 (le (minus (match_dup 3) (pc)) (const_int 244)))
4930 (const_int 8)
4931 (match_operand:SI 1 "compact_register_operand" "")
4932 (const_int 10)]
4933 (const_int 12))))
4934 (set (attr "iscompact")
4935 (if_then_else (match_test "get_attr_length (insn) & 2")
4936 (const_string "true") (const_string "false")))])
4937
4938 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
4939 (define_insn "*bbit"
4940 [(set (pc)
4941 (if_then_else
4942 (match_operator 3 "equality_comparison_operator"
4943 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
4944 (const_int 1)
4945 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
4946 (const_int 0)])
4947 (label_ref (match_operand 0 "" ""))
4948 (pc)))
4949 (clobber (reg:CC_ZN CC_REG))]
4950 "!CROSSING_JUMP_P (insn)"
4951 {
4952 switch (get_attr_length (insn))
4953 {
4954 case 4: return (GET_CODE (operands[3]) == EQ
4955 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
4956 case 6:
4957 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
4958 default: gcc_unreachable ();
4959 }
4960 }
4961 [(set_attr "type" "brcc")
4962 (set_attr "cond" "clob")
4963 (set (attr "length")
4964 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
4965 (le (minus (match_dup 0) (pc))
4966 (minus (const_int 248)
4967 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4968 (const_int 4)
4969 (eq (symbol_ref "which_alternative") (const_int 0))
4970 (const_int 6)]
4971 (const_int 8)))
4972 (set (attr "iscompact")
4973 (if_then_else (match_test "get_attr_length (insn) == 6")
4974 (const_string "true") (const_string "false")))])
4975
4976 ; ??? When testing a bit from a DImode register, combine creates a
4977 ; zero_extract in DImode. This goes via an AND with a DImode constant,
4978 ; so can only be observed on 64 bit hosts.
4979 (define_insn_and_split "*bbit_di"
4980 [(set (pc)
4981 (if_then_else
4982 (match_operator 3 "equality_comparison_operator"
4983 [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
4984 (const_int 1)
4985 (match_operand 2 "immediate_operand" "L,L"))
4986 (const_int 0)])
4987 (label_ref (match_operand 0 "" ""))
4988 (pc)))
4989 (clobber (reg:CC_ZN CC_REG))]
4990 "!CROSSING_JUMP_P (insn)"
4991 "#"
4992 ""
4993 [(parallel
4994 [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
4995 (clobber (reg:CC_ZN CC_REG))])]
4996 {
4997 rtx xtr;
4998
4999 xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
5000 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
5001 xtr, const0_rtx);
5002 })
5003
5004 ; operand 0 is the loop count pseudo register
5005 ; operand 1 is the loop end pattern
5006 (define_expand "doloop_begin"
5007 [(use (match_operand 0 "register_operand" ""))
5008 (use (match_operand 1 "" ""))]
5009 ""
5010 {
5011 /* Using the INSN_UID of the loop end pattern to identify it causes
5012 trouble with -fcompare-debug, so allocate a debug-independent
5013 id instead. We use negative numbers so that we can use the same
5014 slot in doloop_end_i where we later store a CODE_LABEL_NUMBER, and
5015 still be able to tell what kind of number this is. */
5016 static HOST_WIDE_INT loop_end_id = 0;
5017
5018 rtx id = GEN_INT (--loop_end_id);
5019 XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
5020 emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
5021 const0_rtx, const0_rtx));
5022 DONE;
5023 })
5024
5025 ; ??? can't describe the insn properly as then the optimizers try to
5026 ; hoist the SETs.
5027 ;(define_insn "doloop_begin_i"
5028 ; [(set (reg:SI LP_START) (pc))
5029 ; (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_ARC_LP))
5030 ; (use (match_operand 0 "const_int_operand" "n"))]
5031 ; ""
5032 ; "lp .L__GCC__LP%0"
5033 ;)
5034
5035 ; The operands of doloop_end_i are also read / written by arc_reorg with
5036 ; XVECEXP (PATTERN (lp, 0, N), so if you want to change the pattern, you
5037 ; might have to adjust arc_reorg.
5038 ; operands 0 / 2 are supplied by the expander, 1, 3 and 4 are filled in
5039 ; by arc_reorg. arc_reorg might also alter operand 0.
5040 ;
5041 ; N in XVECEXP PATTERN (lp, 0 N)
5042 ; V rtl purpose
5043 ; 0 unspec UNSPEC_ARC_LP identify pattern
5044 ; 1 clobber LP_START show LP_START is set
5045 ; 2 clobber LP_END show LP_END is set
5046 ; 3 use operand0 loop count pseudo register
5047 ; 4 use operand1 before arc_reorg: -id
5048 ; after : CODE_LABEL_NUMBER of loop top label
5049 ; 5 use operand2 INSN_UID of loop end insn
5050 ; 6 use operand3 loop setup not at start (1 above, 2 below)
5051 ; 7 use operand4 LABEL_REF of top label, if not
5052 ; immediately following
5053 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
5054 ; instruction that was not at the start of the loop.
5055 ; There is no point is reloading this insn - then lp_count would still not
5056 ; be available for the loop end.
5057 (define_insn "doloop_begin_i"
5058 [(unspec:SI [(pc)] UNSPEC_ARC_LP)
5059 (clobber (reg:SI LP_START))
5060 (clobber (reg:SI LP_END))
5061 (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
5062 (use (match_operand 1 "const_int_operand" "n,n,C_0"))
5063 (use (match_operand 2 "const_int_operand" "n,n,X"))
5064 (use (match_operand 3 "const_int_operand" "C_0,n,X"))
5065 (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
5066 ""
5067 {
5068 rtx_insn *scan;
5069 int len, size = 0;
5070 int n_insns = 0;
5071 rtx loop_start = operands[4];
5072
5073 if (CONST_INT_P (loop_start))
5074 loop_start = NULL_RTX;
5075 /* Size implications of the alignment will be taken care of by the
5076 alignment inserted at the loop start. */
5077 if (LOOP_ALIGN (0) && INTVAL (operands[1]))
5078 {
5079 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5080 arc_clear_unalign ();
5081 }
5082 if (!INTVAL (operands[1]))
5083 return "; LITTLE LOST LOOP";
5084 if (loop_start && flag_pic)
5085 {
5086 /* ??? Can do better for when a scratch register
5087 is known. But that would require extra testing. */
5088 return "push_s r0\;add r0,pcl,%4-(.&-4)\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-(.&-4)\;sr r0,[3]; LP_END\;pop_s r0";
5089 }
5090 /* Check if the loop end is in range to be set by the lp instruction. */
5091 size = INTVAL (operands[3]) < 2 ? 0 : 2048;
5092 for (scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
5093 {
5094 if (!INSN_P (scan))
5095 continue;
5096 if (recog_memoized (scan) == CODE_FOR_doloop_end_i
5097 && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
5098 == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
5099 break;
5100 len = get_attr_length (scan);
5101 size += len;
5102 }
5103 /* Try to verify that there are at least three instruction fetches
5104 between the loop setup and the first encounter of the loop end. */
5105 for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
5106 {
5107 if (!INSN_P (scan))
5108 continue;
5109 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (scan)))
5110 scan = seq->insn (0);
5111 if (JUMP_P (scan))
5112 {
5113 if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
5114 {
5115 n_insns += 2;
5116 if (simplejump_p (scan))
5117 {
5118 scan = as_a <rtx_insn *> (XEXP (SET_SRC (PATTERN (scan)), 0));
5119 continue;
5120 }
5121 if (JUMP_LABEL (scan)
5122 /* JUMP_LABEL might be simple_return instead if an insn. */
5123 && (!INSN_P (JUMP_LABEL (scan))
5124 || (!next_active_insn (JUMP_LABEL (scan))
5125 || (recog_memoized (next_active_insn (JUMP_LABEL (scan)))
5126 != CODE_FOR_doloop_begin_i)))
5127 && (!next_active_insn (NEXT_INSN (PREV_INSN (scan)))
5128 || (recog_memoized
5129 (next_active_insn (NEXT_INSN (PREV_INSN (scan))))
5130 != CODE_FOR_doloop_begin_i)))
5131 n_insns++;
5132 }
5133 break;
5134 }
5135 len = get_attr_length (scan);
5136 /* Size estimation of asms assumes that each line which is nonempty
5137 codes an insn, and that each has a long immediate. For minimum insn
5138 count, assume merely that a nonempty asm has at least one insn. */
5139 if (GET_CODE (PATTERN (scan)) == ASM_INPUT
5140 || asm_noperands (PATTERN (scan)) >= 0)
5141 n_insns += (len != 0);
5142 else
5143 n_insns += (len > 4 ? 2 : (len ? 1 : 0));
5144 }
5145 if (LOOP_ALIGN (0))
5146 {
5147 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5148 arc_clear_unalign ();
5149 }
5150 gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
5151 if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
5152 {
5153 if (flag_pic)
5154 {
5155 /* ??? Can do better for when a scratch register
5156 is known. But that would require extra testing. */
5157 arc_clear_unalign ();
5158 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";
5159 }
5160 output_asm_insn ((size < 2048
5161 ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
5162 operands);
5163 output_asm_insn (loop_start
5164 ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
5165 operands);
5166 if (TARGET_ARC600 && n_insns < 1)
5167 output_asm_insn ("nop", operands);
5168 return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
5169 }
5170 else if (TARGET_ARC600 && n_insns < 3)
5171 {
5172 /* At least four instructions are needed between the setting of LP_COUNT
5173 and the loop end - but the lp instruction qualifies as one. */
5174 rtx_insn *prev = prev_nonnote_insn (insn);
5175
5176 if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
5177 output_asm_insn ("nop", operands);
5178 }
5179 return "lp .L__GCC__LP%1";
5180 }
5181 [(set_attr "type" "loop_setup")
5182 (set_attr_alternative "length"
5183 ; FIXME: length is usually 4, but we need branch shortening
5184 ; to get this right.
5185 ; [(if_then_else (match_test "TARGET_ARC600") (const_int 16) (const_int 4))
5186 [(if_then_else (match_test "flag_pic") (const_int 24) (const_int 16))
5187 (if_then_else (match_test "flag_pic") (const_int 28) (const_int 16))
5188 (const_int 0)])]
5189 ;; ??? we should really branch shorten this insn, but then we'd
5190 ;; need a proper label first. N.B. the end label can not only go out
5191 ;; of range when it is far away, but also when it precedes the loop -
5192 ;; which, unfortunately, it sometimes does, when the loop "optimizer"
5193 ;; messes things up.
5194 )
5195
5196 ; operand 0 is the loop count pseudo register
5197 ; operand 1 is the label to jump to at the top of the loop
5198 ; Use this for the ARC600 and ARC700.
5199 ; ??? ARC600 might want to check if the loop has few iteration and only a
5200 ; single insn - loop setup is expensive then.
5201 (define_expand "doloop_end"
5202 [(use (match_operand 0 "register_operand" ""))
5203 (use (label_ref (match_operand 1 "" "")))]
5204 "!TARGET_ARC601"
5205 {
5206 /* We could do smaller bivs with biv widening, and wider bivs by having
5207 a high-word counter in an outer loop - but punt on this for now. */
5208 if (GET_MODE (operands[0]) != SImode)
5209 FAIL;
5210 emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
5211 DONE;
5212 })
5213
5214 (define_insn_and_split "doloop_end_i"
5215 [(set (pc)
5216 (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
5217 (const_int 1))
5218 (label_ref (match_operand 1 "" ""))
5219 (pc)))
5220 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5221 (use (reg:SI LP_START))
5222 (use (reg:SI LP_END))
5223 (use (match_operand 2 "const_int_operand" "n,???Cn0,???X"))
5224 (clobber (match_scratch:SI 3 "=X,X,&????r"))]
5225 ""
5226 "*
5227 {
5228 rtx_insn *prev = prev_nonnote_insn (insn);
5229
5230 /* If there is an immediately preceding label, we must output a nop,
5231 lest a branch to that label will fall out of the loop.
5232 ??? We could try to avoid this by claiming to have a delay slot if there
5233 is a preceding label, and outputting the delay slot insn instead, if
5234 present.
5235 Or we could have some optimization that changes the source edge to update
5236 the loop count and jump to the loop start instead. */
5237 /* For ARC600, we must also prevent jumps inside the loop and jumps where
5238 the loop counter value is live at the target from being directly at the
5239 loop end. Being sure that the loop counter is dead at the target is
5240 too much hair - we can't rely on data flow information at this point -
5241 so insert a nop for all branches.
5242 The ARC600 also can't read the loop counter in the last insn of a loop. */
5243 if (LABEL_P (prev))
5244 output_asm_insn (\"nop%?\", operands);
5245 return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
5246 }"
5247 "&& memory_operand (operands[0], SImode)"
5248 [(pc)]
5249 {
5250 emit_move_insn (operands[3], operands[0]);
5251 emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
5252 DONE;
5253 }
5254 [(set_attr "type" "loop_end")
5255 (set (attr "length")
5256 (if_then_else (match_test "LABEL_P (prev_nonnote_insn (insn))")
5257 (const_int 4) (const_int 0)))]
5258 )
5259
5260 ; This pattern is generated by arc_reorg when there is no recognizable
5261 ; loop start.
5262 (define_insn "*doloop_fallback"
5263 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
5264 (const_int 1))
5265 (label_ref (match_operand 1 "" ""))
5266 (pc)))
5267 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
5268 ; avoid fooling the loop optimizer into assuming this is a special insn.
5269 "reload_completed"
5270 "*return get_attr_length (insn) == 8
5271 ? \"brne.d %0,1,%1\;sub %0,%0,1\"
5272 : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
5273 [(set (attr "length")
5274 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
5275 (le (minus (match_dup 1) (pc)) (const_int 244)))
5276 (const_int 8) (const_int 12)))
5277 (set_attr "type" "brcc_no_delay_slot")
5278 (set_attr "cond" "nocond")]
5279 )
5280
5281 ; reload can't make output reloads for jump insns, so we have to do this by hand.
5282 (define_insn "doloop_fallback_m"
5283 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
5284 (const_int 1))
5285 (label_ref (match_operand 1 "" ""))
5286 (pc)))
5287 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5288 (set (match_operand:SI 2 "memory_operand" "=m")
5289 (plus:SI (match_dup 0) (const_int -1)))]
5290 ; avoid fooling the loop optimizer into assuming this is a special insn.
5291 "reload_completed"
5292 "*return get_attr_length (insn) == 12
5293 ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5294 : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5295 [(set (attr "length")
5296 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5297 (le (minus (match_dup 1) (pc)) (const_int 244)))
5298 (const_int 12) (const_int 16)))
5299 (set_attr "type" "brcc_no_delay_slot")
5300 (set_attr "cond" "nocond")]
5301 )
5302
5303 (define_expand "movmemsi"
5304 [(match_operand:BLK 0 "" "")
5305 (match_operand:BLK 1 "" "")
5306 (match_operand:SI 2 "nonmemory_operand" "")
5307 (match_operand 3 "immediate_operand" "")]
5308 ""
5309 "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5310
5311 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5312 ;; to the point that we can generate cmove instructions.
5313 (define_expand "cbranch<mode>4"
5314 [(set (reg:CC CC_REG)
5315 (compare:CC (match_operand:SDF 1 "register_operand" "")
5316 (match_operand:SDF 2 "register_operand" "")))
5317 (set (pc)
5318 (if_then_else
5319 (match_operator 0 "comparison_operator" [(reg CC_REG)
5320 (const_int 0)])
5321 (label_ref (match_operand 3 "" ""))
5322 (pc)))]
5323
5324 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5325 {
5326 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5327 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5328 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5329 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5330 DONE;
5331 })
5332
5333 (define_expand "cmp_float"
5334 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5335 (clobber (reg:SI RETURN_ADDR_REGNUM))
5336 (clobber (reg:SI R12_REG))])]
5337 ""
5338 "")
5339
5340 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5341 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5342 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5343
5344 (define_insn "*cmpsf_<cmp>"
5345 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5346 (clobber (reg:SI RETURN_ADDR_REGNUM))
5347 (clobber (reg:SI R12_REG))]
5348 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5349 && SFUNC_CHECK_PREDICABLE"
5350 "*return arc_output_libcall (\"__<cmp>sf2\");"
5351 [(set_attr "is_sfunc" "yes")
5352 (set_attr "predicable" "yes")])
5353
5354 ;; N.B. for "*cmpdf_ord":
5355 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5356 ;; for the floating point emulation to recognize the NaN.
5357 (define_insn "*cmpdf_<cmp>"
5358 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5359 (clobber (reg:SI RETURN_ADDR_REGNUM))
5360 (clobber (reg:SI R12_REG))]
5361 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5362 && SFUNC_CHECK_PREDICABLE"
5363 "*return arc_output_libcall (\"__<cmp>df2\");"
5364 [(set_attr "is_sfunc" "yes")
5365 (set_attr "predicable" "yes")])
5366
5367 (define_insn "abssf2"
5368 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w")
5369 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))]
5370 ""
5371 "bclr%? %0,%1,31%&"
5372 [(set_attr "type" "unary")
5373 (set_attr "iscompact" "maybe,false,false")
5374 (set_attr "length" "2,4,4")
5375 (set_attr "predicable" "no,yes,no")])
5376
5377 (define_insn "negsf2"
5378 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5379 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5380 ""
5381 "bxor%? %0,%1,31"
5382 [(set_attr "type" "unary")
5383 (set_attr "predicable" "yes,no")])
5384
5385 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5386 (define_insn "*millicode_thunk_st"
5387 [(match_parallel 0 "millicode_store_operation"
5388 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5389 ""
5390 {
5391 output_asm_insn ("bl%* __st_r13_to_%0",
5392 &SET_SRC (XVECEXP (operands[0], 0,
5393 XVECLEN (operands[0], 0) - 2)));
5394 return "";
5395 }
5396 [(set_attr "type" "call")])
5397
5398 (define_insn "*millicode_thunk_ld"
5399 [(match_parallel 0 "millicode_load_clob_operation"
5400 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5401 ""
5402 {
5403 output_asm_insn ("bl%* __ld_r13_to_%0",
5404 &SET_DEST (XVECEXP (operands[0], 0,
5405 XVECLEN (operands[0], 0) - 2)));
5406 return "";
5407 }
5408 [(set_attr "type" "call")])
5409
5410 ; the sibthunk restores blink, so we use the return rtx.
5411 (define_insn "*millicode_sibthunk_ld"
5412 [(match_parallel 0 "millicode_load_operation"
5413 [(return)
5414 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5415 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5416 ""
5417 {
5418 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5419 &SET_DEST (XVECEXP (operands[0], 0,
5420 XVECLEN (operands[0], 0) - 1)));
5421 return "";
5422 }
5423 [(set_attr "type" "call")
5424 (set_attr "is_SIBCALL" "yes")])
5425
5426 (define_insn "tls_load_tp_soft"
5427 [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF))
5428 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5429 ""
5430 "*return arc_output_libcall (\"__read_tp\");"
5431 [(set_attr "is_sfunc" "yes")
5432 (set_attr "predicable" "yes")])
5433
5434 (define_insn "tls_gd_load"
5435 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,c")
5436 (unspec:SI [(match_operand:SI 1 "register_operand" "Rcq#q,c")
5437 (match_operand:SI 2 "symbolic_operand" "X,X")]
5438 UNSPEC_TLS_GD))]
5439 ""
5440 ".tls_gd_ld %2`ld%? %0,[%1]"
5441 [(set_attr "type" "load")
5442 ; if the linker has to patch this into IE, we need a long insn
5443 ; (FIXME: or two short insn, ld_s / jl_s. missing -Os optimization.)
5444 (set_attr_alternative "iscompact"
5445 [(cond [(ne (symbol_ref "arc_tp_regno == 30") (const_int 0))
5446 (const_string "*")] (const_string "maybe"))
5447 (const_string "*")])])
5448
5449 (define_insn "tls_gd_get_addr"
5450 [(set (reg:SI R0_REG)
5451 (call:SI (mem:SI (unspec:SI [(match_operand:SI 0
5452 "symbolic_operand" "X,X")]
5453 UNSPEC_TLS_GD))
5454 (const_int 0)))
5455 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5456 ""
5457 ".tls_gd_ld %0`bl%* __tls_get_addr@plt"
5458 [(set_attr "type" "call")
5459 ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
5460 (set_attr "predicable" "no")])
5461
5462 ; We make this call specific to the tls symbol to avoid commoning this
5463 ; with calls for other symbols; we want the linker to be able to
5464 (define_insn "tls_gd_dispatch"
5465 [(set (reg:SI R0_REG)
5466 (unspec:SI
5467 [(reg:SI R0_REG)
5468 (call (mem:SI (match_operand:SI 0 "register_operand" "Rcq,q,c"))
5469 (const_int 0))
5470 (match_operand:SI 1 "symbolic_operand" "X,X,X")]
5471 UNSPEC_TLS_GD))
5472 (clobber (reg:SI RETURN_ADDR_REGNUM))
5473 (clobber (reg:DI R10_REG))
5474 (clobber (reg:SI R12_REG))]
5475 ""
5476 ".tls_gd_call %1`jl%!%* [%0]"
5477 [(set_attr "type" "call")
5478 (set_attr "iscompact" "maybe,false,*")
5479 (set_attr "predicable" "no,no,yes")])
5480
5481 ;; For thread pointer builtins
5482 (define_expand "get_thread_pointersi"
5483 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5484 ""
5485 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5486
5487 (define_expand "set_thread_pointersi"
5488 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5489 ""
5490 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5491
5492 ;; If hardware floating point is available, don't define a negdf pattern;
5493 ;; it would be something like:
5494 ;;(define_insn "negdf2"
5495 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5496 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5497 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5498 ;; ""
5499 ;; "@
5500 ;; bxor%? %H0,%H1,31
5501 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5502 ;; drsubh%F0%F1 0,0,0
5503 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5504 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5505 ;; (set_attr "iscompact" "false,false,false,false")
5506 ;; (set_attr "length" "4,4,8,12")
5507 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5508 ;; and this suffers from always requiring a long immediate when using
5509 ;; the floating point hardware.
5510 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5511 ;; constant zero efficiently into a register when we want to do the
5512 ;; computation using the floating point hardware. There should be a special
5513 ;; subdf alternative that matches a zero operand 1, which then can allow
5514 ;; to use bxor to flip the high bit of an integer register.
5515 ;; ??? we actually can't use the floating point hardware for neg, because
5516 ;; this would not work right for -0. OTOH optabs.c has already code
5517 ;; to synthesyze negate by flipping the sign bit.
5518
5519 ;;V2 instructions
5520 (define_insn "bswapsi2"
5521 [(set (match_operand:SI 0 "register_operand" "= r,r")
5522 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5523 "TARGET_V2 && TARGET_SWAP"
5524 "swape %0, %1"
5525 [(set_attr "length" "4,8")
5526 (set_attr "type" "two_cycle_core")])
5527
5528 (define_expand "prefetch"
5529 [(prefetch (match_operand:SI 0 "address_operand" "")
5530 (match_operand:SI 1 "const_int_operand" "")
5531 (match_operand:SI 2 "const_int_operand" ""))]
5532 "TARGET_HS"
5533 "")
5534
5535 (define_insn "prefetch_1"
5536 [(prefetch (match_operand:SI 0 "register_operand" "r")
5537 (match_operand:SI 1 "const_int_operand" "n")
5538 (match_operand:SI 2 "const_int_operand" "n"))]
5539 "TARGET_HS"
5540 {
5541 if (INTVAL (operands[1]))
5542 return "prefetchw [%0]";
5543 else
5544 return "prefetch [%0]";
5545 }
5546 [(set_attr "type" "load")
5547 (set_attr "length" "4")])
5548
5549 (define_insn "prefetch_2"
5550 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5551 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5552 (match_operand:SI 2 "const_int_operand" "n,n,n")
5553 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5554 "TARGET_HS"
5555 {
5556 if (INTVAL (operands[2]))
5557 return "prefetchw [%0, %1]";
5558 else
5559 return "prefetch [%0, %1]";
5560 }
5561 [(set_attr "type" "load")
5562 (set_attr "length" "4,4,8")])
5563
5564 (define_insn "prefetch_3"
5565 [(prefetch (match_operand:SI 0 "address_operand" "p")
5566 (match_operand:SI 1 "const_int_operand" "n")
5567 (match_operand:SI 2 "const_int_operand" "n"))]
5568 "TARGET_HS"
5569 {
5570 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5571 if (INTVAL (operands[1]))
5572 return "prefetchw%U0 %0";
5573 else
5574 return "prefetch%U0 %0";
5575 }
5576 [(set_attr "type" "load")
5577 (set_attr "length" "8")])
5578
5579 (define_insn "divsi3"
5580 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5581 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5582 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5583 "TARGET_DIVREM"
5584 "div%? %0, %1, %2"
5585 [(set_attr "length" "4,4,8,4,4,4,8,8")
5586 (set_attr "iscompact" "false")
5587 (set_attr "type" "div_rem")
5588 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5589 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5590 ])
5591
5592 (define_insn "udivsi3"
5593 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5594 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5595 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5596 "TARGET_DIVREM"
5597 "divu%? %0, %1, %2"
5598 [(set_attr "length" "4,4,8,4,4,4,8,8")
5599 (set_attr "iscompact" "false")
5600 (set_attr "type" "div_rem")
5601 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5602 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5603 ])
5604
5605 (define_insn "modsi3"
5606 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5607 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5608 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5609 "TARGET_DIVREM"
5610 "rem%? %0, %1, %2"
5611 [(set_attr "length" "4,4,8,4,4,4,8,8")
5612 (set_attr "iscompact" "false")
5613 (set_attr "type" "div_rem")
5614 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5615 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5616 ])
5617
5618 (define_insn "umodsi3"
5619 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5620 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5621 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5622 "TARGET_DIVREM"
5623 "remu%? %0, %1, %2"
5624 [(set_attr "length" "4,4,8,4,4,4,8,8")
5625 (set_attr "iscompact" "false")
5626 (set_attr "type" "div_rem")
5627 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5628 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5629 ])
5630
5631 ;; SETcc instructions
5632 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5633
5634 (define_insn "arcset<code>"
5635 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5636 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5637 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5638 "TARGET_V2 && TARGET_CODE_DENSITY"
5639 "set<code>%? %0, %1, %2"
5640 [(set_attr "length" "4,4,4,4,4,8,8")
5641 (set_attr "iscompact" "false")
5642 (set_attr "type" "compare")
5643 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5644 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5645 ])
5646
5647 (define_insn "arcsetltu"
5648 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5649 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5650 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5651 "TARGET_V2 && TARGET_CODE_DENSITY"
5652 "setlo%? %0, %1, %2"
5653 [(set_attr "length" "4,4,4,4,4,8,8")
5654 (set_attr "iscompact" "false")
5655 (set_attr "type" "compare")
5656 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5657 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5658 ])
5659
5660 (define_insn "arcsetgeu"
5661 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5662 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5663 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5664 "TARGET_V2 && TARGET_CODE_DENSITY"
5665 "seths%? %0, %1, %2"
5666 [(set_attr "length" "4,4,4,4,4,8,8")
5667 (set_attr "iscompact" "false")
5668 (set_attr "type" "compare")
5669 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5670 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5671 ])
5672
5673 ;; Special cases of SETCC
5674 (define_insn_and_split "arcsethi"
5675 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5676 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5677 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5678 "TARGET_V2 && TARGET_CODE_DENSITY"
5679 "setlo%? %0, %2, %1"
5680 "reload_completed
5681 && CONST_INT_P (operands[2])
5682 && satisfies_constraint_C62 (operands[2])"
5683 [(const_int 0)]
5684 "{
5685 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5686 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5687 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5688 DONE;
5689 }"
5690 [(set_attr "length" "4,4,4,8")
5691 (set_attr "iscompact" "false")
5692 (set_attr "type" "compare")
5693 (set_attr "predicable" "yes,no,no,no")
5694 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5695 )
5696
5697 (define_insn_and_split "arcsetls"
5698 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5699 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5700 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5701 "TARGET_V2 && TARGET_CODE_DENSITY"
5702 "seths%? %0, %2, %1"
5703 "reload_completed
5704 && CONST_INT_P (operands[2])
5705 && satisfies_constraint_C62 (operands[2])"
5706 [(const_int 0)]
5707 "{
5708 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5709 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5710 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5711 DONE;
5712 }"
5713 [(set_attr "length" "4,4,4,8")
5714 (set_attr "iscompact" "false")
5715 (set_attr "type" "compare")
5716 (set_attr "predicable" "yes,no,no,no")
5717 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5718 )
5719
5720 ; Any mode that needs to be solved by secondary reload
5721 (define_mode_iterator SRI [QI HI])
5722
5723 (define_expand "reload_<mode>_load"
5724 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5725 (match_operand:SRI 1 "memory_operand" "m")
5726 (match_operand:SI 2 "register_operand" "=&r")])]
5727 ""
5728 {
5729 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5730 DONE;
5731 })
5732
5733 (define_expand "reload_<mode>_store"
5734 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5735 (match_operand:SRI 1 "register_operand" "r")
5736 (match_operand:SI 2 "register_operand" "=&r")])]
5737 ""
5738 {
5739 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5740 DONE;
5741 })
5742
5743
5744 (define_insn "extzvsi"
5745 [(set (match_operand:SI 0 "register_operand" "=r , r , r, r, r")
5746 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r , 0, 0, r")
5747 (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5748 (match_operand:SI 3 "const_int_operand" "i , i , i, i, i")))]
5749 "TARGET_HS && TARGET_BARREL_SHIFTER"
5750 {
5751 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5752 operands[2] = GEN_INT (assemble_op2);
5753 return "xbfu%? %0,%1,%2";
5754 }
5755 [(set_attr "type" "shift")
5756 (set_attr "iscompact" "false")
5757 (set_attr "length" "4,4,4,8,8")
5758 (set_attr "predicable" "yes,no,no,yes,no")
5759 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond")])
5760
5761 (define_insn "kflag"
5762 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5763 VUNSPEC_ARC_KFLAG)]
5764 "TARGET_V2"
5765 "@
5766 kflag%? %0
5767 kflag %0
5768 kflag%? %S0"
5769 [(set_attr "length" "4,4,8")
5770 (set_attr "type" "misc,misc,misc")
5771 (set_attr "predicable" "yes,no,yes")
5772 (set_attr "cond" "clob,clob,clob")])
5773
5774 (define_insn "clri"
5775 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5776 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5777 VUNSPEC_ARC_CLRI))]
5778 "TARGET_V2"
5779 "clri %0"
5780 [(set_attr "length" "4")
5781 (set_attr "type" "misc")])
5782
5783 (define_insn "ffs"
5784 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5785 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5786 UNSPEC_ARC_FFS))]
5787 "TARGET_NORM && TARGET_V2"
5788 "@
5789 ffs \t%0, %1
5790 ffs \t%0, %S1"
5791 [(set_attr "length" "4,8")
5792 (set_attr "type" "two_cycle_core,two_cycle_core")])
5793
5794 (define_insn "ffs_f"
5795 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5796 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5797 UNSPEC_ARC_FFS))
5798 (set (reg:CC_ZN CC_REG)
5799 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5800 "TARGET_NORM && TARGET_V2"
5801 "@
5802 ffs.f\t%0, %1
5803 ffs.f\t%0, %S1"
5804 [(set_attr "length" "4,8")
5805 (set_attr "type" "two_cycle_core,two_cycle_core")])
5806
5807 (define_expand "ffssi2"
5808 [(parallel [(set (match_dup 2)
5809 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5810 UNSPEC_ARC_FFS))
5811 (set (reg:CC_ZN CC_REG)
5812 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5813 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5814 (set (match_operand:SI 0 "dest_reg_operand" "")
5815 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5816 (const_int 0)
5817 (match_dup 2)))]
5818 "TARGET_NORM && TARGET_V2"
5819 {
5820 operands[2] = gen_reg_rtx (SImode);
5821 })
5822
5823 (define_insn "fls"
5824 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5825 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5826 UNSPEC_ARC_FLS))]
5827 "TARGET_NORM && TARGET_V2"
5828 "@
5829 fls \t%0, %1
5830 fls \t%0, %S1"
5831 [(set_attr "length" "4,8")
5832 (set_attr "type" "two_cycle_core,two_cycle_core")])
5833
5834 (define_insn "seti"
5835 [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5836 VUNSPEC_ARC_SETI)]
5837 "TARGET_V2"
5838 "seti %0"
5839 [(set_attr "length" "4")
5840 (set_attr "type" "misc")])
5841
5842 ;; FPU/FPX expands
5843
5844 ;;add
5845 (define_expand "addsf3"
5846 [(set (match_operand:SF 0 "register_operand" "")
5847 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5848 (match_operand:SF 2 "nonmemory_operand" "")))]
5849 "TARGET_FP_SP_BASE || TARGET_SPFP"
5850 "
5851 if (!register_operand (operands[1], SFmode)
5852 && !register_operand (operands[2], SFmode))
5853 operands[1] = force_reg (SFmode, operands[1]);
5854 ")
5855
5856 ;;sub
5857 (define_expand "subsf3"
5858 [(set (match_operand:SF 0 "register_operand" "")
5859 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5860 (match_operand:SF 2 "nonmemory_operand" "")))]
5861 "TARGET_FP_SP_BASE || TARGET_SPFP"
5862 "
5863 if (!register_operand (operands[1], SFmode)
5864 && !register_operand (operands[2], SFmode))
5865 operands[1] = force_reg (SFmode, operands[1]);
5866 ")
5867
5868 ;;mul
5869 (define_expand "mulsf3"
5870 [(set (match_operand:SF 0 "register_operand" "")
5871 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5872 (match_operand:SF 2 "nonmemory_operand" "")))]
5873 "TARGET_FP_SP_BASE || TARGET_SPFP"
5874 "
5875 if (!register_operand (operands[1], SFmode)
5876 && !register_operand (operands[2], SFmode))
5877 operands[1] = force_reg (SFmode, operands[1]);
5878 ")
5879
5880 ;;add
5881 (define_expand "adddf3"
5882 [(set (match_operand:DF 0 "double_register_operand" "")
5883 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5884 (match_operand:DF 2 "nonmemory_operand" "")))]
5885 "TARGET_FP_DP_BASE || TARGET_DPFP"
5886 "
5887 if (TARGET_DPFP)
5888 {
5889 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5890 {
5891 rtx first, second, tmp;
5892 split_double (operands[2], &first, &second);
5893 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5894 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5895 operands[2], tmp, const0_rtx));
5896 }
5897 else
5898 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5899 operands[2], const1_rtx, const1_rtx));
5900 DONE;
5901 }
5902 else if (TARGET_FP_DP_BASE)
5903 {
5904 if (!even_register_operand (operands[2], DFmode))
5905 operands[2] = force_reg (DFmode, operands[2]);
5906
5907 if (!even_register_operand (operands[1], DFmode))
5908 operands[1] = force_reg (DFmode, operands[1]);
5909 }
5910 else
5911 gcc_unreachable ();
5912 ")
5913
5914 ;;sub
5915 (define_expand "subdf3"
5916 [(set (match_operand:DF 0 "double_register_operand" "")
5917 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5918 (match_operand:DF 2 "nonmemory_operand" "")))]
5919 "TARGET_FP_DP_BASE || TARGET_DPFP"
5920 "
5921 if (TARGET_DPFP)
5922 {
5923 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5924 operands[1] = force_reg (DFmode, operands[1]);
5925 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5926 || GET_CODE (operands[2]) == CONST_DOUBLE)
5927 {
5928 rtx first, second, tmp;
5929 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5930 split_double (operands[const_index], &first, &second);
5931 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5932 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5933 operands[2], tmp, const0_rtx));
5934 }
5935 else
5936 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5937 operands[2], const1_rtx, const1_rtx));
5938 DONE;
5939 }
5940 else if (TARGET_FP_DP_BASE)
5941 {
5942 if (!even_register_operand (operands[2], DFmode))
5943 operands[2] = force_reg (DFmode, operands[2]);
5944
5945 if (!even_register_operand (operands[1], DFmode))
5946 operands[1] = force_reg (DFmode, operands[1]);
5947 }
5948 else
5949 gcc_unreachable ();
5950 ")
5951
5952 ;;mul
5953 (define_expand "muldf3"
5954 [(set (match_operand:DF 0 "double_register_operand" "")
5955 (mult:DF (match_operand:DF 1 "double_register_operand" "")
5956 (match_operand:DF 2 "nonmemory_operand" "")))]
5957 "TARGET_FP_DP_BASE || TARGET_DPFP"
5958 "
5959 if (TARGET_DPFP)
5960 {
5961 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5962 {
5963 rtx first, second, tmp;
5964 split_double (operands[2], &first, &second);
5965 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5966 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5967 operands[2], tmp, const0_rtx));
5968 }
5969 else
5970 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5971 operands[2], const1_rtx, const1_rtx));
5972 DONE;
5973 }
5974 else if (TARGET_FP_DP_BASE)
5975 {
5976 if (!even_register_operand (operands[2], DFmode))
5977 operands[2] = force_reg (DFmode, operands[2]);
5978
5979 if (!even_register_operand (operands[1], DFmode))
5980 operands[1] = force_reg (DFmode, operands[1]);
5981 }
5982 else
5983 gcc_unreachable ();
5984 ")
5985
5986 (define_expand "extzv"
5987 [(set (match_operand:SI 0 "register_operand" "")
5988 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5989 (match_operand:SI 2 "const_int_operand" "")
5990 (match_operand:SI 3 "const_int_operand" "")))]
5991 "TARGET_NPS_BITOPS")
5992
5993 ; We need a sanity check in the instuction predicate because combine
5994 ; will throw any old rubbish at us and see what sticks.
5995 (define_insn "*extzv_i"
5996 [(set (match_operand:SI 0 "register_operand" "=Rrq")
5997 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5998 (match_operand:SI 2 "const_int_operand" "n")
5999 (match_operand:SI 3 "const_int_operand" "n")))]
6000 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
6001 "movb.cl %0,%1,0,%3,%2"
6002 [(set_attr "type" "shift")
6003 (set_attr "length" "4")])
6004
6005 (define_expand "insv"
6006 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
6007 (match_operand:SI 1 "const_int_operand" "")
6008 (match_operand:SI 2 "const_int_operand" ""))
6009 (match_operand:SI 3 "nonmemory_operand" ""))]
6010 "TARGET_NPS_BITOPS"
6011 {
6012 int size = INTVAL (operands[1]);
6013
6014 if (size != 1 && size != 2 && size != 4 && size != 8)
6015 operands[3] = force_reg (SImode, operands[3]);
6016 })
6017
6018 (define_insn "*insv_i"
6019 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
6020 (match_operand:SI 1 "const_int_operand" "C18,n")
6021 (match_operand:SI 2 "const_int_operand" "n,n"))
6022 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
6023 "TARGET_NPS_BITOPS
6024 && (register_operand (operands[3], SImode)
6025 || satisfies_constraint_C18 (operands[1]))"
6026 "@
6027 movbi %0,%0,%3,%2,%1
6028 movb %0,%0,%3,%2,0,%1"
6029 [(set_attr "type" "shift")
6030 (set_attr "length" "4")])
6031
6032 (define_insn "*movb"
6033 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6034 (match_operand:SI 1 "const_int_operand" "n")
6035 (match_operand:SI 2 "const_int_operand" "n"))
6036 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
6037 (match_dup 1)
6038 (match_operand:SI 4 "const_int_operand" "n")))]
6039 "TARGET_NPS_BITOPS"
6040 "movb %0,%0,%3,%2,%4,%1"
6041 [(set_attr "type" "shift")
6042 (set_attr "length" "4")])
6043
6044 (define_insn "*movb_signed"
6045 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6046 (match_operand:SI 1 "const_int_operand" "n")
6047 (match_operand:SI 2 "const_int_operand" "n"))
6048 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
6049 (match_dup 1)
6050 (match_operand:SI 4 "const_int_operand" "n")))]
6051 "TARGET_NPS_BITOPS"
6052 "movb %0,%0,%3,%2,%4,%1"
6053 [(set_attr "type" "shift")
6054 (set_attr "length" "4")])
6055
6056 (define_insn "*movb_high"
6057 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6058 (match_operand:SI 1 "const_int_operand" "n")
6059 (match_operand:SI 2 "const_int_operand" "n"))
6060 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6061 (match_operand:SI 4 "const_int_operand" "n")))]
6062 "TARGET_NPS_BITOPS
6063 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6064 "movb %0,%0,%3,%2,%4,%1"
6065 [(set_attr "type" "shift")
6066 (set_attr "length" "4")])
6067
6068 ; N.B.: when processing signed bitfields that fit in the top half of
6069 ; a word, gcc will use a narrow sign extending load, and in this case
6070 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6071 (define_insn "*movb_high_signed"
6072 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6073 (match_operand:SI 1 "const_int_operand" "n")
6074 (match_operand:SI 2 "const_int_operand" "n"))
6075 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6076 (match_operand:SI 4 "const_int_operand" "n")))]
6077 "TARGET_NPS_BITOPS
6078 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6079 "movb %0,%0,%3,%2,%4,%1"
6080 [(set_attr "type" "shift")
6081 (set_attr "length" "4")])
6082
6083 (define_split
6084 [(set (match_operand:SI 0 "register_operand" "")
6085 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6086 (match_operand:SI 2 "const_int_operand" ""))
6087 (subreg:SI (match_operand 3 "") 0)))]
6088 "TARGET_NPS_BITOPS
6089 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6090 && !reg_overlap_mentioned_p (operands[0], operands[1])"
6091 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6092 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6093 (match_dup 1))]
6094 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6095
6096 (define_insn "*mrgb"
6097 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6098 (match_operand:SI 1 "const_int_operand" "n")
6099 (match_operand:SI 2 "const_int_operand" "n"))
6100 (zero_extract:SI (match_dup 0) (match_dup 1)
6101 (match_operand:SI 3 "const_int_operand" "n")))
6102 (set (zero_extract:SI (match_dup 0)
6103 (match_operand:SI 4 "const_int_operand" "n")
6104 (match_operand:SI 5 "const_int_operand" "n"))
6105 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6106 (match_dup 4)
6107 (match_operand:SI 7 "const_int_operand" "n")))]
6108 "TARGET_NPS_BITOPS"
6109 {
6110 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6111 /* The ;%? updates the known unalignment. */
6112 return arc_short_long (insn, ";%?", "nop_s");
6113 }
6114 [(set_attr "type" "shift")
6115 (set_attr "length" "6")
6116 (set_attr "iscompact" "true")])
6117
6118 ;; combine fumbles combination of two movb patterns, and then the
6119 ;; combination is rejected by combinable_i3pat.
6120 ;; Thus, we can only use a peephole2 to combine two such insns.
6121
6122 (define_peephole2
6123 [(set (match_operand:SI 0 "register_operand" "")
6124 (match_operand:SI 1 "register_operand" ""))
6125 (set (zero_extract:SI (match_dup 0)
6126 (match_operand:SI 2 "const_int_operand" "")
6127 (match_operand:SI 3 "const_int_operand" ""))
6128 (zero_extract:SI (match_dup 1)
6129 (match_dup 2)
6130 (match_operand:SI 4 "const_int_operand" "")))
6131 (match_operand 9) ; unrelated insn scheduled here
6132 (set (zero_extract:SI (match_dup 0)
6133 (match_operand:SI 5 "const_int_operand" "")
6134 (match_operand:SI 6 "const_int_operand" ""))
6135 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6136 (match_dup 5)
6137 (match_operand:SI 8 "const_int_operand" "")))]
6138 "TARGET_NPS_BITOPS
6139 // Check that the second movb doesn't clobber an input of the extra insn.
6140 && !reg_overlap_mentioned_p (operands[0], operands[9])
6141 // And vice versa.
6142 && !reg_set_p (operands[0], operands[9])
6143 && !reg_set_p (operands[7], operands[9])"
6144 [(set (match_dup 0) (match_dup 1))
6145 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6146 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6147 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6148 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6149 (match_dup 9)])
6150
6151 (define_peephole2
6152 [(set (match_operand:SI 0 "register_operand" "")
6153 (match_operand:SI 1 "register_operand" ""))
6154 (set (zero_extract:SI (match_dup 0)
6155 (match_operand:SI 2 "const_int_operand" "")
6156 (match_operand:SI 3 "const_int_operand" ""))
6157 (zero_extract:SI (match_dup 1)
6158 (match_dup 2)
6159 (match_operand:SI 4 "const_int_operand" "")))
6160 (set (match_dup 1) (match_operand 8))
6161 (set (zero_extract:SI (match_dup 0)
6162 (match_operand:SI 5 "const_int_operand" "")
6163 (match_operand:SI 6 "const_int_operand" ""))
6164 (zero_extract:SI (match_dup 1) (match_dup 5)
6165 (match_operand:SI 7 "const_int_operand" "")))]
6166 "TARGET_NPS_BITOPS
6167 && !reg_overlap_mentioned_p (operands[0], operands[8])"
6168 [(set (match_dup 0) (match_dup 1))
6169 (set (match_dup 1) (match_dup 8))
6170 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6171 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6172 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6173 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6174 (match_dup 1)])
6175
6176 ;; include the arc-FPX instructions
6177 (include "fpx.md")
6178
6179 ;; include the arc-FPU instructions
6180 (include "fpu.md")
6181
6182 (include "simdext.md")
6183
6184 ;; include atomic extensions
6185 (include "atomic.md")