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