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