]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/cris/cris.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / cris / cris.md
CommitLineData
0b85d816 1;; GCC machine description for CRIS cpu cores.
7adcbafe 2;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
0b85d816
HPN
3;; Contributed by Axis Communications.
4
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
748086b7 9;; the Free Software Foundation; either version 3, or (at your option)
0b85d816
HPN
10;; any later version.
11;;
12;; GCC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
0b85d816
HPN
20
21;; The original PO technology requires these to be ordered by speed,
22;; so that assigner will pick the fastest.
23
24;; See files "md.texi" and "rtl.def" for documentation on define_insn,
25;; match_*, et. al.
0b85d816
HPN
26
27;; There are several instructions that are orthogonal in size, and seems
28;; they could be matched by a single pattern without a specified size
29;; for the operand that is orthogonal. However, this did not work on
839a4992 30;; gcc-2.7.2 (and probably not on gcc-2.8.1), relating to that when a
0b85d816
HPN
31;; constant is substituted into an operand, the actual mode must be
32;; deduced from the pattern. There is reasonable hope that that has been
d2f55c5c 33;; fixed, so FIXME: try again.
0b85d816
HPN
34
35;; You will notice that three-operand alternatives ("=r", "r", "!To")
36;; are marked with a "!" constraint modifier to avoid being reloaded
37;; into. This is because gcc would otherwise prefer to use the constant
38;; pool and its offsettable address instead of reloading to an
39;; ("=r", "0", "i") alternative. Also, the constant-pool support was not
40;; only suboptimal but also buggy in 2.7.2, ??? maybe only in 2.6.3.
41
42;; All insns that look like (set (...) (plus (...) (reg:SI 8)))
43;; get problems when reloading r8 (frame pointer) to r14 + offs (stack
44;; pointer). Thus the instructions that get into trouble have specific
45;; checks against matching frame_pointer_rtx.
46;; ??? But it should be re-checked for gcc > 2.7.2
47;; FIXME: This changed some time ago (from 2000-03-16) for gcc-2.9x.
48
21ed4444 49(define_c_enum ""
45d5d09c 50 [
45d5d09c 51 ;; Stack frame deallocation barrier.
21ed4444 52 CRIS_UNSPEC_FRAME_DEALLOC
45d5d09c
HPN
53
54 ;; Swap all 32 bits of the operand; 31 <=> 0, 30 <=> 1...
21ed4444 55 CRIS_UNSPEC_SWAP_BITS
45d5d09c 56 ])
f60c7155
HPN
57
58;; Register numbers.
59(define_constants
d0780379 60 [(CRIS_STATIC_CHAIN_REGNUM 7)
aa27696b 61 (CRIS_REAL_FP_REGNUM 8)
f60c7155 62 (CRIS_SP_REGNUM 14)
45d5d09c 63 (CRIS_ACR_REGNUM 15)
f60c7155 64 (CRIS_SRP_REGNUM 16)
f9968e3e
HPN
65 (CRIS_MOF_REGNUM 17)
66 (CRIS_AP_REGNUM 18)
aa27696b
HPN
67 (CRIS_CC0_REGNUM 19)
68 (CRIS_FP_REGNUM 20)]
f60c7155
HPN
69)
70
0b85d816
HPN
71;; We need an attribute to define whether an instruction can be put in
72;; a branch-delay slot or not, and whether it has a delay slot.
73;;
74;; Branches and return instructions have a delay slot, and cannot
75;; themselves be put in a delay slot. This has changed *for short
76;; branches only* between architecture variants, but the possible win
77;; is presumed negligible compared to the added complexity of the machine
78;; description: one would have to add always-correct infrastructure to
79;; distinguish short branches.
80;;
81;; Whether an instruction can be put in a delay slot depends on the
82;; instruction (all short instructions except jumps and branches)
83;; and the addressing mode (must not be prefixed or referring to pc).
84;; In short, any "slottable" instruction must be 16 bit and not refer
85;; to pc, or alter it.
86;;
d0780379
HPN
87;; The possible values are "yes", "no", "has_slot", and "has_return_slot".
88;; Yes/no tells whether the insn is slottable or not.
45d5d09c
HPN
89;; Of special concern is that no RTX_FRAME_RELATED insn must go in that
90;; call delay slot, as it's located in the address *after* the call insn,
91;; and the unwind machinery doesn't know about delay slots.
92;; Has_slot means that the insn is a branch insn (which are
93;; not considered slottable since that is generally true). Having the
94;; seemingly illogical value "has_slot" means we do not have to add
95;; another attribute just to say that an insn has a delay-slot, since it
96;; also infers that it is not slottable. Better names for the attribute
97;; were found to be longer and not add readability to the machine
98;; description.
99;; Has_return_slot is similar, for the return insn.
0b85d816
HPN
100;;
101;; The default that is defined here for this attribute is "no", not
102;; slottable, not having a delay-slot, so there's no need to worry about
103;; it being wrong for non-branch and return instructions.
104;; The default could depend on the kind of insn and the addressing
105;; mode, but that would need more attributes and hairier, more error
106;; prone code.
107;;
23369bef
HPN
108;; There is an extra memory constraint, 'Q', which recognizes an indirect
109;; register. The constraints 'Q' and '>' together match all possible
110;; memory operands that are slottable.
0b85d816
HPN
111;; For other operands, you need to check if it has a valid "slottable"
112;; quick-immediate operand, where the particular signedness-variation
113;; may match the constraints 'I' or 'J'.), and include it in the
114;; constraint pattern for the slottable pattern. An alternative using
115;; only "r" constraints is most often slottable.
116
d0780379 117(define_attr "slottable" "no,yes,has_slot,has_return_slot"
45d5d09c 118 (const_string "no"))
0b85d816
HPN
119
120;; We also need attributes to sanely determine the condition code
a82c9fb3
HPN
121;; state. This attribute isn't used as-is, just as a template,
122;; effectively a dummy except in a substitution setting CRIS_CC0_REGNUM
123;; to a specific value.
fb062a8b 124(define_attr "cc" "none,clobber,normal" (const_string "normal"))
0b85d816 125
a82c9fb3
HPN
126;; The attribute "_enabled" is appended to "cc", forming "cc_enabled" to
127;; pick out certain alternatives when generating a useful
128;; condition-code-setting. See the "enabled" attribute.
129(define_attr "cc_enabled" "none,clobber,normal" (const_string "normal"))
130
3a5afdfc
HPN
131;; At the moment, this attribute is just used to help bb-reorder do its
132;; work; the default 0 doesn't help it. Many insns have other lengths,
133;; though none are shorter.
134(define_attr "length" "" (const_int 2))
135
45d5d09c 136;; A branch has one delay-slot. The instruction in the
0b85d816
HPN
137;; delay-slot is always executed, independent of whether the branch is
138;; taken or not. Note that besides setting "slottable" to "has_slot",
139;; there also has to be a "%#" at the end of a "delayed" instruction
140;; output pattern (for "jump" this means "ba %l0%#"), so print_operand can
141;; catch it and print a "nop" if necessary. This method was stolen from
142;; sparc.md.
143
144(define_delay (eq_attr "slottable" "has_slot")
145 [(eq_attr "slottable" "yes") (nil) (nil)])
45d5d09c 146
45d5d09c
HPN
147;; The insn in the return insn slot must not be the
148;; return-address-register restore. FIXME: Use has_slot and express
149;; as a parallel with a use of the return-address-register (currently
150;; only SRP). However, this requires an amount of fixing tests for
151;; naked RETURN in middle-end.
152(define_delay (eq_attr "slottable" "has_return_slot")
153 [(and (eq_attr "slottable" "yes")
bf0b8cbe 154 (not (match_test "dead_or_set_regno_p (insn, CRIS_SRP_REGNUM)")))
45d5d09c
HPN
155 (nil) (nil)])
156
a82c9fb3
HPN
157(define_attr "enabled" "no,yes"
158 (if_then_else
159 (eq_attr "cc_enabled" "normal")
160 (const_string "yes")
161 (const_string "no")))
0b85d816 162\f
22c3c091
HPN
163;; Iterator definitions.
164
165;; For the "usual" pattern size alternatives.
3abcb3a7 166(define_mode_iterator BWD [SI HI QI])
fb062a8b
HPN
167(define_mode_iterator BWDD [DI SI HI QI])
168
169;; To be able to refer to the same mode_attr for both a multi-mode
170;; and a mode-specific pattern, we use some singleton iterators.
171(define_mode_iterator DI_ [DI])
172(define_mode_iterator SI_ [SI])
173
3abcb3a7
HPN
174(define_mode_iterator WD [SI HI])
175(define_mode_iterator BW [HI QI])
22c3c091
HPN
176(define_mode_attr S [(SI "HI") (HI "QI")])
177(define_mode_attr s [(SI "hi") (HI "qi")])
178(define_mode_attr m [(SI ".d") (HI ".w") (QI ".b")])
179(define_mode_attr mm [(SI ".w") (HI ".b")])
180(define_mode_attr nbitsm1 [(SI "31") (HI "15") (QI "7")])
181
182;; For the sign_extend+zero_extend variants.
3abcb3a7 183(define_code_iterator szext [sign_extend zero_extend])
22c3c091
HPN
184(define_code_attr u [(sign_extend "") (zero_extend "u")])
185(define_code_attr su [(sign_extend "s") (zero_extend "u")])
186
9596eccb
HPN
187;; For extended-operand variants.
188(define_code_iterator plusminus [plus minus])
189(define_code_attr addsub [(plus "add") (minus "sub")])
190
191;; Similar, other cases also matching bound/umin.
192(define_code_iterator plusminusumin [plus minus umin])
193
194;; Ditto, commutative operators (i.e. not minus).
195(define_code_iterator plusumin [plus umin])
196
197;; The addsubbo and nd code-attributes form a hack. We need to output
198;; "addu.b", "subu.b" but "bound.b" (no "u"-suffix) which means we'd
199;; need to refer to one iterator from the next. But, that can't be
200;; done. Instead output the "u" for unsigned as the "u" in "bound",
201;; i.e. the mnemonic as three parts including the extend-letter, and
202;; with an empty third part for "add" and "sub".
203(define_code_attr addsubbo [(plus "add") (minus "sub") (umin "bo")])
204(define_code_attr nd [(plus "") (minus "") (umin "nd")])
205
22c3c091 206;; For the shift variants.
3abcb3a7
HPN
207(define_code_iterator shift [ashiftrt lshiftrt ashift])
208(define_code_iterator shiftrt [ashiftrt lshiftrt])
22c3c091
HPN
209(define_code_attr shlr [(ashiftrt "ashr") (lshiftrt "lshr") (ashift "ashl")])
210(define_code_attr slr [(ashiftrt "asr") (lshiftrt "lsr") (ashift "lsl")])
211
b3e01c3d
HPN
212;; Compares, branches, cbranch, cstore. Conditions gt and le are CC_NZVC.
213;; Others start out as CCmode and can degenerate to CC_NZmode.
214;; Incidental setters are either CC_NZVCmode or CC_NZmode. See also
215;; cris-modes.def.
216(define_mode_iterator NZSET [CC_NZ])
217(define_mode_iterator NZUSE [CC CC_NZ CC_NZVC])
218(define_mode_iterator NZVCSET [CC CC_NZVC CC_NZ])
219(define_mode_iterator NZVCUSE [CC_NZVC])
b73bf8a1
HPN
220(define_mode_iterator ZnNNZSET [CC_ZnN CC_NZ])
221(define_mode_iterator ZnNNZUSE [CC CC_ZnN CC_NZ CC_NZVC])
b3e01c3d
HPN
222
223;; All conditions.
224(define_code_iterator cond [eq ne gtu ltu geu leu gt le lt ge])
225
226;; Just equal and not equal.
27228024 227(define_code_iterator zcond [eq ne])
b3e01c3d
HPN
228
229;; Conditions that look only at Z and/or N (or can do with that).
230(define_code_iterator nzcond [eq ne gtu leu lt ge])
231
232;; The complement of nzcond within cond; conditions that look (also) on V
233;; or C.
234(define_code_iterator nzvccond [geu ltu gt le])
235
236;; Within nzcond, those that give different opcodes when operands are
237;; reversed or that can ignore V or C. Also, the complement of zcond
238;; within nzcond.
239(define_code_iterator rnzcond [gtu leu lt ge])
240
241;; CRIS condition mnemonic.
22c3c091
HPN
242(define_code_attr CC [(eq "eq") (ne "ne") (gt "gt") (gtu "hi") (lt "lt")
243 (ltu "lo") (ge "ge") (geu "hs") (le "le") (leu "ls")])
b3e01c3d
HPN
244
245;; CRIS reverse condition mnemonic.
22c3c091
HPN
246(define_code_attr rCC [(eq "ne") (ne "eq") (gt "le") (gtu "ls") (lt "ge")
247 (ltu "hs") (ge "lt") (geu "lo") (le "gt") (leu "hi")])
b3e01c3d
HPN
248
249;; Mnemomic for the CRIS condition when V or C can be ignored.
250(define_code_attr oCC [(lt "mi") (ge "pl") (gtu "eq") (ltu "ne")])
251
252;; Reverse of oCC.
253(define_code_attr roCC [(lt "pl") (ge "mi") (gtu "eq") (ltu "ne")])
254
b73bf8a1
HPN
255;; CC_Z_IN_NOT_N, a.k.a. CC_ZnNmode.
256(define_code_attr znnCC [(eq "pl") (ne "mi")])
257
258;;; ...and the reverse
259(define_code_attr rznnCC [(eq "mi") (ne "pl")])
260
b3e01c3d
HPN
261;; Required unoptimized CCmode, different for nzcond and nzvccond.
262(define_code_attr xCC [(eq "CC") (ne "CC") (gtu "CC") (ltu "CC_NZVC")
263 (geu "CC_NZVC") (leu "CC") (lt "CC") (ge "CC")
264 (gt "CC_NZVC") (le "CC_NZVC")])
22c3c091 265
a82c9fb3
HPN
266;; Substitutions to describe condition-code settings.
267
268(define_subst_attr "setnz" "setnz_subst" "" "_setnz")
269(define_subst_attr "ccnz" "setnz_subst" "" "_enabled")
3c7016b0 270(define_subst_attr "anz" "setnz_subst" "" "*")
a82c9fb3
HPN
271
272(define_subst "setnz_subst"
273 [(set (match_operand 0)
274 (match_operand 1))
275 (clobber (reg:CC CRIS_CC0_REGNUM))]
276 "reload_completed"
277 [(set (reg:CC_NZ CRIS_CC0_REGNUM)
278 (compare:CC_NZ (match_dup 1) (const_int 0)))
f4ac1a7f 279 (set (match_dup 0) (match_dup 1))])
a82c9fb3
HPN
280
281(define_subst_attr "setnzvc" "setnzvc_subst" "" "_setnzvc")
282(define_subst_attr "ccnzvc" "setnzvc_subst" "" "_enabled")
3c7016b0 283(define_subst_attr "anzvc" "setnzvc_subst" "" "*")
a82c9fb3
HPN
284
285(define_subst "setnzvc_subst"
286 [(set (match_operand 0)
287 (match_operand 1))
288 (clobber (reg:CC CRIS_CC0_REGNUM))]
289 "reload_completed"
290 [(set (reg:CC_NZVC CRIS_CC0_REGNUM)
291 (compare:CC_NZVC (match_dup 1) (const_int 0)))
f4ac1a7f 292 (set (match_dup 0) (match_dup 1))])
a82c9fb3
HPN
293
294(define_subst_attr "setcc" "setcc_subst" "" "_setcc")
295(define_subst_attr "cccc" "setcc_subst" "" "_enabled")
3c7016b0 296(define_subst_attr "acc" "setcc_subst" "" "*")
a82c9fb3
HPN
297
298(define_subst "setcc_subst"
299 [(set (match_operand 0)
300 (match_operand 1))
301 (clobber (reg:CC CRIS_CC0_REGNUM))]
302 "reload_completed"
303 [(set (reg:CC CRIS_CC0_REGNUM)
304 (compare:CC (match_dup 1) (const_int 0)))
f4ac1a7f 305 (set (match_dup 0) (match_dup 1))])
a82c9fb3 306
68a81332
HPN
307;; Operand and operator predicates.
308
309(include "predicates.md")
06cadf63 310(include "constraints.md")
68a81332 311\f
0b85d816
HPN
312;; It seems that the position of the sign-bit and the fact that 0.0 is
313;; all 0-bits would make "tstsf" a straight-forward implementation;
314;; either "test.d" it for positive/negative or "btstq 30,r" it for
315;; zeroness.
316;;
fb062a8b 317;; FIXME: Do that some time.
0b85d816
HPN
318\f
319;; Compare insns.
320
fb062a8b
HPN
321;; These are used for compare insn, cbranch and cstore.
322;; FIXME: Port-local reversing of operands is not done. Still needed?
323;; (It shouldn't be; it should be done as part of register allocation.)
324(define_mode_attr sCC_destc
325 [(DI "r, r,r,r,r,r,r") (SI "r,r, r, r,r,r") (HI "r, r, r,r") (QI "r, r, r,r")])
b3e01c3d 326(define_mode_attr cmp_op0c
fb062a8b 327 [(DI "rm,r,r,r,r,r,r") (SI "r,r, rQ>,r,r,m") (HI "r, rQ>,r,m") (QI "r, rQ>,r,m")])
b3e01c3d 328(define_mode_attr cmp_op1c
fb062a8b
HPN
329 [(DI "M,Kc,I,P,n,r,o") (SI "I,rQ>,M, P,g,M") (HI "rQ>,M, g,M") (QI "rQ>,M, g,M")])
330
0b85d816
HPN
331;; We could optimize the sizes of the immediate operands for various
332;; cases, but that is not worth it because of the very little usage of
333;; DImode for anything else but a structure/block-mode. Just do the
334;; obvious stuff for the straight-forward constraint letters.
335
b3e01c3d
HPN
336(define_insn "*cmpdi<NZVCSET:mode>"
337 [(set (reg:NZVCSET CRIS_CC0_REGNUM)
338 (compare:NZVCSET
339 (match_operand:DI_ 0 "nonimmediate_operand" "<cmp_op0c>")
340 (match_operand:DI_ 1 "general_operand" "<cmp_op1c>")))]
fb062a8b 341 "reload_completed"
0b85d816 342 "@
f90b7a5a 343 test.d %M0\;ax\;test.d %H0
0b85d816
HPN
344 cmpq %1,%M0\;ax\;cmpq 0,%H0
345 cmpq %1,%M0\;ax\;cmpq -1,%H0
346 cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0
347 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
348 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
fb062a8b 349 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0")
0b85d816
HPN
350
351;; Note that compare insns with side effect addressing mode (e.g.):
352;;
353;; cmp.S [rx=ry+i],rz;
354;; cmp.S [%3=%1+%2],%0
355;;
356;; are *not* usable for gcc since the reloader *does not accept*
357;; cc0-changing insns with side-effects other than setting the condition
358;; codes. The reason is that the reload stage *may* cause another insn to
359;; be output after the main instruction, in turn invalidating cc0 for the
360;; insn using the test. (This does not apply to the CRIS case, since a
361;; reload for output -- move to memory -- does not change the condition
362;; code. Unfortunately we have no way to describe that at the moment. I
363;; think code would improve being in the order of one percent faster.
364\f
365;; We have cmps and cmpu (compare reg w. sign/zero extended mem).
366;; These are mostly useful for compares in SImode, using 8 or 16-bit
367;; constants, but sometimes gcc will find its way to use it for other
368;; (memory) operands. Avoid side-effect patterns, though (see above).
0b85d816 369
b3e01c3d
HPN
370(define_insn "*cmp_ext<BW:mode><NZVCSET:mode>"
371 [(set (reg:NZVCSET CRIS_CC0_REGNUM)
372 (compare:NZVCSET
0b85d816
HPN
373 (match_operand:SI 0 "register_operand" "r,r")
374 (match_operator:SI 2 "cris_extend_operator"
22c3c091 375 [(match_operand:BW 1 "memory_operand" "Q>,m")])))]
fb062a8b 376 "reload_completed"
22c3c091 377 "cmp%e2<m> %1,%0"
0b85d816 378 [(set_attr "slottable" "yes,no")])
0b85d816 379\f
45d5d09c 380;; The "normal" compare patterns, from SI on. Special-cases with zero
f90b7a5a 381;; are covered above.
0b85d816 382
b3e01c3d
HPN
383(define_insn "*cmpsi<NZVCSET:mode>"
384 [(set (reg:NZVCSET CRIS_CC0_REGNUM)
385 (compare:NZVCSET
386 (match_operand:SI_ 0 "nonimmediate_operand" "<cmp_op0c>")
387 (match_operand:SI_ 1 "general_operand" "<cmp_op1c>")))]
fb062a8b 388 "reload_completed"
0b85d816
HPN
389 "@
390 cmpq %1,%0
391 cmp.d %1,%0
fb062a8b 392 test.d %0
0b85d816
HPN
393 cmp%e1.%z1 %1,%0
394 cmp.d %1,%0
fb062a8b
HPN
395 test.d %0"
396 [(set_attr "slottable" "yes,yes,yes,no,no,no")])
0b85d816 397
b3e01c3d
HPN
398(define_insn "*cmp<BW:mode><NZVCSET:mode>"
399 [(set (reg:NZVCSET CRIS_CC0_REGNUM)
400 (compare:NZVCSET
401 (match_operand:BW 0 "nonimmediate_operand" "<cmp_op0c>")
402 (match_operand:BW 1 "general_operand" "<cmp_op1c>")))]
fb062a8b 403 "reload_completed"
0b85d816 404 "@
22c3c091 405 cmp<m> %1,%0
fb062a8b 406 test<m> %0
22c3c091 407 cmp<m> %1,%0
fb062a8b
HPN
408 test<m> %0"
409 [(set_attr "slottable" "yes,yes,no,no")])
0b85d816
HPN
410\f
411;; Pattern matching the BTST insn.
412;; It is useful for "if (i & val)" constructs, where val is an exact
413;; power of 2, or if val + 1 is a power of two, where we check for a bunch
414;; of zeros starting at bit 0).
415
416;; SImode. This mode is the only one needed, since gcc automatically
b73bf8a1 417;; extends subregs for lower-size modes.
b3e01c3d 418(define_insn "*btst<mode>"
b73bf8a1
HPN
419 [(set (reg:ZnNNZSET CRIS_CC0_REGNUM)
420 (compare:ZnNNZSET
f90b7a5a
PB
421 (zero_extract:SI
422 (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
423 (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
424 (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r"))
425 (const_int 0)))]
0b85d816 426 ;; Either it is a single bit, or consecutive ones starting at 0.
fb062a8b
HPN
427 "reload_completed
428 && CONST_INT_P (operands[1])
b73bf8a1
HPN
429 && ((operands[1] == const1_rtx && <MODE>mode == CC_ZnNmode)
430 || (operands[2] == const0_rtx && <MODE>mode == CC_NZmode))
0b85d816
HPN
431 && (REG_S_P (operands[0])
432 || (operands[1] == const1_rtx
433 && REG_S_P (operands[2])
991c42ac 434 && CONST_INT_P (operands[0])
45d5d09c
HPN
435 && exact_log2 (INTVAL (operands[0])) >= 0))
436 && !TARGET_CCINIT"
0b85d816 437
45d5d09c 438;; The next-to-last "&&" condition above should be caught by some kind of
0b85d816
HPN
439;; canonicalization in gcc, but we can easily help with it here.
440;; It results from expressions of the type
b73bf8a1 441;; "power_of_2_value & (1 << y)". FIXME: Add testcase.
0b85d816
HPN
442;;
443;; Since there may be codes with tests in on bits (in constant position)
444;; beyond the size of a word, handle that by assuming those bits are 0.
445;; GCC should handle that, but it's a matter of easily-added belts while
446;; having suspenders.
447
448 "@
449 btstq (%1-1),%0
45d5d09c 450 cmpq 0,%0
0b85d816
HPN
451 btstq %2,%0
452 clearf nz
453 btst %2,%0
454 clearf nz
455 cmpq %p0,%2"
d0780379 456 [(set_attr "slottable" "yes")])
0b85d816
HPN
457\f
458;; Move insns.
459
460;; The whole mandatory movdi family is here; expander, "anonymous"
461;; recognizer and splitter. We're forced to have a movdi pattern,
462;; although GCC should be able to split it up itself. Normally it can,
463;; but if other insns have DI operands (as is the case here), reload
464;; must be able to generate or match a movdi. many testcases fail at
465;; -O3 or -fssa if we don't have this. FIXME: Fix GCC... See
466;; <URL:http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00104.html>.
467;; However, a patch from Richard Kenner (similar to the cause of
468;; discussion at the URL above), indicates otherwise. See
469;; <URL:http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00554.html>.
470;; The truth has IMO is not been decided yet, so check from time to
471;; time by disabling the movdi patterns.
472
22c3c091
HPN
473;; To appease testcase gcc.c-torture/execute/920501-2.c (and others) at
474;; -O0, we need a movdi as a temporary measure. Here's how things fail:
475;; A cmpdi RTX needs reloading (global):
476;; (insn 185 326 186 (set (cc0)
477;; (compare (mem/f:DI (reg/v:SI 22) 0)
478;; (const_int 1 [0x1]))) 4 {cmpdi} (nil)
479;; (nil))
480;; Now, reg 22 is reloaded for input address, and the mem is also moved
481;; out of the instruction (into a register), since one of the operands
482;; must be a register. Reg 22 is reloaded (into reg 10), and the mem is
483;; moved out and synthesized in SImode parts (reg 9, reg 10 - should be ok
484;; wrt. overlap). The bad things happen with the synthesis in
485;; emit_move_insn_1; the location where to substitute reg 10 is lost into
486;; two new RTX:es, both still having reg 22. Later on, the left-over reg
487;; 22 is recognized to have an equivalent in memory which is substituted
488;; straight in, and we end up with an unrecognizable insn:
489;; (insn 325 324 326 (set (reg:SI 9 r9)
490;; (mem/f:SI (mem:SI (plus:SI (reg:SI 8 r8)
491;; (const_int -84 [0xffffffac])) 0) 0)) -1 (nil)
492;; (nil))
493;; which is the first part of the reloaded synthesized "movdi".
494;; The right thing would be to add equivalent replacement locations for
495;; insn with pseudos that need more reloading. The question is where.
496
0b85d816 497(define_expand "movdi"
fb062a8b
HPN
498 [(parallel
499 [(set (match_operand:DI 0 "nonimmediate_operand")
500 (match_operand:DI 1 "general_operand"))
501 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 502 ""
0b85d816 503{
45d5d09c
HPN
504 if (MEM_P (operands[0])
505 && operands[1] != const0_rtx
d0780379 506 && can_create_pseudo_p ())
0b85d816
HPN
507 operands[1] = copy_to_mode_reg (DImode, operands[1]);
508
509 /* Some other ports (as of 2001-09-10 for example mcore and romp) also
510 prefer to split up constants early, like this. The testcase in
511 gcc.c-torture/execute/961213-1.c shows that CSE2 gets confused by the
512 resulting subreg sets when using the construct from mcore (as of FSF
049746c2 513 CVS, version -r 1.5), and it believes that the high part (the last one
d70dcf29 514 emitted) is the final value. */
991c42ac 515 if ((CONST_INT_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
0b85d816
HPN
516 && ! reload_completed
517 && ! reload_in_progress)
518 {
519 rtx insns;
520 rtx op0 = operands[0];
521 rtx op1 = operands[1];
522
523 start_sequence ();
524 emit_move_insn (operand_subword (op0, 0, 1, DImode),
525 operand_subword (op1, 0, 1, DImode));
526 emit_move_insn (operand_subword (op0, 1, 1, DImode),
527 operand_subword (op1, 1, 1, DImode));
528 insns = get_insns ();
529 end_sequence ();
530
d70dcf29 531 emit_insn (insns);
0b85d816
HPN
532 DONE;
533 }
22c3c091 534})
0b85d816 535
d0780379 536(define_insn_and_split "*movdi_insn"
477c433d 537 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rx,m")
fb062a8b
HPN
538 (match_operand:DI 1 "general_operand" "rx,g,rxM"))
539 (clobber (reg:CC CRIS_CC0_REGNUM))]
45d5d09c
HPN
540 "(register_operand (operands[0], DImode)
541 || register_operand (operands[1], DImode)
d0780379 542 || operands[1] == const0_rtx)"
45d5d09c
HPN
543 "#"
544 "&& reload_completed"
545 [(match_dup 2)]
546 "operands[2] = cris_split_movdx (operands);")
0b85d816 547\f
0b85d816
HPN
548;; Normal move patterns from SI on.
549
550(define_expand "movsi"
fb062a8b
HPN
551 [(parallel
552 [(set
553 (match_operand:SI 0 "nonimmediate_operand")
554 (match_operand:SI 1 "general_operand"))
555 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 556 ""
0b85d816
HPN
557{
558 /* If the output goes to a MEM, make sure we have zero or a register as
559 input. */
991c42ac 560 if (MEM_P (operands[0])
0b85d816
HPN
561 && ! REG_S_P (operands[1])
562 && operands[1] != const0_rtx
3a0e695a 563 && can_create_pseudo_p ())
0b85d816 564 operands[1] = force_reg (SImode, operands[1]);
e49cee5c
HPN
565
566 /* At post-reload time, we'll get here for e.g. split multi-mode insns
567 with a memory destination. Go directly to the clobber-less variant.
12bdaa7d
HPN
568 FIXME: Also applies to special-register source or destination. */
569 if (reload_completed
570 && (MEM_P (operands[0]) || operands[1] == const0_rtx))
e49cee5c
HPN
571 {
572 emit_insn (gen_rtx_SET (operands[0], operands[1]));
573 DONE;
574 }
b6c34129 575})
0b85d816 576
a82c9fb3
HPN
577;; We provide CC, CC_NZ and CC_NZVC variants, as moves clear V and C
578;; and the result is thus usable in a compare against 0.
579(define_insn "*movsi_internal<setcc><setnz><setnzvc>"
0b85d816 580 [(set
45d5d09c 581 (match_operand:SI 0 "nonimmediate_operand"
d0780379
HPN
582 "=r,r, r,Q>,r,Q>,g,r,r,g,rQ>,x, m,x")
583 (match_operand:SI 1 "general_operand"
fb062a8b
HPN
584 "r,Q>,M,M, I,r, M,n,g,r,x, rQ>,x,gi"))
585 (clobber (reg:CC CRIS_CC0_REGNUM))]
c00fc5cf 586 ;; Note that we prefer not to use the S alternative (if for some reason
45d5d09c 587 ;; it competes with others) above, but g matches S.
0b85d816 588 ""
0b85d816
HPN
589{
590 /* Better to have c-switch here; it is worth it to optimize the size of
591 move insns. The alternative would be to try to find more constraint
592 letters. FIXME: Check again. It seems this could shrink a bit. */
593 switch (which_alternative)
594 {
595 case 0:
596 case 1:
597 case 5:
d0780379
HPN
598 case 8:
599 case 9:
22c3c091 600 return "move.d %1,%0";
0b85d816 601
d0780379 602 case 10:
f60c7155
HPN
603 case 11:
604 case 12:
605 case 13:
d0780379 606 return "move %1,%0";
f60c7155 607
0b85d816
HPN
608 case 2:
609 case 3:
610 case 6:
22c3c091 611 return "clear.d %0";
0b85d816
HPN
612
613 /* Constants -32..31 except 0. */
614 case 4:
22c3c091 615 return "moveq %1,%0";
0b85d816
HPN
616
617 /* We can win a little on constants -32768..-33, 32..65535. */
618 case 7:
619 if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) < 65536)
620 {
621 if (INTVAL (operands[1]) < 256)
22c3c091
HPN
622 return "movu.b %1,%0";
623 return "movu.w %1,%0";
0b85d816
HPN
624 }
625 else if (INTVAL (operands[1]) >= -32768 && INTVAL (operands[1]) < 32768)
626 {
627 if (INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) < 128)
22c3c091
HPN
628 return "movs.b %1,%0";
629 return "movs.w %1,%0";
0b85d816 630 }
22c3c091 631 return "move.d %1,%0";
0b85d816 632
0b85d816 633 default:
d0780379 634 gcc_unreachable ();
0b85d816 635 }
22c3c091 636}
d0780379 637 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,no,no,yes,yes,no,no")
a82c9fb3
HPN
638 (set_attr "cc<cccc><ccnz><ccnzvc>"
639 "*,*,none,none,*,none,none,*,*,none,none,none,none,none")])
0b85d816 640\f
0b85d816
HPN
641;; FIXME: See movsi.
642
3c7016b0 643(define_insn "<acc><anz><anzvc>movhi<setcc><setnz><setnzvc>"
0b85d816 644 [(set
f60c7155 645 (match_operand:HI 0 "nonimmediate_operand" "=r,r, r,Q>,r,Q>,r,r,r,g,g,r,r,x")
fb062a8b
HPN
646 (match_operand:HI 1 "general_operand" "r,Q>,M,M, I,r, L,O,n,M,r,g,x,r"))
647 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 648 ""
0b85d816
HPN
649{
650 switch (which_alternative)
651 {
652 case 0:
653 case 1:
654 case 5:
655 case 10:
656 case 11:
22c3c091 657 return "move.w %1,%0";
f60c7155
HPN
658 case 12:
659 case 13:
22c3c091 660 return "move %1,%0";
0b85d816
HPN
661 case 2:
662 case 3:
663 case 9:
22c3c091 664 return "clear.w %0";
0b85d816 665 case 4:
22c3c091 666 return "moveq %1,%0";
0b85d816
HPN
667 case 6:
668 case 8:
669 if (INTVAL (operands[1]) < 256 && INTVAL (operands[1]) >= -128)
670 {
671 if (INTVAL (operands[1]) > 0)
22c3c091
HPN
672 return "movu.b %1,%0";
673 return "movs.b %1,%0";
0b85d816 674 }
22c3c091 675 return "move.w %1,%0";
0b85d816 676 case 7:
22c3c091 677 return "movEq %b1,%0";
0b85d816 678 default:
22c3c091 679 return "BOGUS: %1 to %0";
0b85d816 680 }
22c3c091 681}
f60c7155 682 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,yes,no,no,no,no,yes,yes")
3c7016b0 683 (set_attr "cc<cccc><ccnz><ccnzvc>" "*,*,none,none,*,none,*,clobber,*,none,none,*,none,none")])
0b85d816
HPN
684
685(define_insn "movstricthi"
686 [(set
687 (strict_low_part
23369bef 688 (match_operand:HI 0 "nonimmediate_operand" "+r,r, r,Q>,Q>,g,r,g"))
fb062a8b
HPN
689 (match_operand:HI 1 "general_operand" "r,Q>,M,M, r, M,g,r"))
690 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
691 ""
692 "@
693 move.w %1,%0
694 move.w %1,%0
695 clear.w %0
696 clear.w %0
697 move.w %1,%0
698 clear.w %0
699 move.w %1,%0
700 move.w %1,%0"
701 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
f60c7155 702
22c3c091
HPN
703(define_expand "reload_in<mode>"
704 [(set (match_operand:BW 2 "register_operand" "=r")
705 (match_operand:BW 1 "memory_operand" "m"))
706 (set (match_operand:BW 0 "register_operand" "=x")
f60c7155
HPN
707 (match_dup 2))]
708 ""
709 "")
710
22c3c091 711(define_expand "reload_out<mode>"
11e30dd8 712 [(set (match_operand:BW 2 "register_operand" "=&r")
22c3c091
HPN
713 (match_operand:BW 1 "register_operand" "x"))
714 (set (match_operand:BW 0 "memory_operand" "=m")
f60c7155
HPN
715 (match_dup 2))]
716 ""
717 "")
0b85d816 718\f
3c7016b0 719(define_insn "<acc><anz><anzvc>movqi<setcc><setnz><setnzvc>"
f60c7155 720 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,Q>,r, r,Q>,r,g,g,r,r,r,x")
fb062a8b
HPN
721 (match_operand:QI 1 "general_operand" "r,r, Q>,M,M, I,M,r,O,g,x,r"))
722 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
723 ""
724 "@
725 move.b %1,%0
726 move.b %1,%0
727 move.b %1,%0
728 clear.b %0
729 clear.b %0
730 moveq %1,%0
731 clear.b %0
732 move.b %1,%0
733 moveq %b1,%0
f60c7155
HPN
734 move.b %1,%0
735 move %1,%0
736 move %1,%0"
737 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,yes,no,yes,yes")
3c7016b0
HPN
738 (set_attr "cc<cccc><ccnz><ccnzvc>"
739 "*,none,*,none,none,*,none,none,clobber,*,none,none")])
0b85d816
HPN
740
741(define_insn "movstrictqi"
742 [(set (strict_low_part
23369bef 743 (match_operand:QI 0 "nonimmediate_operand" "+r,Q>,r, r,Q>,g,g,r"))
fb062a8b
HPN
744 (match_operand:QI 1 "general_operand" "r,r, Q>,M,M, M,r,g"))
745 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
746 ""
747 "@
748 move.b %1,%0
749 move.b %1,%0
750 move.b %1,%0
751 clear.b %0
752 clear.b %0
753 clear.b %0
754 move.b %1,%0
755 move.b %1,%0"
756 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
757
758;; The valid "quick" bit-patterns are, except for 0.0, denormalized
759;; values REALLY close to 0, and some NaN:s (I think; their exponent is
760;; all ones); the worthwhile one is "0.0".
761;; It will use clear, so we know ALL types of immediate 0 never change cc.
762
763(define_insn "movsf"
f60c7155 764 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,Q>,r, r,Q>,g,g,r,r,x,Q>,m,x, x")
fb062a8b
HPN
765 (match_operand:SF 1 "general_operand" "r,r, Q>,G,G, G,r,g,x,r,x, x,Q>,g"))
766 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
767 ""
768 "@
769 move.d %1,%0
770 move.d %1,%0
771 move.d %1,%0
772 clear.d %0
773 clear.d %0
774 clear.d %0
775 move.d %1,%0
f60c7155
HPN
776 move.d %1,%0
777 move %1,%0
778 move %1,%0
779 move %1,%0
780 move %1,%0
781 move %1,%0
782 move %1,%0"
783 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no,yes,yes,yes,no,yes,no")])
e49cee5c
HPN
784
785;; Post-reload, for memory destinations, split the clobber-variant and
786;; get rid of the clobber.
787
788(define_split ;; "*mov_tomem<mode>_split"
789 [(set (match_operand:BWD 0 "memory_operand")
790 (match_operand:BWD 1 "nonmemory_operand"))
791 (clobber (reg:CC CRIS_CC0_REGNUM))]
792 "reload_completed"
793 [(set (match_dup 0) (match_dup 1))]
794 "")
795
796;; Exclude moving special-registers to memory from matching for
797;; less-than-SImode, as they are SImode only (or actually, the size of
798;; the register, but the ones free for "x" are naturally SImode; see
799;; special measures taken for reload).
800;; This might be a belt-and-suspenders thing, as a move from special
801;; register to memory in less-than-SImode should not have made it here.
802
803(define_mode_attr mov_tomem_enabled
804 [(SI "yes,yes,yes,yes,yes,yes")
805 (HI "yes,yes,no,yes,yes,no")
806 (QI "yes,yes,no,yes,yes,no")])
807
808(define_insn "*mov_tomem<mode>"
809 [(set (match_operand:BWD 0 "memory_operand" "=Q>,Q>,Q>,m,m,m")
810 (match_operand:BWD 1 "nonmemory_operand" "M, r, x, M,r,x"))]
811 "reload_completed"
812 "@
813 clear<m> %0
814 move<m> %1,%0
815 move %1,%0
816 clear<m> %0
817 move<m> %1,%0
818 move %1,%0"
819 [(set_attr "slottable" "yes,yes,yes,no,no,no")
820 (set_attr "enabled" "<mov_tomem_enabled>")])
12bdaa7d
HPN
821
822(define_split ;; "*mov_fromzero<mode>_split"
823 [(set (match_operand:BWD 0 "register_operand") (const_int 0))
824 (clobber (reg:CC CRIS_CC0_REGNUM))]
825 "reload_completed
826 && REGNO(operands[0]) <= CRIS_LAST_GENERAL_REGISTER"
827 [(set (match_dup 0) (const_int 0))]
828 "")
829
830(define_insn "*mov_fromzero<mode>"
831 [(set (match_operand:BWD 0 "register_operand" "=r") (const_int 0))]
832 "reload_completed"
833 "clear<m> %0"
834 [(set_attr "slottable" "yes")])
45d5d09c
HPN
835\f
836;; Movem patterns. Primarily for use in function prologue and epilogue.
d0780379
HPN
837;; Unfortunately, movem stores R0 in the highest memory location, thus
838;; the opposite of the expectation for the standard names "load_multiple"
839;; and "store_multiple".
04539954 840
04539954
HPN
841(define_insn "*cris_load_multiple"
842 [(match_parallel 0 "cris_load_multiple_op"
843 [(set (match_operand:SI 1 "register_operand" "=r,r")
844 (match_operand:SI 2 "memory_operand" "Q,m"))])]
845 ""
846 "movem %O0,%o0"
847 [(set_attr "cc" "none")
848 (set_attr "slottable" "yes,no")
849 ;; Not true, but setting the length to 0 causes return sequences (ret
850 ;; movem) to have the cost they had when (return) included the movem
851 ;; and reduces the performance penalty taken for needing to emit an
852 ;; epilogue (in turn copied by bb-reorder) instead of return patterns.
853 ;; FIXME: temporary change until all insn lengths are correctly
854 ;; described. FIXME: have better target control over bb-reorder.
855 (set_attr "length" "0")])
d29b4b1b
HPN
856
857(define_insn "*cris_store_multiple"
858 [(match_parallel 0 "cris_store_multiple_op"
859 [(set (match_operand:SI 2 "memory_operand" "=Q,m")
860 (match_operand:SI 1 "register_operand" "r,r"))])]
861 ""
862 "movem %o0,%O0"
863 [(set_attr "cc" "none")
864 (set_attr "slottable" "yes,no")])
0b85d816
HPN
865\f
866
867;; Sign- and zero-extend insns with standard names.
868;; Those for integer source operand are ordered with the widest source
869;; type first.
870
871;; Sign-extend.
872
873(define_insn "extendsidi2"
874 [(set (match_operand:DI 0 "register_operand" "=r")
fb062a8b
HPN
875 (sign_extend:DI (match_operand:SI 1 "general_operand" "g")))
876 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
877 ""
878 "move.d %1,%M0\;smi %H0\;neg.d %H0,%H0")
879
22c3c091 880(define_insn "extend<mode>di2"
0b85d816 881 [(set (match_operand:DI 0 "register_operand" "=r")
fb062a8b
HPN
882 (sign_extend:DI (match_operand:BW 1 "general_operand" "g")))
883 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 884 ""
22c3c091 885 "movs<m> %1,%M0\;smi %H0\;neg.d %H0,%H0")
0b85d816 886
61c964c7 887(define_insn "<acc><anz><anzvc>extend<mode>si2<setcc><setnz><setnzvc>"
0b85d816 888 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
fb062a8b
HPN
889 (sign_extend:SI (match_operand:BW 1 "general_operand" "r,Q>,g")))
890 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 891 ""
22c3c091 892 "movs<m> %1,%0"
0b85d816
HPN
893 [(set_attr "slottable" "yes,yes,no")])
894
073a8998 895;; To do a byte->word extension, extend to dword, except that the top half
0b85d816
HPN
896;; of the register will be clobbered. FIXME: Perhaps this is not needed.
897
898(define_insn "extendqihi2"
899 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
fb062a8b
HPN
900 (sign_extend:HI (match_operand:QI 1 "general_operand" "r,Q>,g")))
901 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
902 ""
903 "movs.b %1,%0"
904 [(set_attr "slottable" "yes,yes,no")])
905\f
906
907;; Zero-extend. The DImode ones are synthesized by gcc, so we don't
908;; specify them here.
909
61c964c7 910(define_insn "<acc><anz><anzvc>zero_extend<mode>si2<setcc><setnz><setnzvc>"
0b85d816
HPN
911 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
912 (zero_extend:SI
fb062a8b
HPN
913 (match_operand:BW 1 "nonimmediate_operand" "r,Q>,m")))
914 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 915 ""
22c3c091 916 "movu<m> %1,%0"
0b85d816
HPN
917 [(set_attr "slottable" "yes,yes,no")])
918
919;; Same comment as sign-extend QImode to HImode above applies.
920
921(define_insn "zero_extendqihi2"
922 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
923 (zero_extend:HI
fb062a8b
HPN
924 (match_operand:QI 1 "nonimmediate_operand" "r,Q>,m")))
925 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
926 ""
927 "movu.b %1,%0"
928 [(set_attr "slottable" "yes,yes,no")])
929\f
0b85d816
HPN
930;; Add operations, standard names.
931
932;; Note that for the 'P' constraint, the high part can be -1 or 0. We
933;; output the insn through the 'A' output modifier as "adds.w" and "addq",
934;; respectively.
45d5d09c 935(define_expand "adddi3"
fb062a8b
HPN
936 [(parallel
937 [(set (match_operand:DI 0 "register_operand")
938 (plus:DI (match_operand:DI 1 "register_operand")
939 (match_operand:DI 2 "general_operand")))
940 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c 941 ""
d0780379 942 "")
45d5d09c 943
e561b9fe 944(define_insn "*adddi3<setnz>"
0b85d816
HPN
945 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
946 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,r")
fb062a8b
HPN
947 (match_operand:DI 2 "general_operand" "J,N,P,g,!To")))
948 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 949 ""
0b85d816
HPN
950 "@
951 addq %2,%M0\;ax\;addq 0,%H0
952 subq %n2,%M0\;ax\;subq 0,%H0
953 add%e2.%z2 %2,%M0\;ax\;%A2 %H2,%H0
954 add.d %M2,%M0\;ax\;add.d %H2,%H0
955 add.d %M2,%M1,%M0\;ax\;add.d %H2,%H1,%H0")
956
45d5d09c 957(define_expand "add<mode>3"
fb062a8b
HPN
958 [(parallel
959 [(set (match_operand:BWD 0 "register_operand")
960 (plus:BWD
961 (match_operand:BWD 1 "register_operand")
962 (match_operand:BWD 2 "general_operand")))
963 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c
HPN
964 ""
965 "")
966
e561b9fe 967(define_insn "*addsi3<setnz>"
d0780379 968 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r,r, r")
0b85d816 969 (plus:SI
d0780379 970 (match_operand:SI 1 "register_operand" "%0,0, 0,0,0,0,r, r")
fb062a8b
HPN
971 (match_operand:SI 2 "general_operand" "r,Q>,J,N,n,g,!To,0")))
972 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
973
974;; The last constraint is due to that after reload, the '%' is not
975;; honored, and canonicalization doesn't care about keeping the same
976;; register as in destination. This will happen after insn splitting.
0b85d816 977
d0780379 978 ""
0b85d816
HPN
979{
980 switch (which_alternative)
981 {
982 case 0:
983 case 1:
22c3c091 984 return "add.d %2,%0";
0b85d816 985 case 2:
22c3c091 986 return "addq %2,%0";
0b85d816 987 case 3:
22c3c091 988 return "subq %n2,%0";
0b85d816
HPN
989 case 4:
990 /* 'Known value', but not in -63..63.
991 Check if addu/subu may be used. */
992 if (INTVAL (operands[2]) > 0)
993 {
994 if (INTVAL (operands[2]) < 256)
22c3c091 995 return "addu.b %2,%0";
0b85d816 996 if (INTVAL (operands[2]) < 65536)
22c3c091 997 return "addu.w %2,%0";
0b85d816
HPN
998 }
999 else
1000 {
1001 if (INTVAL (operands[2]) >= -255)
22c3c091 1002 return "subu.b %n2,%0";
0b85d816 1003 if (INTVAL (operands[2]) >= -65535)
22c3c091 1004 return "subu.w %n2,%0";
0b85d816 1005 }
22c3c091 1006 return "add.d %2,%0";
0b85d816 1007 case 5:
d0780379 1008 return "add.d %2,%0";
c00fc5cf 1009 case 6:
c00fc5cf 1010 return "add.d %2,%1,%0";
d0780379 1011 case 7:
22c3c091 1012 return "add.d %1,%0";
0b85d816 1013 default:
22c3c091 1014 return "BOGUS addsi %2+%1 to %0";
0b85d816 1015 }
22c3c091 1016}
d0780379 1017 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,yes")])
0b85d816 1018\f
e561b9fe 1019(define_insn "*addhi3<setnz>"
23369bef
HPN
1020 [(set (match_operand:HI 0 "register_operand" "=r,r, r,r,r,r")
1021 (plus:HI (match_operand:HI 1 "register_operand" "%0,0, 0,0,0,r")
fb062a8b
HPN
1022 (match_operand:HI 2 "general_operand" "r,Q>,J,N,g,!To")))
1023 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1024 ""
0b85d816
HPN
1025 "@
1026 add.w %2,%0
1027 add.w %2,%0
1028 addq %2,%0
1029 subq %n2,%0
1030 add.w %2,%0
1031 add.w %2,%1,%0"
1032 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
e561b9fe 1033 (set_attr "cc<ccnz>" "normal,normal,clobber,clobber,normal,normal")])
0b85d816 1034
e561b9fe 1035(define_insn "*addqi3<setnz>"
23369bef
HPN
1036 [(set (match_operand:QI 0 "register_operand" "=r,r, r,r,r,r,r")
1037 (plus:QI (match_operand:QI 1 "register_operand" "%0,0, 0,0,0,0,r")
fb062a8b
HPN
1038 (match_operand:QI 2 "general_operand" "r,Q>,J,N,O,g,!To")))
1039 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1040 ""
0b85d816
HPN
1041 "@
1042 add.b %2,%0
1043 add.b %2,%0
1044 addq %2,%0
1045 subq %n2,%0
1046 subQ -%b2,%0
1047 add.b %2,%0
1048 add.b %2,%1,%0"
1049 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no")
e561b9fe 1050 (set_attr "cc<ccnz>" "normal,normal,clobber,clobber,clobber,normal,normal")])
0b85d816
HPN
1051\f
1052;; Subtract.
1053;;
1054;; Note that because of insn canonicalization these will *seldom* but
1055;; rarely be used with a known constant as an operand.
1056
1057;; Note that for the 'P' constraint, the high part can be -1 or 0. We
1058;; output the insn through the 'D' output modifier as "subs.w" and "subq",
1059;; respectively.
45d5d09c 1060(define_expand "subdi3"
fb062a8b
HPN
1061 [(parallel
1062 [(set (match_operand:DI 0 "register_operand")
1063 (minus:DI (match_operand:DI 1 "register_operand")
1064 (match_operand:DI 2 "general_operand")))
1065 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c 1066 ""
d0780379 1067 "")
45d5d09c 1068
e561b9fe 1069(define_insn "*subdi3<setnz>"
0b85d816
HPN
1070 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
1071 (minus:DI (match_operand:DI 1 "register_operand" "0,0,0,0,r")
fb062a8b
HPN
1072 (match_operand:DI 2 "general_operand" "J,N,P,g,!To")))
1073 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1074 ""
0b85d816
HPN
1075 "@
1076 subq %2,%M0\;ax\;subq 0,%H0
1077 addq %n2,%M0\;ax\;addq 0,%H0
1078 sub%e2.%z2 %2,%M0\;ax\;%D2 %H2,%H0
1079 sub.d %M2,%M0\;ax\;sub.d %H2,%H0
1080 sub.d %M2,%M1,%M0\;ax\;sub.d %H2,%H1,%H0")
1081
45d5d09c 1082(define_expand "sub<mode>3"
fb062a8b
HPN
1083 [(parallel
1084 [(set (match_operand:BWD 0 "register_operand")
1085 (minus:BWD
1086 (match_operand:BWD 1 "register_operand")
1087 (match_operand:BWD 2 "general_operand")))
1088 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c
HPN
1089 ""
1090 "")
1091
e561b9fe 1092(define_insn "*subsi3<setnz>"
23369bef 1093 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r,r,r")
0b85d816 1094 (minus:SI
23369bef 1095 (match_operand:SI 1 "register_operand" "0,0, 0,0,0,0,0,r")
fb062a8b
HPN
1096 (match_operand:SI 2 "general_operand" "r,Q>,J,N,P,n,g,!To")))
1097 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1098 ""
0b85d816
HPN
1099
1100;; This does not do the optimal: "addu.w 65535,r0" when %2 is negative.
1101;; But then again, %2 should not be negative.
1102
1103 "@
1104 sub.d %2,%0
1105 sub.d %2,%0
1106 subq %2,%0
1107 addq %n2,%0
1108 sub%e2.%z2 %2,%0
1109 sub.d %2,%0
1110 sub.d %2,%0
1111 sub.d %2,%1,%0"
1112 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,no")])
1113\f
e561b9fe 1114(define_insn "*sub<mode>3<setnz>"
22c3c091
HPN
1115 [(set (match_operand:BW 0 "register_operand" "=r,r, r,r,r,r")
1116 (minus:BW (match_operand:BW 1 "register_operand" "0,0, 0,0,0,r")
fb062a8b
HPN
1117 (match_operand:BW 2 "general_operand" "r,Q>,J,N,g,!To")))
1118 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1119 ""
0b85d816 1120 "@
22c3c091
HPN
1121 sub<m> %2,%0
1122 sub<m> %2,%0
0b85d816
HPN
1123 subq %2,%0
1124 addq %n2,%0
22c3c091
HPN
1125 sub<m> %2,%0
1126 sub<m> %2,%1,%0"
0b85d816 1127 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
e561b9fe 1128 (set_attr "cc<ccnz>" "normal,normal,clobber,clobber,normal,normal")])
0b85d816 1129\f
65f8403f
HPN
1130;; Extend versions (zero/sign) of normal add/sub (no side-effects).
1131
1132;; QImode to HImode
1133;; FIXME: GCC should widen.
1134
9596eccb 1135(define_insn "*<addsub><su>qihi"
65f8403f 1136 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
9596eccb
HPN
1137 (plusminus:HI
1138 (match_operand:HI 1 "register_operand" "0,0,0,r")
1139 (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To"))))
65f8403f
HPN
1140 (clobber (reg:CC CRIS_CC0_REGNUM))]
1141 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
9596eccb 1142 && (operands[1] != frame_pointer_rtx || <plusminus:CODE> != PLUS)"
65f8403f 1143 "@
9596eccb
HPN
1144 <addsub><su>.b %2,%0
1145 <addsub><su>.b %2,%0
1146 <addsub><su>.b %2,%0
1147 <addsub><su>.b %2,%1,%0"
65f8403f
HPN
1148 [(set_attr "slottable" "yes,yes,no,no")
1149 (set_attr "cc" "clobber")])
1150
9596eccb
HPN
1151;; FIXME: bound is actually also <setnzvc>, but is so rarely used in this
1152;; form that it's not worthwhile to make that distinction.
1153(define_insn "*<addsubbo><su><nd><mode>si<setnz>"
65f8403f 1154 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
9596eccb
HPN
1155 (plusminusumin:SI
1156 (match_operand:SI 1 "register_operand" "0,0,0,r")
1157 (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To"))))
65f8403f 1158 (clobber (reg:CC CRIS_CC0_REGNUM))]
9596eccb
HPN
1159 "(<plusminusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND)
1160 && (operands[1] != frame_pointer_rtx || <plusminusumin:CODE> != PLUS)"
65f8403f 1161 "@
9596eccb
HPN
1162 <addsubbo><su><nd><m> %2,%0
1163 <addsubbo><su><nd><m> %2,%0
1164 <addsubbo><su><nd><m> %2,%0
1165 <addsubbo><su><nd><m> %2,%1,%0"
65f8403f
HPN
1166 [(set_attr "slottable" "yes,yes,no,no")])
1167\f
1168;; We may have swapped operands for add or bound.
1169;; For commutative operands, these are the canonical forms.
1170
1171;; QImode to HImode
1172
9596eccb 1173(define_insn "*add<su>qihi_swap"
65f8403f
HPN
1174 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1175 (plus:HI
9596eccb 1176 (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To"))
65f8403f
HPN
1177 (match_operand:HI 1 "register_operand" "0,0,0,r")))
1178 (clobber (reg:CC CRIS_CC0_REGNUM))]
1179 "operands[1] != frame_pointer_rtx"
1180 "@
9596eccb
HPN
1181 add<su>.b %2,%0
1182 add<su>.b %2,%0
1183 add<su>.b %2,%0
1184 add<su>.b %2,%1,%0"
65f8403f
HPN
1185 [(set_attr "slottable" "yes,yes,no,no")
1186 (set_attr "cc" "clobber")])
1187
9596eccb 1188(define_insn "*<addsubbo><su><nd><mode>si<setnz>_swap"
65f8403f 1189 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
9596eccb
HPN
1190 (plusumin:SI
1191 (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To"))
1192 (match_operand:SI 1 "register_operand" "0,0,0,r")))
65f8403f 1193 (clobber (reg:CC CRIS_CC0_REGNUM))]
9596eccb 1194 "(<plusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND)
65f8403f
HPN
1195 && operands[1] != frame_pointer_rtx"
1196 "@
9596eccb
HPN
1197 <addsubbo><su><nd><m> %2,%0
1198 <addsubbo><su><nd><m> %2,%0
1199 <addsubbo><su><nd><m> %2,%0
1200 <addsubbo><su><nd><m> %2,%1,%0"
65f8403f
HPN
1201 [(set_attr "slottable" "yes,yes,no,no")])
1202\f
0b85d816
HPN
1203;; This is the special case when we use what corresponds to the
1204;; instruction above in "casesi". Do *not* change it to use the generic
1205;; pattern and "REG 15" as pc; I did that and it led to madness and
1206;; maintenance problems: Instead of (as imagined) recognizing and removing
1207;; or replacing this pattern with something simpler, other variant
1208;; patterns were recognized or combined, including some prefix variants
1209;; where the value in pc is not that of the next instruction (which means
1210;; this instruction actually *is* special and *should* be marked as such).
1211;; When switching from the "generic pattern match" approach to this simpler
1212;; approach, there were insignificant differences in gcc, ipps and
1213;; product code, somehow due to scratching reload behind the ear or
1214;; something. Testcase "gcc" looked .01% slower and 4 bytes bigger;
1215;; product code became .001% smaller but "looked better". The testcase
1216;; "ipps" was just different at register allocation).
1217;;
1218;; Assumptions in the jump optimizer forces us to use IF_THEN_ELSE in this
1219;; pattern with the default-label as the else, with the "if" being
1220;; index-is-less-than the max number of cases plus one. The default-label
1221;; is attached to the end of the case-table at time of output.
1222
1223(define_insn "*casesi_adds_w"
1224 [(set (pc)
1225 (if_then_else
1226 (ltu (match_operand:SI 0 "register_operand" "r")
1227 (match_operand:SI 1 "const_int_operand" "n"))
1228 (plus:SI (sign_extend:SI
1229 (mem:HI
1230 (plus:SI (mult:SI (match_dup 0) (const_int 2))
1231 (pc))))
1232 (pc))
1233 (label_ref (match_operand 2 "" ""))))
fb062a8b
HPN
1234 (use (label_ref (match_operand 3 "" "")))
1235 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1236 "operands[0] != frame_pointer_rtx"
0b85d816
HPN
1237 "adds.w [$pc+%0.w],$pc"
1238 [(set_attr "cc" "clobber")])
1239\f
1240;; Multiply instructions.
1241
1242;; Sometimes powers of 2 (which are normally canonicalized to a
1243;; left-shift) appear here, as a result of address reloading.
1244;; As a special, for values 3 and 5, we can match with an addi, so add those.
1245;;
1246;; FIXME: This may be unnecessary now.
1247;; Explicitly named for convenience of having a gen_... function.
1248
1249(define_insn "addi_mul"
1250 [(set (match_operand:SI 0 "register_operand" "=r")
1251 (mult:SI
1252 (match_operand:SI 1 "register_operand" "%0")
fb062a8b
HPN
1253 (match_operand:SI 2 "const_int_operand" "n")))
1254 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1255 "operands[0] != frame_pointer_rtx
1256 && operands[1] != frame_pointer_rtx
991c42ac 1257 && CONST_INT_P (operands[2])
0b85d816
HPN
1258 && (INTVAL (operands[2]) == 2
1259 || INTVAL (operands[2]) == 4 || INTVAL (operands[2]) == 3
1260 || INTVAL (operands[2]) == 5)"
0b85d816
HPN
1261{
1262 if (INTVAL (operands[2]) == 2)
22c3c091 1263 return "lslq 1,%0";
0b85d816 1264 else if (INTVAL (operands[2]) == 4)
22c3c091 1265 return "lslq 2,%0";
0b85d816 1266 else if (INTVAL (operands[2]) == 3)
22c3c091 1267 return "addi %0.w,%0";
0b85d816 1268 else if (INTVAL (operands[2]) == 5)
22c3c091
HPN
1269 return "addi %0.d,%0";
1270 return "BAD: adr_mulsi: %0=%1*%2";
1271}
0b85d816
HPN
1272[(set_attr "slottable" "yes")
1273 ;; No flags are changed if this insn is "addi", but it does not seem
1274 ;; worth the trouble to distinguish that to the lslq cases.
1275 (set_attr "cc" "clobber")])
1276
1277;; The addi insn as it is normally used.
1278
1279(define_insn "*addi"
d0780379 1280 [(set (match_operand:SI 0 "register_operand" "=r")
0b85d816 1281 (plus:SI
6cb68940
HPN
1282 (ashift:SI (match_operand:SI 2 "register_operand" "r")
1283 (match_operand:SI 3 "const_int_operand" "n"))
d0780379 1284 (match_operand:SI 1 "register_operand" "0")))]
0b85d816
HPN
1285 "operands[0] != frame_pointer_rtx
1286 && operands[1] != frame_pointer_rtx
991c42ac 1287 && CONST_INT_P (operands[3])
6cb68940 1288 && (INTVAL (operands[3]) == 1 || INTVAL (operands[3]) == 2)"
d0780379 1289 "addi %2%T3,%0"
0b85d816
HPN
1290 [(set_attr "slottable" "yes")
1291 (set_attr "cc" "none")])
1292
6cb68940
HPN
1293;; The mult-vs-ashift canonicalization-cleanup plagues us: nothing in
1294;; reload transforms a "scaled multiplication" into an ashift in a
1295;; reloaded address; it's passed as-is and expected to be recognized,
1296;; or else we get a tell-tale "unrecognizable insn".
1297;; On top of that, we *should* match the bare insn, as a *matching
1298;; pattern* (as opposed to e.g. a reload_load_address expander
1299;; changing the mul into an ashift), so can_reload_into will re-use
1300;; registers in the reloaded expression instead of allocating a new
1301;; register.
1302(define_insn_and_split "*addi_reload"
1303 [(set (match_operand:SI 0 "register_operand" "=r")
1304 (plus:SI
1305 (mult:SI (match_operand:SI 2 "register_operand" "r")
1306 (match_operand:SI 3 "const_int_operand" "n"))
1307 (match_operand:SI 1 "register_operand" "0")))]
1308 "operands[0] != frame_pointer_rtx
1309 && operands[1] != frame_pointer_rtx
1310 && CONST_INT_P (operands[3])
1311 && (INTVAL (operands[3]) == 2 || INTVAL (operands[3]) == 4)
1312 && (reload_in_progress || reload_completed)"
1313 "#"
47d25a03 1314 "&& 1"
6cb68940
HPN
1315 [(set (match_dup 0)
1316 (plus:SI (ashift:SI (match_dup 2) (match_dup 3)) (match_dup 1)))]
1317 "operands[3] = operands[3] == const2_rtx ? const1_rtx : const2_rtx;")
1318
ef07c7a5
HPN
1319;; This pattern is usually generated after reload, so a '%' is
1320;; ineffective; use explicit combinations.
1321(define_insn "*addi_b_<mode>"
1322 [(set (match_operand:BWD 0 "register_operand" "=r,r")
1323 (plus:BWD
1324 (match_operand:BWD 1 "register_operand" "0,r")
1325 (match_operand:BWD 2 "register_operand" "r,0")))]
1326 ""
1327 "@
1328 addi %2.b,%0
1329 addi %1.b,%0"
1330 [(set_attr "slottable" "yes")])
1331
1332;; Strip the dccr clobber from addM3 with register operands, if the
1333;; next instruction isn't using it.
1334;; Not clobbering dccr may let cmpelim match a later compare with a
1335;; previous operation of interest. This has to run before cmpelim so it
1336;; can't be a peephole2. See gcc.target/cris/pr93372-45.c for a
1337;; test-case.
1338(define_split ;; "*add<mode>3_addi"
1339 [(parallel
1340 [(set (match_operand:BWD 0 "register_operand")
1341 (plus:BWD
1342 (match_operand:BWD 1 "register_operand")
1343 (match_operand:BWD 2 "register_operand")))
1344 (clobber (reg:CC CRIS_CC0_REGNUM))])]
1345 "reload_completed"
1346 [(set (match_dup 0) (plus:BWD (match_dup 1) (match_dup 2)))]
1347{
1348 rtx reg = operands[0];
1349 rtx_insn *i = next_nonnote_nondebug_insn_bb (curr_insn);
1350
1351 while (i != NULL_RTX && (!INSN_P (i) || DEBUG_INSN_P (i)))
1352 i = next_nonnote_nondebug_insn_bb (i);
1353
1354 if (i == NULL_RTX || reg_mentioned_p (reg, i) || BARRIER_P (i))
1355 FAIL;
1356})
1357
22c3c091
HPN
1358(define_insn "<u>mul<s><mode>3"
1359 [(set (match_operand:WD 0 "register_operand" "=r")
1360 (mult:WD
1361 (szext:WD (match_operand:<S> 1 "register_operand" "%0"))
1362 (szext:WD (match_operand:<S> 2 "register_operand" "r"))))
fb062a8b
HPN
1363 (clobber (match_scratch:SI 3 "=h"))
1364 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 1365 "TARGET_HAS_MUL_INSNS"
22c3c091 1366 "%!mul<su><mm> %2,%0"
86da66b5 1367 [(set (attr "slottable")
bf0b8cbe 1368 (if_then_else (match_test "TARGET_MUL_BUG")
86da66b5
HPN
1369 (const_string "no")
1370 (const_string "yes")))
22c3c091
HPN
1371 ;; For umuls.[bwd] it's just N unusable here, but let's be safe.
1372 ;; For muls.b, this really extends to SImode, so cc should be
1373 ;; considered clobbered.
1374 ;; For muls.w, it's just N unusable here, but let's be safe.
0b85d816
HPN
1375 (set_attr "cc" "clobber")])
1376
1377;; Note that gcc does not make use of such a thing as umulqisi3. It gets
1378;; confused and will erroneously use it instead of umulhisi3, failing (at
1379;; least) gcc.c-torture/execute/arith-rand.c at all optimization levels.
1380;; Inspection of optab code shows that there must be only one widening
1381;; multiplication per mode widened to.
1382
1383(define_insn "mulsi3"
1384 [(set (match_operand:SI 0 "register_operand" "=r")
ef6201a6 1385 (mult:SI (match_operand:SI 1 "register_operand" "%0")
f60c7155 1386 (match_operand:SI 2 "register_operand" "r")))
fb062a8b
HPN
1387 (clobber (match_scratch:SI 3 "=h"))
1388 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 1389 "TARGET_HAS_MUL_INSNS"
86da66b5
HPN
1390 "%!muls.d %2,%0"
1391 [(set (attr "slottable")
bf0b8cbe 1392 (if_then_else (match_test "TARGET_MUL_BUG")
86da66b5
HPN
1393 (const_string "no")
1394 (const_string "yes")))
0b85d816
HPN
1395 ;; Just N unusable here, but let's be safe.
1396 (set_attr "cc" "clobber")])
1397\f
1398;; A few multiply variations.
1399
0b85d816
HPN
1400;; When needed, we can get the high 32 bits from the overflow
1401;; register. We don't care to split and optimize these.
0b85d816 1402
22c3c091 1403(define_insn "<u>mulsidi3"
0b85d816
HPN
1404 [(set (match_operand:DI 0 "register_operand" "=r")
1405 (mult:DI
22c3c091
HPN
1406 (szext:DI (match_operand:SI 1 "register_operand" "%0"))
1407 (szext:DI (match_operand:SI 2 "register_operand" "r"))))
fb062a8b
HPN
1408 (clobber (match_scratch:SI 3 "=h"))
1409 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 1410 "TARGET_HAS_MUL_INSNS"
22c3c091 1411 "%!mul<su>.d %2,%M0\;move $mof,%H0")
0b85d816 1412
f60c7155
HPN
1413;; These two patterns may be expressible by other means, perhaps by making
1414;; [u]?mulsidi3 a define_expand.
1415
1416;; Due to register allocation braindamage, the clobber 1,2 alternatives
1417;; cause a move into the clobbered register *before* the insn, then
1418;; after the insn, mof is moved too, rather than the clobber assigned
1419;; the last mof target. This became apparent when making MOF and SRP
1420;; visible registers, with the necessary tweak to smulsi3_highpart.
1421;; Because these patterns are used in division by constants, that damage
1422;; is visible (ipps regression tests). Therefore the last two
1423;; alternatives, "helping" reload to avoid an unnecessary move, but
1424;; punished by force of one "?". Check code from "int d (int a) {return
1425;; a / 1000;}" and unsigned. FIXME: Comment above was for 3.2, revisit.
0b85d816 1426
22c3c091 1427(define_insn "<su>mulsi3_highpart"
45d5d09c 1428 [(set (match_operand:SI 0 "register_operand" "=h,h,?r,?r")
0b85d816
HPN
1429 (truncate:SI
1430 (lshiftrt:DI
1431 (mult:DI
22c3c091
HPN
1432 (szext:DI (match_operand:SI 1 "register_operand" "r,r,0,r"))
1433 (szext:DI (match_operand:SI 2 "register_operand" "r,r,r,0")))
0b85d816 1434 (const_int 32))))
fb062a8b
HPN
1435 (clobber (match_scratch:SI 3 "=1,2,h,h"))
1436 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 1437 "TARGET_HAS_MUL_INSNS"
f60c7155 1438 "@
22c3c091
HPN
1439 %!mul<su>.d %2,%1
1440 %!mul<su>.d %1,%2
1441 %!mul<su>.d %2,%1\;move $mof,%0
1442 %!mul<su>.d %1,%2\;move $mof,%0"
f60c7155
HPN
1443 [(set_attr "slottable" "yes,yes,no,no")
1444 (set_attr "cc" "clobber")])
0b85d816
HPN
1445\f
1446;; Divide and modulus instructions. CRIS only has a step instruction.
1447
1448(define_insn "dstep_shift"
1449 [(set (match_operand:SI 0 "register_operand" "=r")
1450 (if_then_else:SI
1451 (geu:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1452 (const_int 1))
1453 (match_operand:SI 2 "register_operand" "r"))
1454 (minus:SI (ashift:SI (match_operand:SI 3 "register_operand" "0")
1455 (const_int 1))
1456 (match_operand:SI 4 "register_operand" "2"))
1457 (ashift:SI (match_operand:SI 5 "register_operand" "0")
fb062a8b
HPN
1458 (const_int 1))))
1459 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1460 ""
1461 "dstep %2,%0"
d0780379 1462 [(set_attr "slottable" "yes")])
0b85d816
HPN
1463
1464;; Here's a variant with mult instead of ashift.
1465;;
1466;; FIXME: This should be investigated. Which one matches through combination?
1467
1468(define_insn "dstep_mul"
1469 [(set (match_operand:SI 0 "register_operand" "=r")
1470 (if_then_else:SI
1471 (geu:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
1472 (const_int 2))
1473 (match_operand:SI 2 "register_operand" "r"))
1474 (minus:SI (mult:SI (match_operand:SI 3 "register_operand" "0")
1475 (const_int 2))
1476 (match_operand:SI 4 "register_operand" "2"))
1477 (mult:SI (match_operand:SI 5 "register_operand" "0")
fb062a8b
HPN
1478 (const_int 2))))
1479 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1480 "operands[0] != frame_pointer_rtx
1481 && operands[1] != frame_pointer_rtx
1482 && operands[2] != frame_pointer_rtx
1483 && operands[3] != frame_pointer_rtx"
1484 "dstep %2,%0"
d0780379 1485 [(set_attr "slottable" "yes")])
0b85d816
HPN
1486\f
1487;; Logical operators.
1488
1489;; Bitwise "and".
1490
1491;; There is no use in defining "anddi3", because gcc can expand this by
1492;; itself, and make reasonable code without interference.
1493
1494;; If the first operand is memory or a register and is the same as the
1495;; second operand, and the third operand is -256 or -65536, we can use
1496;; CLEAR instead. Or, if the first operand is a register, and the third
1497;; operand is 255 or 65535, we can zero_extend.
f5143c46 1498;; GCC isn't smart enough to recognize these cases (yet), and they seem
0b85d816
HPN
1499;; to be common enough to be worthwhile.
1500;; FIXME: This should be made obsolete.
1501
1502(define_expand "andsi3"
fb062a8b
HPN
1503 [(parallel
1504 [(set (match_operand:SI 0 "nonimmediate_operand")
1505 (and:SI (match_operand:SI 1 "nonimmediate_operand")
1506 (match_operand:SI 2 "general_operand")))
1507 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 1508 ""
0b85d816 1509{
991c42ac 1510 if (! (CONST_INT_P (operands[2])
0b85d816
HPN
1511 && (((INTVAL (operands[2]) == -256
1512 || INTVAL (operands[2]) == -65536)
1513 && rtx_equal_p (operands[1], operands[0]))
1514 || ((INTVAL (operands[2]) == 255
1515 || INTVAL (operands[2]) == 65535)
1516 && REG_P (operands[0])))))
1517 {
1518 /* Make intermediate steps if operand0 is not a register or
1519 operand1 is not a register, and hope that the reload pass will
1520 make something useful out of it. Note that the operands are
1521 *not* canonicalized. For the moment, I chicken out on this,
1522 because all or most ports do not describe 'and' with
1523 canonicalized operands, and I seem to remember magic in reload,
1524 checking that operand1 has constraint '%0', in which case
1525 operand0 and operand1 must have similar predicates.
1526 FIXME: Investigate. */
1527 rtx reg0 = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
1528 rtx reg1 = operands[1];
1529
1530 if (! REG_P (reg1))
1531 {
1532 emit_move_insn (reg0, reg1);
1533 reg1 = reg0;
1534 }
1535
fb062a8b
HPN
1536 cris_emit_insn (gen_rtx_SET (reg0, gen_rtx_AND (SImode, reg1,
1537 operands[2])));
0b85d816
HPN
1538
1539 /* Make sure we get the right *final* destination. */
1540 if (! REG_P (operands[0]))
1541 emit_move_insn (operands[0], reg0);
1542
1543 DONE;
1544 }
22c3c091 1545})
0b85d816
HPN
1546
1547;; Some special cases of andsi3.
1548
1549(define_insn "*andsi_movu"
1550 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
428eae94 1551 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q,To")
fb062a8b
HPN
1552 (match_operand:SI 2 "const_int_operand" "n,n,n")))
1553 (clobber (reg:CC CRIS_CC0_REGNUM))]
f38a62ff 1554 "(INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535)
c3e786e7 1555 && !side_effects_p (operands[1])"
0b85d816
HPN
1556 "movu.%z2 %1,%0"
1557 [(set_attr "slottable" "yes,yes,no")])
1558
fb062a8b
HPN
1559;; FIXME: Remember, this does *not* actually affect condition codes;
1560;; get rid of the clobber.
0b85d816 1561(define_insn "*andsi_clear"
f38a62ff 1562 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q,Q,To,To")
0b85d816 1563 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
fb062a8b
HPN
1564 (match_operand:SI 2 "const_int_operand" "P,n,P,n,P,n")))
1565 (clobber (reg:CC CRIS_CC0_REGNUM))]
f38a62ff 1566 "(INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256)
c3e786e7 1567 && !side_effects_p (operands[0])"
0b85d816
HPN
1568 "@
1569 cLear.b %0
1570 cLear.w %0
1571 cLear.b %0
1572 cLear.w %0
1573 cLear.b %0
1574 cLear.w %0"
1575 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
1576 (set_attr "cc" "none")])
1577
1578;; This is a catch-all pattern, taking care of everything that was not
1579;; matched in the insns above.
1580;;
1581;; Sidenote: the tightening from "nonimmediate_operand" to
1582;; "register_operand" for operand 1 actually increased the register
1583;; pressure (worse code). That will hopefully change with an
1584;; improved reload pass.
1585
730cafef 1586(define_insn "*expanded_andsi<setcc><setnz><setnzvc>"
23369bef
HPN
1587 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r,r")
1588 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0,r")
fb062a8b
HPN
1589 (match_operand:SI 2 "general_operand" "I,r,Q>,g,!To")))
1590 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1591 ""
0b85d816
HPN
1592 "@
1593 andq %2,%0
1594 and.d %2,%0
1595 and.d %2,%0
1596 and.d %2,%0
1597 and.d %2,%1,%0"
1598 [(set_attr "slottable" "yes,yes,yes,no,no")])
1599\f
1600;; For both QI and HI we may use the quick patterns. This results in
1601;; useless condition codes, but that is used rarely enough for it to
fb062a8b
HPN
1602;; normally be a win (could check ahead for use of CRIS_CC0_REGNUM, but
1603;; seems to be more pain than win).
0b85d816
HPN
1604
1605;; FIXME: See note for andsi3
1606
1607(define_expand "andhi3"
fb062a8b
HPN
1608 [(parallel
1609 [(set (match_operand:HI 0 "nonimmediate_operand")
1610 (and:HI (match_operand:HI 1 "nonimmediate_operand")
1611 (match_operand:HI 2 "general_operand")))
1612 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 1613 ""
0b85d816 1614{
991c42ac 1615 if (! (CONST_INT_P (operands[2])
0b85d816
HPN
1616 && (((INTVAL (operands[2]) == -256
1617 || INTVAL (operands[2]) == 65280)
1618 && rtx_equal_p (operands[1], operands[0]))
1619 || (INTVAL (operands[2]) == 255
1620 && REG_P (operands[0])))))
1621 {
1622 /* See comment for andsi3. */
1623 rtx reg0 = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (HImode);
1624 rtx reg1 = operands[1];
1625
1626 if (! REG_P (reg1))
1627 {
1628 emit_move_insn (reg0, reg1);
1629 reg1 = reg0;
1630 }
1631
fb062a8b
HPN
1632 cris_emit_insn (gen_rtx_SET (reg0, gen_rtx_AND (HImode, reg1,
1633 operands[2])));
0b85d816
HPN
1634
1635 /* Make sure we get the right destination. */
1636 if (! REG_P (operands[0]))
1637 emit_move_insn (operands[0], reg0);
1638
1639 DONE;
1640 }
22c3c091 1641})
0b85d816
HPN
1642
1643;; Some fast andhi3 special cases.
1644
1645(define_insn "*andhi_movu"
1646 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
428eae94 1647 (and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q,To")
fb062a8b
HPN
1648 (const_int 255)))
1649 (clobber (reg:CC CRIS_CC0_REGNUM))]
c3e786e7 1650 "!side_effects_p (operands[1])"
0b85d816
HPN
1651 "mOvu.b %1,%0"
1652 [(set_attr "slottable" "yes,yes,no")])
1653
f38a62ff
HPN
1654(define_insn "*andhi_clear"
1655 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q,To")
0b85d816 1656 (and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
fb062a8b
HPN
1657 (const_int -256)))
1658 (clobber (reg:CC CRIS_CC0_REGNUM))]
c3e786e7 1659 "!side_effects_p (operands[0])"
0b85d816
HPN
1660 "cLear.b %0"
1661 [(set_attr "slottable" "yes,yes,no")
1662 (set_attr "cc" "none")])
1663
1664;; Catch-all andhi3 pattern.
1665
730cafef
HPN
1666(define_insn "*expanded_andhi<setcc><setnz><setnzvc>"
1667 [(set (match_operand:HI 0 "register_operand" "=r,r, r,r, r,r,r,r")
1668 (and:HI (match_operand:HI 1 "register_operand" "%0,0, 0,0, 0,0,0,r")
1669 (match_operand:HI 2 "general_operand" "I,Kc,r,Q>,L,O,g,!To")))
1670 ;; The "Kc" alternative above, is there to match for cmpelim;
1671 ;; it will be dominated by the "I" alternative at other times.
fb062a8b 1672 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1673
1674;; Sidenote: the tightening from "general_operand" to
1675;; "register_operand" for operand 1 actually increased the register
1676;; pressure (worse code). That will hopefully change with an
1677;; improved reload pass.
1678
d0780379 1679 ""
0b85d816 1680 "@
730cafef 1681 andq %2,%0
0b85d816
HPN
1682 andq %2,%0
1683 and.w %2,%0
1684 and.w %2,%0
1685 and.w %2,%0
1686 anDq %b2,%0
1687 and.w %2,%0
1688 and.w %2,%1,%0"
730cafef
HPN
1689 [(set_attr "slottable" "yes,yes,yes,yes,no,yes,no,no")
1690 (set_attr "cc<cccc><ccnz><ccnzvc>"
1691 "clobber,normal,normal,normal,normal,clobber,normal,normal")])
0b85d816
HPN
1692
1693;; A strict_low_part pattern.
1694
d7173593
HPN
1695;; Note the use of (match_dup 0) for the first operand of the operation
1696;; here. Reload can't handle an operand pair where one is read-write
1697;; and must match a read, like in:
1698;; (insn 80 79 81 4
1699;; (set (strict_low_part
1700;; (subreg:QI (reg/v:SI 0 r0 [orig:36 data ] [36]) 0))
1701;; (and:QI
1702;; (subreg:QI (reg:SI 15 acr [orig:27 D.7531 ] [27]) 0)
1703;; (const_int -64 [0xf..fc0]))) x.c:126 147 {*andqi_lowpart_v32}
1704;; (nil))
d0780379 1705;; (Note: the example is obsolete.)
d7173593
HPN
1706;; In theory, it could reload this as a movstrictqi of the register
1707;; operand at the and:QI to the destination register and change the
1708;; and:QI operand to the same as the read-write output operand and the
1709;; result would be recognized, but it doesn't recognize that's a valid
1710;; reload for a strict_low_part-destination; it just sees a "+" at the
1711;; destination constraints. Better than adding complexity to reload is
1712;; to follow the lead of m68k (see comment that begins with "These insns
1713;; must use MATCH_DUP") since prehistoric times and make it just a
1714;; match_dup. FIXME: a sanity-check in gen* to refuse an insn with
1715;; input-constraints matching input-output-constraints, e.g. "+r" <- "0".
1716
d0780379 1717(define_insn "*andhi_lowpart"
0b85d816 1718 [(set (strict_low_part
d7173593
HPN
1719 (match_operand:HI 0 "register_operand" "+r,r,r"))
1720 (and:HI (match_dup 0)
fb062a8b
HPN
1721 (match_operand:HI 1 "general_operand" "r,Q>,g")))
1722 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1723 ""
0b85d816 1724 "@
d7173593
HPN
1725 and.w %1,%0
1726 and.w %1,%0
1727 and.w %1,%0"
1728 [(set_attr "slottable" "yes,yes,no")])
0b85d816 1729\f
45d5d09c 1730(define_expand "andqi3"
fb062a8b
HPN
1731 [(parallel
1732 [(set (match_operand:QI 0 "register_operand")
1733 (and:QI (match_operand:QI 1 "register_operand")
1734 (match_operand:QI 2 "general_operand")))
1735 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c
HPN
1736 ""
1737 "")
1738
730cafef
HPN
1739(define_insn "*andqi3<setcc><setnz><setnzvc>"
1740 [(set (match_operand:QI 0 "register_operand" "=r,r, r,r, r,r,r")
1741 (and:QI (match_operand:QI 1 "register_operand" "%0,0, 0,0, 0,0,r")
1742 (match_operand:QI 2 "general_operand" "I,Kc,r,Q>,O,g,!To")))
fb062a8b 1743 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1744 ""
0b85d816 1745 "@
730cafef 1746 andq %2,%0
0b85d816
HPN
1747 andq %2,%0
1748 and.b %2,%0
1749 and.b %2,%0
1750 andQ %b2,%0
1751 and.b %2,%0
1752 and.b %2,%1,%0"
730cafef
HPN
1753 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no")
1754 (set_attr "cc<cccc><ccnz><ccnzvc>"
1755 "clobber,normal,normal,normal,clobber,normal,normal")])
0b85d816 1756
d0780379 1757(define_insn "*andqi_lowpart"
0b85d816 1758 [(set (strict_low_part
d7173593
HPN
1759 (match_operand:QI 0 "register_operand" "+r,r,r"))
1760 (and:QI (match_dup 0)
fb062a8b
HPN
1761 (match_operand:QI 1 "general_operand" "r,Q>,g")))
1762 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1763 ""
0b85d816 1764 "@
d7173593
HPN
1765 and.b %1,%0
1766 and.b %1,%0
1767 and.b %1,%0"
1768 [(set_attr "slottable" "yes,yes,no")])
0b85d816
HPN
1769\f
1770;; Bitwise or.
1771
1772;; Same comment as anddi3 applies here - no need for such a pattern.
1773
1774;; It seems there's no need to jump through hoops to get good code such as
1775;; with andsi3.
1776
45d5d09c 1777(define_expand "ior<mode>3"
fb062a8b
HPN
1778 [(parallel
1779 [(set (match_operand:BWD 0 "register_operand")
1780 (ior:BWD (match_operand:BWD 1 "register_operand")
1781 (match_operand:BWD 2 "general_operand")))
1782 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c
HPN
1783 ""
1784 "")
1785
730cafef 1786(define_insn "*iorsi3<setcc><setnz><setnzvc>"
23369bef
HPN
1787 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r,r,r")
1788 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0,0,r")
fb062a8b
HPN
1789 (match_operand:SI 2 "general_operand" "I, r,Q>,n,g,!To")))
1790 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1791 ""
0b85d816
HPN
1792 "@
1793 orq %2,%0
1794 or.d %2,%0
1795 or.d %2,%0
1796 oR.%s2 %2,%0
1797 or.d %2,%0
1798 or.d %2,%1,%0"
1799 [(set_attr "slottable" "yes,yes,yes,no,no,no")
730cafef
HPN
1800 (set_attr "cc<cccc><ccnz><ccnzvc>"
1801 "normal,normal,normal,clobber,normal,normal")])
0b85d816 1802
730cafef 1803(define_insn "*iorhi3<setcc><setnz><setnzvc>"
23369bef
HPN
1804 [(set (match_operand:HI 0 "register_operand" "=r,r,r, r,r,r,r")
1805 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0, 0,0,0,r")
fb062a8b
HPN
1806 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))
1807 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1808 ""
0b85d816
HPN
1809 "@
1810 orq %2,%0
1811 or.w %2,%0
1812 or.w %2,%0
1813 or.w %2,%0
1814 oRq %b2,%0
1815 or.w %2,%0
1816 or.w %2,%1,%0"
1817 [(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
730cafef
HPN
1818 (set_attr "cc<cccc><ccnz><ccnzvc>"
1819 "clobber,normal,normal,normal,clobber,normal,normal")])
0b85d816 1820
730cafef 1821(define_insn "*iorqi3<setcc><setnz><setnzvc>"
23369bef
HPN
1822 [(set (match_operand:QI 0 "register_operand" "=r,r,r, r,r,r")
1823 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0, 0,0,r")
fb062a8b
HPN
1824 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))
1825 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 1826 ""
0b85d816
HPN
1827 "@
1828 orq %2,%0
1829 or.b %2,%0
1830 or.b %2,%0
1831 orQ %b2,%0
1832 or.b %2,%0
1833 or.b %2,%1,%0"
1834 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
730cafef
HPN
1835 (set_attr "cc<cccc><ccnz><ccnzvc>"
1836 "clobber,normal,normal,clobber,normal,normal")])
0b85d816
HPN
1837\f
1838;; Exclusive-or
1839
1840;; See comment about "anddi3" for xordi3 - no need for such a pattern.
22c3c091 1841;; FIXME: Do we really need the shorter variants?
0b85d816 1842
730cafef 1843(define_insn "<acc><anz><anzvc>xorsi3<setcc><setnz><setnzvc>"
0b85d816
HPN
1844 [(set (match_operand:SI 0 "register_operand" "=r")
1845 (xor:SI (match_operand:SI 1 "register_operand" "%0")
fb062a8b
HPN
1846 (match_operand:SI 2 "register_operand" "r")))
1847 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1848 ""
1849 "xor %2,%0"
d0780379 1850 [(set_attr "slottable" "yes")])
0b85d816 1851
22c3c091
HPN
1852(define_insn "xor<mode>3"
1853 [(set (match_operand:BW 0 "register_operand" "=r")
1854 (xor:BW (match_operand:BW 1 "register_operand" "%0")
fb062a8b
HPN
1855 (match_operand:BW 2 "register_operand" "r")))
1856 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1857 ""
1858 "xor %2,%0"
1859 [(set_attr "slottable" "yes")
1860 (set_attr "cc" "clobber")])
1861\f
1862;; Negation insns.
1863
1864;; Questionable use, here mostly as a (slightly usable) define_expand
1865;; example.
1866
1867(define_expand "negsf2"
fb062a8b
HPN
1868 [(parallel
1869 [(set (match_dup 2) (match_dup 3))
1870 (clobber (reg:CC CRIS_CC0_REGNUM))])
1871 (parallel [(set (match_operand:SF 0 "register_operand")
1872 (neg:SF (match_operand:SF 1 "register_operand")))
1873 (use (match_dup 2))
1874 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 1875 ""
0b85d816
HPN
1876{
1877 operands[2] = gen_reg_rtx (SImode);
1878 operands[3] = GEN_INT (1 << 31);
22c3c091 1879})
0b85d816
HPN
1880
1881(define_insn "*expanded_negsf2"
1882 [(set (match_operand:SF 0 "register_operand" "=r")
1883 (neg:SF (match_operand:SF 1 "register_operand" "0")))
fb062a8b
HPN
1884 (use (match_operand:SI 2 "register_operand" "r"))
1885 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1886 ""
1887 "xor %2,%0"
1888 [(set_attr "slottable" "yes")])
1889
1890;; No "negdi2" although we could make one up that may be faster than
1891;; the one in libgcc.
1892
a33649e6 1893(define_insn "<anz>neg<mode>2<setnz>"
22c3c091 1894 [(set (match_operand:BWD 0 "register_operand" "=r")
fb062a8b
HPN
1895 (neg:BWD (match_operand:BWD 1 "register_operand" "r")))
1896 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 1897 ""
22c3c091 1898 "neg<m> %1,%0"
0b85d816
HPN
1899 [(set_attr "slottable" "yes")])
1900\f
1901;; One-complements.
1902
1903;; See comment on anddi3 - no need for a DImode pattern.
22c3c091 1904;; See also xor comment.
0b85d816 1905
730cafef 1906(define_insn "<acc><anz><anzvc>one_cmplsi2<setcc><setnz><setnzvc>"
0b85d816 1907 [(set (match_operand:SI 0 "register_operand" "=r")
fb062a8b
HPN
1908 (not:SI (match_operand:SI 1 "register_operand" "0")))
1909 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1910 ""
1911 "not %0"
d0780379 1912 [(set_attr "slottable" "yes")])
0b85d816 1913
22c3c091
HPN
1914(define_insn "one_cmpl<mode>2"
1915 [(set (match_operand:BW 0 "register_operand" "=r")
fb062a8b
HPN
1916 (not:BW (match_operand:BW 1 "register_operand" "0")))
1917 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
1918 ""
1919 "not %0"
1920 [(set_attr "slottable" "yes")
1921 (set_attr "cc" "clobber")])
1922\f
22c3c091 1923;; Arithmetic/Logical shift right (and SI left).
0b85d816 1924
d137723b 1925(define_insn "<acc><anz><anzvc><shlr>si3<setcc><setnz><setnzvc>"
0b85d816 1926 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 1927 (shift:SI (match_operand:SI 1 "register_operand" "0")
fb062a8b
HPN
1928 (match_operand:SI 2 "nonmemory_operand" "Kcr")))
1929 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 1930 ""
0b85d816
HPN
1931{
1932 if (REG_S_P (operands[2]))
22c3c091 1933 return "<slr>.d %2,%0";
0b85d816 1934
22c3c091
HPN
1935 return "<slr>q %2,%0";
1936}
d0780379 1937 [(set_attr "slottable" "yes")])
0b85d816 1938
22c3c091
HPN
1939;; Since gcc gets lost, and forgets to zero-extend the source (or mask
1940;; the destination) when it changes shifts of lower modes into SImode,
1941;; it is better to make these expands an anonymous patterns instead of
1942;; the more correct define_insns. This occurs when gcc thinks that is
1943;; is better to widen to SImode and use immediate shift count.
0b85d816 1944
22c3c091 1945;; FIXME: Is this legacy or still true for gcc >= 2.7.2?
0b85d816 1946
22c3c091
HPN
1947;; FIXME: Can't parametrize sign_extend and zero_extend (before
1948;; mentioning "shiftrt"), so we need two patterns.
1949(define_expand "ashr<mode>3"
fb062a8b
HPN
1950 [(parallel
1951 [(set (match_dup 3)
1952 (sign_extend:SI (match_operand:BW 1 "nonimmediate_operand")))
1953 (clobber (reg:CC CRIS_CC0_REGNUM))])
1954 (parallel
1955 [(set (match_dup 4)
1956 (zero_extend:SI (match_operand:BW 2 "nonimmediate_operand")))
1957 (clobber (reg:CC CRIS_CC0_REGNUM))])
1958 (parallel
1959 [(set (match_dup 5) (ashiftrt:SI (match_dup 3) (match_dup 4)))
1960 (clobber (reg:CC CRIS_CC0_REGNUM))])
1961 (parallel
1962 [(set (match_operand:BW 0 "general_operand")
1963 (subreg:BW (match_dup 5) 0))
1964 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 1965 ""
0b85d816
HPN
1966{
1967 int i;
1968
1969 for (i = 3; i < 6; i++)
1970 operands[i] = gen_reg_rtx (SImode);
22c3c091 1971})
0b85d816 1972
22c3c091 1973(define_expand "lshr<mode>3"
fb062a8b
HPN
1974 [(parallel
1975 [(set (match_dup 3)
1976 (zero_extend:SI (match_operand:BW 1 "nonimmediate_operand")))
1977 (clobber (reg:CC CRIS_CC0_REGNUM))])
1978 (parallel
1979 [(set (match_dup 4)
1980 (zero_extend:SI (match_operand:BW 2 "nonimmediate_operand")))
1981 (clobber (reg:CC CRIS_CC0_REGNUM))])
1982 (parallel
1983 [(set (match_dup 5) (lshiftrt:SI (match_dup 3) (match_dup 4)))
1984 (clobber (reg:CC CRIS_CC0_REGNUM))])
1985 (parallel
1986 [(set (match_operand:BW 0 "general_operand")
1987 (subreg:BW (match_dup 5) 0))
1988 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 1989 ""
0b85d816
HPN
1990{
1991 int i;
1992
1993 for (i = 3; i < 6; i++)
1994 operands[i] = gen_reg_rtx (SImode);
22c3c091 1995})
0b85d816 1996
22c3c091
HPN
1997(define_insn "*expanded_<shlr><mode>"
1998 [(set (match_operand:BW 0 "register_operand" "=r")
1999 (shiftrt:BW (match_operand:BW 1 "register_operand" "0")
fb062a8b
HPN
2000 (match_operand:BW 2 "register_operand" "r")))
2001 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 2002 ""
22c3c091 2003 "<slr><m> %2,%0"
d0780379 2004 [(set_attr "slottable" "yes")])
0b85d816 2005
22c3c091
HPN
2006(define_insn "*<shlr><mode>_lowpart"
2007 [(set (strict_low_part (match_operand:BW 0 "register_operand" "+r"))
2008 (shiftrt:BW (match_dup 0)
fb062a8b
HPN
2009 (match_operand:BW 1 "register_operand" "r")))
2010 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 2011 ""
22c3c091 2012 "<slr><m> %1,%0"
d0780379 2013 [(set_attr "slottable" "yes")])
0b85d816
HPN
2014\f
2015;; Arithmetic/logical shift left.
2016
0b85d816
HPN
2017;; For narrower modes than SI, we can use lslq although it makes cc
2018;; unusable. The win is that we do not have to reload the shift-count
2019;; into a register.
2020
22c3c091
HPN
2021(define_insn "ashl<mode>3"
2022 [(set (match_operand:BW 0 "register_operand" "=r,r")
2023 (ashift:BW (match_operand:BW 1 "register_operand" "0,0")
fb062a8b
HPN
2024 (match_operand:BW 2 "nonmemory_operand" "r,Kc")))
2025 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 2026 ""
0b85d816
HPN
2027{
2028 return
991c42ac 2029 (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > <nbitsm1>)
22c3c091 2030 ? "moveq 0,%0"
0b85d816 2031 : (CONSTANT_P (operands[2])
22c3c091
HPN
2032 ? "lslq %2,%0" : "lsl<m> %2,%0");
2033}
0b85d816 2034 [(set_attr "slottable" "yes")
d0780379 2035 (set_attr "cc" "*,clobber")])
0b85d816
HPN
2036
2037;; A strict_low_part matcher.
2038
22c3c091
HPN
2039(define_insn "*ashl<mode>_lowpart"
2040 [(set (strict_low_part (match_operand:BW 0 "register_operand" "+r"))
2041 (ashift:BW (match_dup 0)
fb062a8b
HPN
2042 (match_operand:HI 1 "register_operand" "r")))
2043 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816 2044 ""
22c3c091 2045 "lsl<m> %1,%0"
d0780379 2046 [(set_attr "slottable" "yes")])
0b85d816
HPN
2047\f
2048;; Various strange insns that gcc likes.
2049
2050;; Fortunately, it is simple to construct an abssf (although it may not
2051;; be very much used in practice).
2052
2053(define_insn "abssf2"
2054 [(set (match_operand:SF 0 "register_operand" "=r")
fb062a8b
HPN
2055 (abs:SF (match_operand:SF 1 "register_operand" "0")))
2056 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
2057 ""
2058 "lslq 1,%0\;lsrq 1,%0")
2059
2060(define_insn "abssi2"
2061 [(set (match_operand:SI 0 "register_operand" "=r")
fb062a8b
HPN
2062 (abs:SI (match_operand:SI 1 "register_operand" "r")))
2063 (clobber (reg:CC CRIS_CC0_REGNUM))]
0b85d816
HPN
2064 ""
2065 "abs %1,%0"
d0780379 2066 [(set_attr "slottable" "yes")])
0b85d816
HPN
2067
2068;; FIXME: GCC should be able to do these expansions itself.
2069
22c3c091 2070(define_expand "abs<mode>2"
fb062a8b
HPN
2071 [(parallel
2072 [(set (match_dup 2)
2073 (sign_extend:SI (match_operand:BW 1 "general_operand")))
2074 (clobber (reg:CC CRIS_CC0_REGNUM))])
2075 (parallel
2076 [(set (match_dup 3) (abs:SI (match_dup 2)))
2077 (clobber (reg:CC CRIS_CC0_REGNUM))])
2078 (parallel
2079 [(set (match_operand:BW 0 "register_operand")
2080 (subreg:BW (match_dup 3) 0))
2081 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816
HPN
2082 ""
2083 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
e636e508 2084
d137723b 2085(define_insn "<acc><anz><anzvc>clzsi2<setcc><setnz><setnzvc>"
e636e508 2086 [(set (match_operand:SI 0 "register_operand" "=r")
fb062a8b
HPN
2087 (clz:SI (match_operand:SI 1 "register_operand" "r")))
2088 (clobber (reg:CC CRIS_CC0_REGNUM))]
e636e508
JN
2089 "TARGET_HAS_LZ"
2090 "lz %1,%0"
d0780379 2091 [(set_attr "slottable" "yes")])
e636e508 2092
d137723b 2093(define_insn "<acc><anz><anzvc>bswapsi2<setcc><setnz><setnzvc>"
df638b27 2094 [(set (match_operand:SI 0 "register_operand" "=r")
fb062a8b
HPN
2095 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
2096 (clobber (reg:CC CRIS_CC0_REGNUM))]
df638b27
JN
2097 "TARGET_HAS_SWAP"
2098 "swapwb %0"
d0780379 2099 [(set_attr "slottable" "yes")])
df638b27 2100
9ef4a0cd
JN
2101;; This instruction swaps all bits in a register.
2102;; That means that the most significant bit is put in the place
2103;; of the least significant bit, and so on.
2104
2105(define_insn "cris_swap_bits"
2106 [(set (match_operand:SI 0 "register_operand" "=r")
2107 (unspec:SI [(match_operand:SI 1 "register_operand" "0")]
fb062a8b
HPN
2108 CRIS_UNSPEC_SWAP_BITS))
2109 (clobber (reg:CC CRIS_CC0_REGNUM))]
9ef4a0cd
JN
2110 "TARGET_HAS_SWAP"
2111 "swapwbr %0"
d0780379 2112 [(set_attr "slottable" "yes")])
9ef4a0cd
JN
2113
2114;; Implement ctz using two instructions, one for bit swap and one for clz.
2115;; Defines a scratch register to avoid clobbering input.
2116
2117(define_expand "ctzsi2"
fb062a8b
HPN
2118 [(parallel
2119 [(set (match_dup 2)
2120 (match_operand:SI 1 "register_operand"))
2121 (clobber (reg:CC CRIS_CC0_REGNUM))])
2122 (parallel
2123 [(set (match_dup 2)
2124 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
2125 (clobber (reg:CC CRIS_CC0_REGNUM))])
2126 (parallel
2127 [(set (match_operand:SI 0 "register_operand")
2128 (clz:SI (match_dup 2)))
2129 (clobber (reg:CC CRIS_CC0_REGNUM))])]
9ef4a0cd
JN
2130 "TARGET_HAS_LZ && TARGET_HAS_SWAP"
2131 "operands[2] = gen_reg_rtx (SImode);")
2132
0b85d816
HPN
2133;; Bound-insn. Defined to be the same as an unsigned minimum, which is an
2134;; operation supported by gcc. Used in casesi, but used now and then in
2135;; normal code too.
2136
45d5d09c 2137(define_expand "uminsi3"
fb062a8b
HPN
2138 [(parallel
2139 [(set (match_operand:SI 0 "register_operand")
2140 (umin:SI (match_operand:SI 1 "register_operand")
2141 (match_operand:SI 2 "general_operand")))
2142 (clobber (reg:CC CRIS_CC0_REGNUM))])]
45d5d09c 2143 ""
d0780379 2144 "")
45d5d09c 2145
d137723b 2146(define_insn "*uminsi3<setcc><setnz><setnzvc>"
23369bef
HPN
2147 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
2148 (umin:SI (match_operand:SI 1 "register_operand" "%0,0, 0,r")
fb062a8b
HPN
2149 (match_operand:SI 2 "general_operand" "r,Q>,g,!To")))
2150 (clobber (reg:CC CRIS_CC0_REGNUM))]
d0780379 2151 ""
0b85d816 2152{
991c42ac 2153 if (CONST_INT_P (operands[2]))
0b85d816 2154 {
d76fe40b
HPN
2155 /* Constant operands are zero-extended, so only 32-bit operands
2156 may be negative. */
2157 if (INTVAL (operands[2]) >= 0)
2158 {
2159 if (INTVAL (operands[2]) < 256)
2160 return "bound.b %2,%0";
0b85d816 2161
d76fe40b
HPN
2162 if (INTVAL (operands[2]) < 65536)
2163 return "bound.w %2,%0";
2164 }
0b85d816
HPN
2165 }
2166 else if (which_alternative == 3)
22c3c091 2167 return "bound.d %2,%1,%0";
0b85d816 2168
22c3c091
HPN
2169 return "bound.d %2,%0";
2170}
0b85d816
HPN
2171 [(set_attr "slottable" "yes,yes,no,no")])
2172\f
2173;; Jump and branch insns.
2174
2175(define_insn "jump"
2176 [(set (pc)
2177 (label_ref (match_operand 0 "" "")))]
2178 ""
2179 "ba %l0%#"
2180 [(set_attr "slottable" "has_slot")])
2181
2182;; Testcase gcc.c-torture/compile/991213-3.c fails if we allow a constant
2183;; here, since the insn is not recognized as an indirect jump by
2184;; jmp_uses_reg_or_mem used by computed_jump_p. Perhaps it is a kludge to
2185;; change from general_operand to nonimmediate_operand (at least the docs
2186;; should be changed), but then again the pattern is called indirect_jump.
45d5d09c
HPN
2187(define_expand "indirect_jump"
2188 [(set (pc) (match_operand:SI 0 "nonimmediate_operand"))]
0b85d816 2189 ""
d0780379 2190 "")
45d5d09c 2191
d0780379 2192(define_insn "*indirect_jump"
45d5d09c 2193 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
d0780379 2194 ""
0b85d816
HPN
2195 "jump %0")
2196
2197;; Return insn. Used whenever the epilogue is very simple; if it is only
04539954
HPN
2198;; a single ret or jump [sp+]. No allocated stack space or saved
2199;; registers are allowed.
0b85d816
HPN
2200;; Note that for this pattern, although named, it is ok to check the
2201;; context of the insn in the test, not only compiler switches.
2202
04539954 2203(define_expand "return"
0b85d816
HPN
2204 [(return)]
2205 "cris_simple_epilogue ()"
04539954 2206 "cris_expand_return (cris_return_address_on_stack ()); DONE;")
0b85d816 2207
04539954
HPN
2208(define_insn "*return_expanded"
2209 [(return)]
2210 ""
2211{
2212 return cris_return_address_on_stack_for_return ()
2213 ? "jump [$sp+]" : "ret%#";
2214}
0b85d816 2215 [(set (attr "slottable")
04539954 2216 (if_then_else
bf0b8cbe 2217 (match_test "cris_return_address_on_stack_for_return ()")
04539954 2218 (const_string "no")
45d5d09c 2219 (const_string "has_return_slot")))])
04539954 2220
d29b4b1b
HPN
2221(define_expand "prologue"
2222 [(const_int 0)]
cc2af705 2223 ""
d29b4b1b
HPN
2224 "cris_expand_prologue (); DONE;")
2225
04539954
HPN
2226(define_expand "epilogue"
2227 [(const_int 0)]
cc2af705 2228 ""
04539954 2229 "cris_expand_epilogue (); DONE;")
0b85d816
HPN
2230\f
2231;; Conditional branches.
2232
f90b7a5a 2233(define_expand "cbranch<mode>4"
fb062a8b
HPN
2234 [(parallel
2235 [(set (pc)
2236 (if_then_else
2237 (match_operator 0 "ordered_comparison_operator"
2238 [(match_operand:BWDD 1 "nonimmediate_operand")
2239 (match_operand:BWDD 2 "general_operand")])
2240 (label_ref (match_operand 3 ""))
2241 (pc)))
2242 (clobber (reg:CC CRIS_CC0_REGNUM))])]
f90b7a5a 2243 ""
cfaf5204 2244 "cris_reduce_compare (&operands[0], &operands[1], &operands[2]);")
f90b7a5a 2245
b3e01c3d 2246(define_insn_and_split "*cbranch<mode><code>4"
fb062a8b
HPN
2247 [(set (pc)
2248 (if_then_else
b3e01c3d
HPN
2249 (cond
2250 (match_operand:BWDD 0 "nonimmediate_operand" "<cmp_op0c>")
2251 (match_operand:BWDD 1 "general_operand" "<cmp_op1c>"))
2252 (label_ref (match_operand 2 ""))
fb062a8b
HPN
2253 (pc)))
2254 (clobber (reg:CC CRIS_CC0_REGNUM))]
2255 ""
2256 "#"
2257 "&& reload_completed"
b3e01c3d
HPN
2258 [(set (reg:<xCC> CRIS_CC0_REGNUM)
2259 (compare:<xCC> (match_dup 0) (match_dup 1)))
f90b7a5a 2260 (set (pc)
b3e01c3d
HPN
2261 (if_then_else (cond (reg:<xCC> CRIS_CC0_REGNUM) (const_int 0))
2262 (label_ref (match_dup 2))
f90b7a5a 2263 (pc)))]
fb062a8b 2264 "")
f90b7a5a 2265
b73bf8a1
HPN
2266;; Test a single bit at operand[0] against 0/non-0.
2267(define_insn_and_split "*cbranch<mode>4_btstrq1_<CC>"
2268 [(set (pc)
2269 (if_then_else
2270 (zcond
2271 (zero_extract:BWD
2272 (match_operand:BWD 0 "register_operand" "r,r")
2273 (const_int 1)
2274 (match_operand:SI 1 "nonmemory_operand" "Kc,r"))
2275 (const_int 0))
2276 (label_ref (match_operand 2 ""))
2277 (pc)))
2278 (clobber (reg:CC CRIS_CC0_REGNUM))]
2279 ""
2280 "#"
2281 "&& reload_completed"
2282 [(set (reg:CC_ZnN CRIS_CC0_REGNUM)
2283 (compare:CC_ZnN
2284 (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
2285 (const_int 0)))
2286 (set (pc)
2287 (if_then_else (zcond (reg:CC_ZnN CRIS_CC0_REGNUM) (const_int 0))
2288 (label_ref (match_dup 2))
2289 (pc)))]
2290 "")
2291
2292;; Test a field of bits starting at bit 0 against 0/non-0.
2293(define_insn_and_split "*cbranch<mode>4_btstqb0_<CC>"
27228024
HPN
2294 [(set (pc)
2295 (if_then_else
2296 (zcond
2297 (zero_extract:BWD
2298 (match_operand:BWD 0 "register_operand" "r")
2299 (match_operand 1 "const_int_operand" "Kc")
2300 (const_int 0))
2301 (const_int 0))
2302 (label_ref (match_operand 2 ""))
2303 (pc)))
2304 (clobber (reg:CC CRIS_CC0_REGNUM))]
2305 ""
2306 "#"
2307 "&& reload_completed"
b73bf8a1
HPN
2308 [(set (reg:CC_NZ CRIS_CC0_REGNUM)
2309 (compare:CC_NZ
27228024
HPN
2310 (zero_extract:SI (match_dup 0) (match_dup 1) (const_int 0))
2311 (const_int 0)))
2312 (set (pc)
b73bf8a1 2313 (if_then_else (zcond (reg:CC_NZ CRIS_CC0_REGNUM) (const_int 0))
b3e01c3d 2314 (label_ref (match_dup 2))
27228024
HPN
2315 (pc)))]
2316 "")
2317
f90b7a5a 2318
0b85d816
HPN
2319;; We suffer from the same overflow-bit-gets-in-the-way problem as
2320;; e.g. m68k, so we have to check if overflow bit is set on all "signed"
2321;; conditions.
2322
3c7016b0 2323(define_insn "*b<zcond:code><mode>"
0b85d816 2324 [(set (pc)
b73bf8a1 2325 (if_then_else (zcond (reg:ZnNNZUSE CRIS_CC0_REGNUM)
22c3c091 2326 (const_int 0))
0b85d816
HPN
2327 (label_ref (match_operand 0 "" ""))
2328 (pc)))]
fb062a8b 2329 "reload_completed"
b73bf8a1
HPN
2330{
2331 return <MODE>mode == CC_ZnNmode ? "b<znnCC> %l0%#" : "b<CC> %l0%#";
2332}
0b85d816
HPN
2333 [(set_attr "slottable" "has_slot")])
2334
3c7016b0 2335(define_insn "*b<nzvccond:code><mode>"
0b85d816 2336 [(set (pc)
b3e01c3d 2337 (if_then_else (nzvccond (reg:NZVCUSE CRIS_CC0_REGNUM)
22c3c091 2338 (const_int 0))
0b85d816
HPN
2339 (label_ref (match_operand 0 "" ""))
2340 (pc)))]
fb062a8b 2341 "reload_completed"
fb062a8b 2342 "b<CC> %l0%#"
0b85d816
HPN
2343 [(set_attr "slottable" "has_slot")])
2344
3c7016b0 2345(define_insn "*b<rnzcond:code><mode>"
0b85d816 2346 [(set (pc)
b3e01c3d 2347 (if_then_else (rnzcond (reg:NZUSE CRIS_CC0_REGNUM)
22c3c091 2348 (const_int 0))
0b85d816
HPN
2349 (label_ref (match_operand 0 "" ""))
2350 (pc)))]
fb062a8b 2351 "reload_completed"
b3e01c3d
HPN
2352{
2353 return <MODE>mode == CC_NZmode ? "b<oCC> %l0%#": "b<CC> %l0%#";
2354}
0b85d816
HPN
2355 [(set_attr "slottable" "has_slot")])
2356\f
2357;; Reversed anonymous patterns to the ones above, as mandated.
2358
b3e01c3d 2359(define_insn "*b<nzcond:code>_reversed<mode>"
0b85d816 2360 [(set (pc)
b73bf8a1
HPN
2361 (if_then_else (nzcond (reg:ZnNNZUSE CRIS_CC0_REGNUM)
2362 (const_int 0))
0b85d816
HPN
2363 (pc)
2364 (label_ref (match_operand 0 "" ""))))]
fb062a8b 2365 "reload_completed"
b73bf8a1
HPN
2366{
2367 return <MODE>mode == CC_ZnNmode ? "b<rznnCC> %l0%#" : "b<rCC> %l0%#";
2368}
0b85d816
HPN
2369 [(set_attr "slottable" "has_slot")])
2370
b3e01c3d 2371(define_insn "*b<nzvccond:code>_reversed<mode>"
0b85d816 2372 [(set (pc)
b3e01c3d 2373 (if_then_else (nzvccond (reg:NZVCUSE CRIS_CC0_REGNUM)
22c3c091 2374 (const_int 0))
0b85d816
HPN
2375 (pc)
2376 (label_ref (match_operand 0 "" ""))))]
fb062a8b 2377 "reload_completed"
fb062a8b 2378 "b<rCC> %l0%#"
0b85d816
HPN
2379 [(set_attr "slottable" "has_slot")])
2380
b3e01c3d 2381(define_insn "*b<rnzcond:code>_reversed<mode>"
0b85d816 2382 [(set (pc)
b3e01c3d 2383 (if_then_else (rnzcond (reg:NZUSE CRIS_CC0_REGNUM)
22c3c091 2384 (const_int 0))
0b85d816
HPN
2385 (pc)
2386 (label_ref (match_operand 0 "" ""))))]
fb062a8b 2387 "reload_completed"
b3e01c3d
HPN
2388{
2389 return <MODE>mode == CC_NZmode ? "b<roCC> %l0%#" : "b<rCC> %l0%#";
2390}
0b85d816
HPN
2391 [(set_attr "slottable" "has_slot")])
2392\f
2393;; Set on condition: sCC.
2394
fb062a8b
HPN
2395(define_expand "cstore<mode>4"
2396 [(parallel
2397 [(set (match_operand:SI 0 "register_operand")
2398 (match_operator:SI 1 "ordered_comparison_operator"
2399 [(match_operand:BWDD 2 "nonimmediate_operand")
2400 (match_operand:BWDD 3 "general_operand")]))
2401 (clobber (reg:CC CRIS_CC0_REGNUM))])]
f90b7a5a 2402 ""
d0780379 2403 "cris_reduce_compare (&operands[1], &operands[2], &operands[3]);")
f90b7a5a 2404
b3e01c3d 2405(define_insn_and_split "*cstore<mode><code>4"
fb062a8b 2406 [(set (match_operand:SI 0 "register_operand" "=<sCC_destc>")
b3e01c3d
HPN
2407 (cond:SI
2408 (match_operand:BWDD 1 "nonimmediate_operand" "<cmp_op0c>")
2409 (match_operand:BWDD 2 "general_operand" "<cmp_op1c>")))
fb062a8b 2410 (clobber (reg:CC CRIS_CC0_REGNUM))]
f90b7a5a 2411 ""
fb062a8b
HPN
2412 "#"
2413 "&& reload_completed"
b3e01c3d
HPN
2414 [(set (reg:<xCC> CRIS_CC0_REGNUM)
2415 (compare:<xCC> (match_dup 1) (match_dup 2)))
2416 (set (match_dup 0)
2417 (cond:SI (reg:<xCC> CRIS_CC0_REGNUM) (const_int 0)))]
fb062a8b 2418 "")
f90b7a5a 2419
0b85d816
HPN
2420;; Like bCC, we have to check the overflow bit for
2421;; signed conditions.
2422
b3e01c3d 2423(define_insn "*s<nzcond:code><mode>"
0b85d816 2424 [(set (match_operand:SI 0 "register_operand" "=r")
b3e01c3d 2425 (nzcond:SI (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)))]
fb062a8b 2426 "reload_completed"
22c3c091 2427 "s<CC> %0"
0b85d816
HPN
2428 [(set_attr "slottable" "yes")
2429 (set_attr "cc" "none")])
2430
b3e01c3d 2431(define_insn "*s<rnzcond:code><mode>"
0b85d816 2432 [(set (match_operand:SI 0 "register_operand" "=r")
b3e01c3d 2433 (rnzcond:SI (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)))]
fb062a8b 2434 "reload_completed"
b3e01c3d
HPN
2435{
2436 return <MODE>mode == CC_NZmode ? "s<oCC> %0" : "s<CC> %0";
2437}
0cec6af1
HPN
2438 [(set_attr "slottable" "yes")
2439 (set_attr "cc" "none")])
0b85d816 2440
b3e01c3d 2441(define_insn "*s<nzvccond:code><mode>"
0b85d816 2442 [(set (match_operand:SI 0 "register_operand" "=r")
b3e01c3d 2443 (nzvccond:SI (reg:NZVCUSE CRIS_CC0_REGNUM) (const_int 0)))]
fb062a8b 2444 "reload_completed"
fb062a8b 2445 "s<CC> %0"
0b85d816
HPN
2446 [(set_attr "slottable" "yes")
2447 (set_attr "cc" "none")])
2448\f
2449;; Call insns.
2450
2451;; We need to make these patterns "expand", since the real operand is
2452;; hidden in a (mem:QI ) inside operand[0] (call_value: operand[1]),
2453;; and cannot be checked if it were a "normal" pattern.
2454;; Note that "call" and "call_value" are *always* called with a
2455;; mem-operand for operand 0 and 1 respective. What happens for combined
2456;; instructions is a different issue.
2457
2458(define_expand "call"
d0780379
HPN
2459 [(parallel [(call (match_operand:SI 0 "indirect_operand")
2460 (match_operand 1 "general_operand"))
f16bb520 2461 (clobber (reg:SI CRIS_SRP_REGNUM))])]
0b85d816 2462 ""
0b85d816 2463{
d0780379 2464 operands[1] = const0_rtx;
b6c34129 2465})
0b85d816 2466
ab4e53fe 2467;; Accept operands for operand 0 in order of preference.
0b85d816 2468
d0780379 2469(define_insn "*expanded_call"
45d5d09c 2470 [(call (mem:QI (match_operand:SI 0 "general_operand" "r,Q>,g"))
d0780379 2471 (const_int 0))
f16bb520 2472 (clobber (reg:SI CRIS_SRP_REGNUM))]
d0780379 2473 ""
0b85d816
HPN
2474 "jsr %0")
2475
2476(define_expand "call_value"
d0780379
HPN
2477 [(parallel [(set (match_operand 0 "")
2478 (call (match_operand:SI 1 "indirect_operand")
2479 (match_operand 2 "")))
f16bb520 2480 (clobber (reg:SI CRIS_SRP_REGNUM))])]
0b85d816 2481 ""
0b85d816 2482{
d0780379 2483 operands[2] = const0_rtx;
b6c34129 2484})
0b85d816 2485
ab4e53fe 2486;; The validity other than "general" of
0b85d816
HPN
2487;; operand 0 will be checked elsewhere. Accept operands for operand 1 in
2488;; order of preference (Q includes r, but r is shorter, faster).
2489;; We also accept a PLT symbol. We output it as [rPIC+sym:GOTPLT] rather
2490;; than requiring getting rPIC + sym:PLT into a register.
2491
d0780379 2492(define_insn "*expanded_call_value"
c00fc5cf 2493 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
45d5d09c 2494 (call (mem:QI (match_operand:SI 1 "general_operand" "r,Q>,g"))
d0780379 2495 (const_int 0)))
f16bb520 2496 (clobber (reg:SI CRIS_SRP_REGNUM))]
d0780379 2497 ""
0b85d816
HPN
2498 "Jsr %1"
2499 [(set_attr "cc" "clobber")])
2500
0b85d816
HPN
2501;; Used in debugging. No use for the direct pattern; unfilled
2502;; delayed-branches are taken care of by other means.
2503
2504(define_insn "nop"
2505 [(const_int 0)]
2506 ""
2507 "nop"
2508 [(set_attr "cc" "none")])
64f5af47 2509
d0780379
HPN
2510;; Same as the gdb trap breakpoint: would cause a SIGTRAP for
2511;; cris-linux* and will work in freestanding environments with
2512;; sufficient framework.
64f5af47
HPN
2513(define_insn "trap"
2514 [(trap_if (const_int 1) (const_int 8))]
2515 "TARGET_TRAP_USING_BREAK8"
2516 "break 8")
0b85d816 2517\f
04539954
HPN
2518;; We need to stop accesses to the stack after the memory is
2519;; deallocated. Unfortunately, reorg doesn't look at naked clobbers,
2520;; e.g. (insn ... (clobber (mem:BLK (stack_pointer_rtx)))) and we don't
2521;; want to use a naked (unspec_volatile) as that would stop any
2522;; scheduling in the epilogue. Hence we model it as a "real" insn that
2523;; sets the memory in an unspecified manner. FIXME: Unfortunately it
2524;; still has the effect of an unspec_volatile.
2525(define_insn "cris_frame_deallocated_barrier"
2526 [(set (mem:BLK (reg:SI CRIS_SP_REGNUM))
2527 (unspec:BLK [(const_int 0)] CRIS_UNSPEC_FRAME_DEALLOC))]
2528 ""
2529 ""
2530 [(set_attr "length" "0")])
2531
0b85d816
HPN
2532;; We expand on casesi so we can use "bound" and "add offset fetched from
2533;; a table to pc" (adds.w [pc+%0.w],pc).
2534
2535;; Note: if you change the "parallel" (or add anything after it) in
2536;; this expansion, you must change the macro ASM_OUTPUT_CASE_END
2537;; accordingly, to add the default case at the end of the jump-table.
2538
d0780379 2539(define_expand "casesi"
fb062a8b
HPN
2540 [(parallel
2541 [(set (match_dup 5) (match_operand:SI 0 "general_operand"))
2542 (clobber (reg:CC CRIS_CC0_REGNUM))])
2543 (parallel
2544 [(set (match_dup 6)
2545 (minus:SI (match_dup 5)
2546 (match_operand:SI 1 "const_int_operand")))
2547 (clobber (reg:CC CRIS_CC0_REGNUM))])
2548 (parallel
2549 [(set (match_dup 7)
2550 (umin:SI (match_dup 6)
2551 (match_operand:SI 2 "const_int_operand")))
2552 (clobber (reg:CC CRIS_CC0_REGNUM))])
0b85d816
HPN
2553 (parallel
2554 [(set (pc)
2555 (if_then_else
2556 (ltu (match_dup 7) (match_dup 2))
2557 (plus:SI (sign_extend:SI
2558 (mem:HI
2559 (plus:SI (mult:SI (match_dup 7) (const_int 2))
2560 (pc))))
2561 (pc))
fb062a8b
HPN
2562 (label_ref (match_operand 4 ""))))
2563 (use (label_ref (match_operand 3 "")))
2564 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 2565 ""
0b85d816 2566{
0a81f074 2567 operands[2] = plus_constant (SImode, operands[2], 1);
0b85d816
HPN
2568 operands[5] = gen_reg_rtx (SImode);
2569 operands[6] = gen_reg_rtx (SImode);
2570 operands[7] = gen_reg_rtx (SImode);
22c3c091 2571})
21ed4444
HPN
2572
2573(include "sync.md")
0b85d816 2574\f
0b85d816
HPN
2575;; Various peephole optimizations.
2576;;
0b85d816 2577;; Do not add patterns that you do not know will be matched.
109b748d 2578;; Please also add a self-contained testcase.
0b85d816
HPN
2579
2580;; We have trouble with and:s and shifts. Maybe something is broken in
43a88a8c 2581;; gcc? Or it could just be that bit-field insn expansion is a bit
cf2bfc7c
HPN
2582;; suboptimal when not having extzv insns. Or combine being over-eager
2583;; to canonicalize to "and", and ignorant on the benefits of the right
2584;; mixture of "and" and "zero-extend".
2585
2586;; Testcase for the following peephole: gcc.target/cris/peep2-movulsr.c
2587
2588;; Where equivalent and where the "and" argument doesn't fit "andq" but
2589;; is 16 bits or smaller, replace the "and" with a zero-extend preceding
2590;; the shift. A zero-extend is shorter and faster than "and" with a
2591;; 32-bit argument.
2592
2593(define_peephole2 ; movulsr
2594 [(parallel
2595 [(set (match_operand:SI 0 "register_operand")
2596 (lshiftrt:SI (match_dup 0)
2597 (match_operand:SI 1 "const_int_operand")))
2598 (clobber (reg:CC CRIS_CC0_REGNUM))])
2599 (parallel
2600 [(set (match_dup 0)
2601 (and:SI (match_dup 0)
2602 (match_operand 2 "const_int_operand")))
2603 (clobber (reg:CC CRIS_CC0_REGNUM))])]
2604 "INTVAL (operands[2]) > 31 && INTVAL (operands[2]) <= 0xffff
2605 && (((INTVAL (operands[2]) <= 0xff ? 0xff : 0xffff) >> INTVAL (operands[1]))
2606 == INTVAL (operands[2]))"
2607 [(parallel
2608 ;; The zero-extend is expressed as an "and", only because that's easier
2609 ;; than messing with zero-extend of a subreg.
2610 [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 3)))
2611 (clobber (reg:CC CRIS_CC0_REGNUM))])
2612 (parallel
2613 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
2614 (clobber (reg:CC CRIS_CC0_REGNUM))])]
2615{
2616 operands[3]
2617 = INTVAL (operands[2]) <= 0xff ? GEN_INT (0xff) : GEN_INT (0xffff);
2618})
2619
2620;; Testcase for the following four peepholes: gcc.target/cris/peep2-xsrand.c
0b85d816 2621
fb062a8b
HPN
2622(define_peephole2 ; asrandb
2623 [(parallel
2624 [(set (match_operand:SI 0 "register_operand")
2625 (ashiftrt:SI (match_dup 0)
2626 (match_operand:SI 1 "const_int_operand")))
2627 (clobber (reg:CC CRIS_CC0_REGNUM))])
2628 (parallel
2629 [(set (match_dup 0)
0b85d816 2630 (and:SI (match_dup 0)
fb062a8b
HPN
2631 (match_operand 2 "const_int_operand")))
2632 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816
HPN
2633 "INTVAL (operands[2]) > 31
2634 && INTVAL (operands[2]) < 255
8ad46d34
HPN
2635 && INTVAL (operands[1]) > 23
2636 /* Check that the and-operation enables us to use logical-shift. */
2637 && (INTVAL (operands[2])
c4362b60
JL
2638 & ((HOST_WIDE_INT) (HOST_WIDE_INT_M1U
2639 << (32 - INTVAL (operands[1]))))) == 0"
fb062a8b
HPN
2640 [(parallel
2641 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
2642 (clobber (reg:CC CRIS_CC0_REGNUM))])
2643 (parallel
2644 [(set (match_dup 3) (and:QI (match_dup 3) (match_dup 4)))
2645 (clobber (reg:CC CRIS_CC0_REGNUM))])]
bf6ac87c
HPN
2646{
2647 operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));
2648 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), QImode));
2649})
8ad46d34 2650
fb062a8b
HPN
2651(define_peephole2 ; asrandw
2652 [(parallel
2653 [(set (match_operand:SI 0 "register_operand")
2654 (ashiftrt:SI (match_dup 0)
2655 (match_operand:SI 1 "const_int_operand")))
2656 (clobber (reg:CC CRIS_CC0_REGNUM))])
2657 (parallel
2658 [(set (match_dup 0)
2659 (and:SI (match_dup 0) (match_operand 2 "const_int_operand")))
2660 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816
HPN
2661 "INTVAL (operands[2]) > 31
2662 && INTVAL (operands[2]) < 65535
2663 && INTVAL (operands[2]) != 255
8ad46d34
HPN
2664 && INTVAL (operands[1]) > 15
2665 /* Check that the and-operation enables us to use logical-shift. */
2666 && (INTVAL (operands[2])
c4362b60
JL
2667 & ((HOST_WIDE_INT) (HOST_WIDE_INT_M1U
2668 << (32 - INTVAL (operands[1]))))) == 0"
fb062a8b
HPN
2669 [(parallel
2670 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
2671 (clobber (reg:CC CRIS_CC0_REGNUM))])
2672 (parallel
2673 [(set (match_dup 3) (and:HI (match_dup 3) (match_dup 4)))
2674 (clobber (reg:CC CRIS_CC0_REGNUM))])]
bf6ac87c
HPN
2675{
2676 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
2677 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), HImode));
2678})
8ad46d34 2679
fb062a8b
HPN
2680(define_peephole2 ; lsrandb
2681 [(parallel
2682 [(set (match_operand:SI 0 "register_operand")
2683 (lshiftrt:SI (match_dup 0)
2684 (match_operand:SI 1 "const_int_operand")))
2685 (clobber (reg:CC CRIS_CC0_REGNUM))])
2686 (parallel
2687 [(set (match_dup 0)
2688 (and:SI (match_dup 0) (match_operand 2 "const_int_operand")))
2689 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816
HPN
2690 "INTVAL (operands[2]) > 31
2691 && INTVAL (operands[2]) < 255
2692 && INTVAL (operands[1]) > 23"
fb062a8b
HPN
2693 [(parallel
2694 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
2695 (clobber (reg:CC CRIS_CC0_REGNUM))])
2696 (parallel
2697 [(set (match_dup 3) (and:QI (match_dup 3) (match_dup 4)))
2698 (clobber (reg:CC CRIS_CC0_REGNUM))])]
bf6ac87c
HPN
2699{
2700 operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));
2701 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), QImode));
2702})
0b85d816 2703
fb062a8b
HPN
2704(define_peephole2 ; lsrandw
2705 [(parallel
2706 [(set (match_operand:SI 0 "register_operand")
0b85d816 2707 (lshiftrt:SI (match_dup 0)
fb062a8b
HPN
2708 (match_operand:SI 1 "const_int_operand")))
2709 (clobber (reg:CC CRIS_CC0_REGNUM))])
2710 (parallel
2711 [(set (match_dup 0)
2712 (and:SI (match_dup 0) (match_operand 2 "const_int_operand")))
2713 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816
HPN
2714 "INTVAL (operands[2]) > 31 && INTVAL (operands[2]) < 65535
2715 && INTVAL (operands[2]) != 255
2716 && INTVAL (operands[1]) > 15"
fb062a8b
HPN
2717 [(parallel
2718 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
2719 (clobber (reg:CC CRIS_CC0_REGNUM))])
2720 (parallel
2721 [(set (match_dup 3) (and:HI (match_dup 3) (match_dup 4)))
2722 (clobber (reg:CC CRIS_CC0_REGNUM))])]
bf6ac87c
HPN
2723{
2724 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
2725 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), HImode));
2726})
0b85d816 2727
ff2ca1bc
HPN
2728;; There seems to be no other way to make GCC (including 4.8/trunk at
2729;; r186932) optimally reload an instruction that looks like
2730;; and.d reg_or_mem,const_32__65535,other_reg
2731;; where other_reg is the destination.
0b85d816 2732;; It should be:
ff2ca1bc
HPN
2733;; movu.[bw] reg_or_mem,reg_32
2734;; and.[bw] trunc_int_for_mode([bw], const_32__65535),reg_32 ;; or andq
365cacbf 2735;; but it turns into:
ff2ca1bc
HPN
2736;; move.d reg_or_mem,reg_32
2737;; and.d const_32__65535,reg_32
2738;; Fix it with these two peephole2's.
cf2bfc7c 2739;; Testcases: gcc.target/cris/peep2-andu1.c gcc.target/cris/peep2-andu2.c
0b85d816 2740
fb062a8b
HPN
2741(define_peephole2 ; andu
2742 [(parallel
2743 [(set (match_operand:SI 0 "register_operand")
2744 (match_operand:SI 1 "nonimmediate_operand"))
2745 (clobber (reg:CC CRIS_CC0_REGNUM))])
2746 (parallel
2747 [(set (match_operand:SI 2 "register_operand")
2748 (and:SI (match_dup 0)
2749 (match_operand:SI 3 "const_int_operand")))
2750 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816
HPN
2751 ;; Since the size of the memory access could be made different here,
2752 ;; don't do this for a mem-volatile access.
0b85d816
HPN
2753 "REGNO (operands[2]) == REGNO (operands[0])
2754 && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
06cadf63 2755 && !satisfies_constraint_I (operands[3])
365cacbf
HPN
2756 && !side_effects_p (operands[1])
2757 && (!REG_P (operands[1])
2758 || REGNO (operands[1]) <= CRIS_LAST_GENERAL_REGISTER)"
fb062a8b
HPN
2759 [(parallel
2760 [(set (match_dup 0) (match_dup 4))
2761 (clobber (reg:CC CRIS_CC0_REGNUM))])
2762 (parallel
2763 [(set (match_dup 5) (match_dup 6))
2764 (clobber (reg:CC CRIS_CC0_REGNUM))])]
0b85d816 2765{
ef4bddc2
RS
2766 machine_mode zmode = INTVAL (operands[3]) <= 255 ? QImode : HImode;
2767 machine_mode amode
06cadf63 2768 = satisfies_constraint_O (operands[3]) ? SImode : zmode;
8ad46d34
HPN
2769 rtx op1
2770 = (REG_S_P (operands[1])
2771 ? gen_rtx_REG (zmode, REGNO (operands[1]))
2772 : adjust_address (operands[1], zmode, 0));
2773 operands[4]
2774 = gen_rtx_ZERO_EXTEND (SImode, op1);
2775 operands[5] = gen_rtx_REG (amode, REGNO (operands[0]));
2776 operands[6]
2777 = gen_rtx_AND (amode, gen_rtx_REG (amode, REGNO (operands[0])),
2778 GEN_INT (trunc_int_for_mode (INTVAL (operands[3]),
2779 amode == SImode
2780 ? QImode : amode)));
2781})
c00fc5cf 2782
cf2bfc7c 2783;; Since r186861, gcc.target/cris/peep2-andu2.c trigs this pattern, with which
ff2ca1bc
HPN
2784;; we fix up e.g.:
2785;; movu.b 254,$r9.
2786;; and.d $r10,$r9
2787;; into:
2788;; movu.b $r10,$r9
2789;; andq -2,$r9.
2790;; Only do this for values fitting the quick immediate operand.
fb062a8b
HPN
2791(define_peephole2 ; andqu
2792 [(parallel
2793 [(set (match_operand:SI 0 "register_operand")
2794 (match_operand:SI 1 "const_int_operand"))
2795 (clobber (reg:CC CRIS_CC0_REGNUM))])
2796 (parallel
2797 [(set (match_dup 0)
2798 (and:SI (match_dup 0) (match_operand:SI 2 "nonimmediate_operand")))
2799 (clobber (reg:CC CRIS_CC0_REGNUM))])]
ff2ca1bc
HPN
2800 ;; Since the size of the memory access will be made different here,
2801 ;; don't do this for a volatile access or a post-incremented address.
2802 "satisfies_constraint_O (operands[1])
2803 && !side_effects_p (operands[2])
2804 && !reg_overlap_mentioned_p (operands[0], operands[2])"
fb062a8b
HPN
2805 [(parallel
2806 [(set (match_dup 0) (match_dup 3))
2807 (clobber (reg:CC CRIS_CC0_REGNUM))])
2808 (parallel
2809 [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))
2810 (clobber (reg:CC CRIS_CC0_REGNUM))])]
ff2ca1bc 2811{
da3243b2 2812 machine_mode zmode = INTVAL (operands[1]) <= 255 ? QImode : HImode;
ff2ca1bc
HPN
2813 rtx op1
2814 = (REG_S_P (operands[2])
2815 ? gen_rtx_REG (zmode, REGNO (operands[2]))
2816 : adjust_address (operands[2], zmode, 0));
2817 operands[3] = gen_rtx_ZERO_EXTEND (SImode, op1);
2818 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]), QImode));
2819})
0b85d816
HPN
2820\f
2821;; Local variables:
2822;; mode:emacs-lisp
2823;; comment-start: ";; "
2824;; eval: (set-syntax-table (copy-sequence (syntax-table)))
2825;; eval: (modify-syntax-entry ?[ "(]")
2826;; eval: (modify-syntax-entry ?] ")[")
2827;; eval: (modify-syntax-entry ?{ "(}")
2828;; eval: (modify-syntax-entry ?} "){")
2829;; eval: (setq indent-tabs-mode t)
2830;; End: