]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/cris/cris.md
Daily bump.
[thirdparty/gcc.git] / gcc / config / cris / cris.md
CommitLineData
0b85d816 1;; GCC machine description for CRIS cpu cores.
66647d44 2;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
d652f226 3;; 2008, 2009, 2010 Free Software Foundation, Inc.
0b85d816
HPN
4;; Contributed by Axis Communications.
5
6;; This file is part of GCC.
7;;
8;; GCC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
748086b7 10;; the Free Software Foundation; either version 3, or (at your option)
0b85d816
HPN
11;; any later version.
12;;
13;; GCC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
19;; along with GCC; see the file COPYING3. If not see
20;; <http://www.gnu.org/licenses/>.
0b85d816
HPN
21
22;; The original PO technology requires these to be ordered by speed,
23;; so that assigner will pick the fastest.
24
25;; See files "md.texi" and "rtl.def" for documentation on define_insn,
26;; match_*, et. al.
27;;
28;; The function cris_notice_update_cc in cris.c handles condition code
29;; updates for most instructions, helped by the "cc" attribute.
30
31;; There are several instructions that are orthogonal in size, and seems
32;; they could be matched by a single pattern without a specified size
33;; for the operand that is orthogonal. However, this did not work on
839a4992 34;; gcc-2.7.2 (and probably not on gcc-2.8.1), relating to that when a
0b85d816
HPN
35;; constant is substituted into an operand, the actual mode must be
36;; deduced from the pattern. There is reasonable hope that that has been
d2f55c5c 37;; fixed, so FIXME: try again.
0b85d816
HPN
38
39;; You will notice that three-operand alternatives ("=r", "r", "!To")
40;; are marked with a "!" constraint modifier to avoid being reloaded
41;; into. This is because gcc would otherwise prefer to use the constant
42;; pool and its offsettable address instead of reloading to an
43;; ("=r", "0", "i") alternative. Also, the constant-pool support was not
44;; only suboptimal but also buggy in 2.7.2, ??? maybe only in 2.6.3.
45
46;; All insns that look like (set (...) (plus (...) (reg:SI 8)))
47;; get problems when reloading r8 (frame pointer) to r14 + offs (stack
48;; pointer). Thus the instructions that get into trouble have specific
49;; checks against matching frame_pointer_rtx.
50;; ??? But it should be re-checked for gcc > 2.7.2
51;; FIXME: This changed some time ago (from 2000-03-16) for gcc-2.9x.
52
53;; FIXME: When PIC, all [rX=rY+S] could be enabled to match
54;; [rX=gotless_symbol].
55;; The movsi for a gotless symbol could be split (post reload).
56\f
45d5d09c
HPN
57
58(define_constants
59 [
60 ;; PLT reference from call expansion: operand 0 is the address,
61 ;; the mode is VOIDmode. Always wrapped in CONST.
62 ;; The value is relative to the GOT.
63 (CRIS_UNSPEC_PLT_GOTREL 0)
64
65 ;; PLT reference from call expansion: operand 0 is the address,
66 ;; the mode is VOIDmode. Always wrapped in CONST.
67 ;; The value is relative to the PC. It's arch-dependent whether
68 ;; the offset counts from the start or the end of the current item.
69 (CRIS_UNSPEC_PLT_PCREL 1)
70
71 ;; The address of the global offset table as a source operand.
c00fc5cf 72 (CRIS_UNSPEC_GOT 2)
45d5d09c
HPN
73
74 ;; The offset from the global offset table to the operand.
c00fc5cf 75 (CRIS_UNSPEC_GOTREL 3)
45d5d09c
HPN
76
77 ;; The PC-relative offset to the operand. It's arch-dependent whether
78 ;; the offset counts from the start or the end of the current item.
79 (CRIS_UNSPEC_PCREL 4)
80
81 ;; The index into the global offset table of a symbol, while
82 ;; also generating a GOT entry for the symbol.
83 (CRIS_UNSPEC_GOTREAD 5)
84
85 ;; Similar to CRIS_UNSPEC_GOTREAD, but also generating a PLT entry.
86 (CRIS_UNSPEC_PLTGOTREAD 6)
87
88 ;; Condition for v32 casesi jump, since it needs to have if_then_else
89 ;; form with register as one branch and default label as other.
90 ;; Operand 0 is const_int 0.
91 (CRIS_UNSPEC_CASESI 7)
92
93 ;; Stack frame deallocation barrier.
94 (CRIS_UNSPEC_FRAME_DEALLOC 8)
95
96 ;; Swap all 32 bits of the operand; 31 <=> 0, 30 <=> 1...
97 (CRIS_UNSPEC_SWAP_BITS 9)
98 ])
f60c7155
HPN
99
100;; Register numbers.
101(define_constants
102 [(CRIS_GOT_REGNUM 0)
103 (CRIS_STATIC_CHAIN_REGNUM 7)
104 (CRIS_FP_REGNUM 8)
105 (CRIS_SP_REGNUM 14)
45d5d09c 106 (CRIS_ACR_REGNUM 15)
f60c7155 107 (CRIS_SRP_REGNUM 16)
f9968e3e
HPN
108 (CRIS_MOF_REGNUM 17)
109 (CRIS_AP_REGNUM 18)
110 (CRIS_CC0_REGNUM 19)]
f60c7155
HPN
111)
112
0b85d816
HPN
113;; We need an attribute to define whether an instruction can be put in
114;; a branch-delay slot or not, and whether it has a delay slot.
115;;
116;; Branches and return instructions have a delay slot, and cannot
117;; themselves be put in a delay slot. This has changed *for short
118;; branches only* between architecture variants, but the possible win
119;; is presumed negligible compared to the added complexity of the machine
120;; description: one would have to add always-correct infrastructure to
121;; distinguish short branches.
122;;
123;; Whether an instruction can be put in a delay slot depends on the
124;; instruction (all short instructions except jumps and branches)
125;; and the addressing mode (must not be prefixed or referring to pc).
126;; In short, any "slottable" instruction must be 16 bit and not refer
127;; to pc, or alter it.
128;;
45d5d09c
HPN
129;; The possible values are "yes", "no", "has_slot", "has_return_slot"
130;; and "has_call_slot".
131;; Yes/no tells whether the insn is slottable or not. Has_call_slot means
132;; that the insn is a call insn, which for CRIS v32 has a delay-slot.
133;; Of special concern is that no RTX_FRAME_RELATED insn must go in that
134;; call delay slot, as it's located in the address *after* the call insn,
135;; and the unwind machinery doesn't know about delay slots.
136;; Has_slot means that the insn is a branch insn (which are
137;; not considered slottable since that is generally true). Having the
138;; seemingly illogical value "has_slot" means we do not have to add
139;; another attribute just to say that an insn has a delay-slot, since it
140;; also infers that it is not slottable. Better names for the attribute
141;; were found to be longer and not add readability to the machine
142;; description.
143;; Has_return_slot is similar, for the return insn.
0b85d816
HPN
144;;
145;; The default that is defined here for this attribute is "no", not
146;; slottable, not having a delay-slot, so there's no need to worry about
147;; it being wrong for non-branch and return instructions.
148;; The default could depend on the kind of insn and the addressing
149;; mode, but that would need more attributes and hairier, more error
150;; prone code.
151;;
23369bef
HPN
152;; There is an extra memory constraint, 'Q', which recognizes an indirect
153;; register. The constraints 'Q' and '>' together match all possible
154;; memory operands that are slottable.
0b85d816
HPN
155;; For other operands, you need to check if it has a valid "slottable"
156;; quick-immediate operand, where the particular signedness-variation
157;; may match the constraints 'I' or 'J'.), and include it in the
158;; constraint pattern for the slottable pattern. An alternative using
159;; only "r" constraints is most often slottable.
160
45d5d09c
HPN
161(define_attr "slottable" "no,yes,has_slot,has_return_slot,has_call_slot"
162 (const_string "no"))
0b85d816
HPN
163
164;; We also need attributes to sanely determine the condition code
165;; state. See cris_notice_update_cc for how this is used.
166
45d5d09c 167(define_attr "cc" "none,clobber,normal,noov32,rev" (const_string "normal"))
0b85d816 168
3a5afdfc
HPN
169;; At the moment, this attribute is just used to help bb-reorder do its
170;; work; the default 0 doesn't help it. Many insns have other lengths,
171;; though none are shorter.
172(define_attr "length" "" (const_int 2))
173
45d5d09c 174;; A branch has one delay-slot. The instruction in the
0b85d816
HPN
175;; delay-slot is always executed, independent of whether the branch is
176;; taken or not. Note that besides setting "slottable" to "has_slot",
177;; there also has to be a "%#" at the end of a "delayed" instruction
178;; output pattern (for "jump" this means "ba %l0%#"), so print_operand can
179;; catch it and print a "nop" if necessary. This method was stolen from
180;; sparc.md.
181
182(define_delay (eq_attr "slottable" "has_slot")
183 [(eq_attr "slottable" "yes") (nil) (nil)])
45d5d09c
HPN
184
185;; We can't put prologue insns in call-insn delay-slots when
186;; DWARF2 unwind info is emitted, because the unwinder matches the
187;; address after the insn. It must see the return address of a call at
188;; a position at least *one byte after* the insn, or it'll think that
189;; the insn hasn't been executed. If the insn is in a delay-slot of a
190;; call, it's just *exactly* after the insn.
191
192(define_delay (eq_attr "slottable" "has_call_slot")
193 [(and (eq_attr "slottable" "yes")
bf0b8cbe
RS
194 (ior (not (match_test "RTX_FRAME_RELATED_P (insn)"))
195 (not (match_test "flag_exceptions"))))
45d5d09c
HPN
196 (nil) (nil)])
197
198;; The insn in the return insn slot must not be the
199;; return-address-register restore. FIXME: Use has_slot and express
200;; as a parallel with a use of the return-address-register (currently
201;; only SRP). However, this requires an amount of fixing tests for
202;; naked RETURN in middle-end.
203(define_delay (eq_attr "slottable" "has_return_slot")
204 [(and (eq_attr "slottable" "yes")
bf0b8cbe 205 (not (match_test "dead_or_set_regno_p (insn, CRIS_SRP_REGNUM)")))
45d5d09c
HPN
206 (nil) (nil)])
207
0b85d816 208\f
22c3c091
HPN
209;; Iterator definitions.
210
211;; For the "usual" pattern size alternatives.
3abcb3a7
HPN
212(define_mode_iterator BWD [SI HI QI])
213(define_mode_iterator WD [SI HI])
214(define_mode_iterator BW [HI QI])
22c3c091
HPN
215(define_mode_attr S [(SI "HI") (HI "QI")])
216(define_mode_attr s [(SI "hi") (HI "qi")])
217(define_mode_attr m [(SI ".d") (HI ".w") (QI ".b")])
218(define_mode_attr mm [(SI ".w") (HI ".b")])
219(define_mode_attr nbitsm1 [(SI "31") (HI "15") (QI "7")])
220
221;; For the sign_extend+zero_extend variants.
3abcb3a7 222(define_code_iterator szext [sign_extend zero_extend])
22c3c091
HPN
223(define_code_attr u [(sign_extend "") (zero_extend "u")])
224(define_code_attr su [(sign_extend "s") (zero_extend "u")])
225
226;; For the shift variants.
3abcb3a7
HPN
227(define_code_iterator shift [ashiftrt lshiftrt ashift])
228(define_code_iterator shiftrt [ashiftrt lshiftrt])
22c3c091
HPN
229(define_code_attr shlr [(ashiftrt "ashr") (lshiftrt "lshr") (ashift "ashl")])
230(define_code_attr slr [(ashiftrt "asr") (lshiftrt "lsr") (ashift "lsl")])
231
3abcb3a7
HPN
232(define_code_iterator ncond [eq ne gtu ltu geu leu])
233(define_code_iterator ocond [gt le])
234(define_code_iterator rcond [lt ge])
22c3c091
HPN
235(define_code_attr CC [(eq "eq") (ne "ne") (gt "gt") (gtu "hi") (lt "lt")
236 (ltu "lo") (ge "ge") (geu "hs") (le "le") (leu "ls")])
237(define_code_attr rCC [(eq "ne") (ne "eq") (gt "le") (gtu "ls") (lt "ge")
238 (ltu "hs") (ge "lt") (geu "lo") (le "gt") (leu "hi")])
239(define_code_attr oCC [(lt "mi") (ge "pl")])
240(define_code_attr roCC [(lt "pl") (ge "mi")])
241
68a81332
HPN
242;; Operand and operator predicates.
243
244(include "predicates.md")
06cadf63 245(include "constraints.md")
68a81332 246\f
0b85d816
HPN
247;; Test insns.
248
0b85d816
HPN
249;; No test insns with side-effect on the mem addressing.
250;;
251;; See note on cmp-insns with side-effects (or lack of them)
252
253;; Normal named test patterns from SI on.
0b85d816 254
f90b7a5a 255(define_insn "*tstsi"
0b85d816 256 [(set (cc0)
f90b7a5a
PB
257 (compare (match_operand:SI 0 "nonimmediate_operand" "r,Q>,m")
258 (const_int 0)))]
0b85d816 259 ""
45d5d09c
HPN
260{
261 if (which_alternative == 0 && TARGET_V32)
262 return "cmpq 0,%0";
263 return "test.d %0";
264}
0b85d816
HPN
265 [(set_attr "slottable" "yes,yes,no")])
266
45d5d09c
HPN
267(define_insn "*tst<mode>_cmp"
268 [(set (cc0)
f90b7a5a
PB
269 (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
270 (const_int 0)))]
45d5d09c
HPN
271 "cris_cc0_user_requires_cmp (insn)"
272 "@
273 cmp<m> 0,%0
274 test<m> %0
275 test<m> %0"
276 [(set_attr "slottable" "no,yes,no")])
277
278(define_insn "*tst<mode>_non_cmp"
279 [(set (cc0)
f90b7a5a
PB
280 (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
281 (const_int 0)))]
45d5d09c
HPN
282 "!cris_cc0_user_requires_cmp (insn)"
283 "@
284 move<m> %0,%0
285 test<m> %0
286 test<m> %0"
287 [(set_attr "slottable" "yes,yes,no")
288 (set_attr "cc" "noov32,*,*")])
289
0b85d816
HPN
290;; It seems that the position of the sign-bit and the fact that 0.0 is
291;; all 0-bits would make "tstsf" a straight-forward implementation;
292;; either "test.d" it for positive/negative or "btstq 30,r" it for
293;; zeroness.
294;;
295;; FIXME: Do that some time; check next_cc0_user to determine if
296;; zero or negative is tested for.
297\f
298;; Compare insns.
299
300;; We could optimize the sizes of the immediate operands for various
301;; cases, but that is not worth it because of the very little usage of
302;; DImode for anything else but a structure/block-mode. Just do the
303;; obvious stuff for the straight-forward constraint letters.
304
45d5d09c 305(define_insn "*cmpdi_non_v32"
0b85d816 306 [(set (cc0)
f90b7a5a
PB
307 (compare (match_operand:DI 0 "nonimmediate_operand" "rm,r,r,r,r,r,r,o")
308 (match_operand:DI 1 "general_operand" "M,Kc,I,P,n,r,o,r")))]
45d5d09c 309 "!TARGET_V32"
0b85d816 310 "@
f90b7a5a 311 test.d %M0\;ax\;test.d %H0
0b85d816
HPN
312 cmpq %1,%M0\;ax\;cmpq 0,%H0
313 cmpq %1,%M0\;ax\;cmpq -1,%H0
314 cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0
315 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
316 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
317 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
318 cmp.d %M0,%M1\;ax\;cmp.d %H0,%H1")
319
45d5d09c
HPN
320(define_insn "*cmpdi_v32"
321 [(set (cc0)
322 (compare (match_operand:DI 0 "register_operand" "r,r,r,r,r")
f49e46d8 323 (match_operand:DI 1 "nonmemory_operand" "Kc,I,P,n,r")))]
45d5d09c
HPN
324 "TARGET_V32"
325 "@
326 cmpq %1,%M0\;ax\;cmpq 0,%H0
327 cmpq %1,%M0\;ax\;cmpq -1,%H0
328 cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0
329 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0
330 cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0")
331
0b85d816
HPN
332;; Note that compare insns with side effect addressing mode (e.g.):
333;;
334;; cmp.S [rx=ry+i],rz;
335;; cmp.S [%3=%1+%2],%0
336;;
337;; are *not* usable for gcc since the reloader *does not accept*
338;; cc0-changing insns with side-effects other than setting the condition
339;; codes. The reason is that the reload stage *may* cause another insn to
340;; be output after the main instruction, in turn invalidating cc0 for the
341;; insn using the test. (This does not apply to the CRIS case, since a
342;; reload for output -- move to memory -- does not change the condition
343;; code. Unfortunately we have no way to describe that at the moment. I
344;; think code would improve being in the order of one percent faster.
345\f
346;; We have cmps and cmpu (compare reg w. sign/zero extended mem).
347;; These are mostly useful for compares in SImode, using 8 or 16-bit
348;; constants, but sometimes gcc will find its way to use it for other
349;; (memory) operands. Avoid side-effect patterns, though (see above).
0b85d816 350
22c3c091 351(define_insn "*cmp_ext<mode>"
0b85d816
HPN
352 [(set (cc0)
353 (compare
354 (match_operand:SI 0 "register_operand" "r,r")
355 (match_operator:SI 2 "cris_extend_operator"
22c3c091 356 [(match_operand:BW 1 "memory_operand" "Q>,m")])))]
0b85d816 357 ""
22c3c091 358 "cmp%e2<m> %1,%0"
0b85d816
HPN
359 [(set_attr "slottable" "yes,no")])
360
361;; Swap operands; it seems the canonical look (if any) is not enforced.
362;;
363;; FIXME: Investigate that.
0b85d816 364
22c3c091 365(define_insn "*cmp_swapext<mode>"
0b85d816
HPN
366 [(set (cc0)
367 (compare
368 (match_operator:SI 2 "cris_extend_operator"
22c3c091 369 [(match_operand:BW 0 "memory_operand" "Q>,m")])
0b85d816
HPN
370 (match_operand:SI 1 "register_operand" "r,r")))]
371 ""
45d5d09c
HPN
372 "cmp%e2<m> %0,%1"
373 [(set_attr "slottable" "yes,no")
374 (set_attr "cc" "rev")])
0b85d816 375\f
45d5d09c 376;; The "normal" compare patterns, from SI on. Special-cases with zero
f90b7a5a 377;; are covered above.
0b85d816 378
f90b7a5a 379(define_insn "*cmpsi"
0b85d816
HPN
380 [(set (cc0)
381 (compare
45d5d09c
HPN
382 (match_operand:SI 0 "nonimmediate_operand" "r,r,r, Q>,r,r,m")
383 (match_operand:SI 1 "general_operand" "I,r,Q>,r, P,g,r")))]
0b85d816
HPN
384 ""
385 "@
386 cmpq %1,%0
387 cmp.d %1,%0
388 cmp.d %1,%0
0b85d816
HPN
389 cmp.d %0,%1
390 cmp%e1.%z1 %1,%0
391 cmp.d %1,%0
0b85d816 392 cmp.d %0,%1"
45d5d09c
HPN
393 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no")
394 (set_attr "cc" "normal,normal,normal,rev,normal,normal,rev")])
0b85d816 395
f90b7a5a 396(define_insn "*cmp<mode>"
0b85d816 397 [(set (cc0)
45d5d09c
HPN
398 (compare (match_operand:BW 0 "nonimmediate_operand" "r,r, Q>,r,m")
399 (match_operand:BW 1 "general_operand" "r,Q>,r, g,r")))]
0b85d816
HPN
400 ""
401 "@
22c3c091
HPN
402 cmp<m> %1,%0
403 cmp<m> %1,%0
22c3c091
HPN
404 cmp<m> %0,%1
405 cmp<m> %1,%0
22c3c091 406 cmp<m> %0,%1"
45d5d09c
HPN
407 [(set_attr "slottable" "yes,yes,yes,no,no")
408 (set_attr "cc" "normal,normal,rev,normal,rev")])
0b85d816
HPN
409\f
410;; Pattern matching the BTST insn.
411;; It is useful for "if (i & val)" constructs, where val is an exact
412;; power of 2, or if val + 1 is a power of two, where we check for a bunch
413;; of zeros starting at bit 0).
414
415;; SImode. This mode is the only one needed, since gcc automatically
109b748d 416;; extends subregs for lower-size modes. FIXME: Add testcase.
0b85d816
HPN
417(define_insn "*btst"
418 [(set (cc0)
f90b7a5a
PB
419 (compare
420 (zero_extract:SI
421 (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
422 (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
423 (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r"))
424 (const_int 0)))]
0b85d816 425 ;; Either it is a single bit, or consecutive ones starting at 0.
45d5d09c 426 ;; The btst ones depend on stuff in NOTICE_UPDATE_CC.
991c42ac 427 "CONST_INT_P (operands[1])
0b85d816
HPN
428 && (operands[1] == const1_rtx || operands[2] == const0_rtx)
429 && (REG_S_P (operands[0])
430 || (operands[1] == const1_rtx
431 && REG_S_P (operands[2])
991c42ac 432 && CONST_INT_P (operands[0])
45d5d09c
HPN
433 && exact_log2 (INTVAL (operands[0])) >= 0))
434 && !TARGET_CCINIT"
0b85d816 435
45d5d09c 436;; The next-to-last "&&" condition above should be caught by some kind of
0b85d816
HPN
437;; canonicalization in gcc, but we can easily help with it here.
438;; It results from expressions of the type
439;; "power_of_2_value & (1 << y)".
440;;
441;; Since there may be codes with tests in on bits (in constant position)
442;; beyond the size of a word, handle that by assuming those bits are 0.
443;; GCC should handle that, but it's a matter of easily-added belts while
444;; having suspenders.
445
446 "@
447 btstq (%1-1),%0
45d5d09c 448 cmpq 0,%0
0b85d816
HPN
449 btstq %2,%0
450 clearf nz
451 btst %2,%0
452 clearf nz
453 cmpq %p0,%2"
45d5d09c
HPN
454 [(set_attr "slottable" "yes")
455 (set_attr "cc" "noov32")])
0b85d816
HPN
456\f
457;; Move insns.
458
459;; The whole mandatory movdi family is here; expander, "anonymous"
460;; recognizer and splitter. We're forced to have a movdi pattern,
461;; although GCC should be able to split it up itself. Normally it can,
462;; but if other insns have DI operands (as is the case here), reload
463;; must be able to generate or match a movdi. many testcases fail at
464;; -O3 or -fssa if we don't have this. FIXME: Fix GCC... See
465;; <URL:http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00104.html>.
466;; However, a patch from Richard Kenner (similar to the cause of
467;; discussion at the URL above), indicates otherwise. See
468;; <URL:http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00554.html>.
469;; The truth has IMO is not been decided yet, so check from time to
470;; time by disabling the movdi patterns.
471
22c3c091
HPN
472;; To appease testcase gcc.c-torture/execute/920501-2.c (and others) at
473;; -O0, we need a movdi as a temporary measure. Here's how things fail:
474;; A cmpdi RTX needs reloading (global):
475;; (insn 185 326 186 (set (cc0)
476;; (compare (mem/f:DI (reg/v:SI 22) 0)
477;; (const_int 1 [0x1]))) 4 {cmpdi} (nil)
478;; (nil))
479;; Now, reg 22 is reloaded for input address, and the mem is also moved
480;; out of the instruction (into a register), since one of the operands
481;; must be a register. Reg 22 is reloaded (into reg 10), and the mem is
482;; moved out and synthesized in SImode parts (reg 9, reg 10 - should be ok
483;; wrt. overlap). The bad things happen with the synthesis in
484;; emit_move_insn_1; the location where to substitute reg 10 is lost into
485;; two new RTX:es, both still having reg 22. Later on, the left-over reg
486;; 22 is recognized to have an equivalent in memory which is substituted
487;; straight in, and we end up with an unrecognizable insn:
488;; (insn 325 324 326 (set (reg:SI 9 r9)
489;; (mem/f:SI (mem:SI (plus:SI (reg:SI 8 r8)
490;; (const_int -84 [0xffffffac])) 0) 0)) -1 (nil)
491;; (nil))
492;; which is the first part of the reloaded synthesized "movdi".
493;; The right thing would be to add equivalent replacement locations for
494;; insn with pseudos that need more reloading. The question is where.
495
0b85d816
HPN
496(define_expand "movdi"
497 [(set (match_operand:DI 0 "nonimmediate_operand" "")
498 (match_operand:DI 1 "general_operand" ""))]
499 ""
0b85d816 500{
45d5d09c
HPN
501 if (MEM_P (operands[0])
502 && operands[1] != const0_rtx
503 && (!TARGET_V32 || (!REG_P (operands[1]) && can_create_pseudo_p ())))
0b85d816
HPN
504 operands[1] = copy_to_mode_reg (DImode, operands[1]);
505
506 /* Some other ports (as of 2001-09-10 for example mcore and romp) also
507 prefer to split up constants early, like this. The testcase in
508 gcc.c-torture/execute/961213-1.c shows that CSE2 gets confused by the
509 resulting subreg sets when using the construct from mcore (as of FSF
049746c2 510 CVS, version -r 1.5), and it believes that the high part (the last one
d70dcf29 511 emitted) is the final value. */
991c42ac 512 if ((CONST_INT_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
0b85d816
HPN
513 && ! reload_completed
514 && ! reload_in_progress)
515 {
516 rtx insns;
517 rtx op0 = operands[0];
518 rtx op1 = operands[1];
519
520 start_sequence ();
521 emit_move_insn (operand_subword (op0, 0, 1, DImode),
522 operand_subword (op1, 0, 1, DImode));
523 emit_move_insn (operand_subword (op0, 1, 1, DImode),
524 operand_subword (op1, 1, 1, DImode));
525 insns = get_insns ();
526 end_sequence ();
527
d70dcf29 528 emit_insn (insns);
0b85d816
HPN
529 DONE;
530 }
22c3c091 531})
0b85d816 532
45d5d09c 533(define_insn_and_split "*movdi_insn_non_v32"
477c433d 534 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rx,m")
45d5d09c
HPN
535 (match_operand:DI 1 "general_operand" "rx,g,rxM"))]
536 "(register_operand (operands[0], DImode)
537 || register_operand (operands[1], DImode)
538 || operands[1] == const0_rtx)
539 && !TARGET_V32"
540 "#"
541 "&& reload_completed"
542 [(match_dup 2)]
543 "operands[2] = cris_split_movdx (operands);")
0b85d816 544
45d5d09c
HPN
545;; Overlapping (but non-identical) source memory address and destination
546;; register would be a compiler bug, so we don't have to specify that.
547(define_insn "*movdi_v32"
548 [(set
549 (match_operand:DI 0 "nonimmediate_operand" "=r,rx,&r,>, m,r,x,m")
550 (match_operand:DI 1 "general_operand" "rxi,r>,m, rx,r,m,m,x"))]
551 "TARGET_V32"
552{
553 switch (which_alternative)
554 {
555 /* FIXME: 1) Use autoincrement where possible. 2) Have peephole2,
556 particularly for cases where the address register is dead. */
557 case 5:
558 if (REGNO (operands[0]) == REGNO (XEXP (operands[1], 0)))
559 return "addq 4,%L1\;move.d %1,%H0\;subq 4,%L1\;move.d %1,%M0";
560 gcc_assert (REGNO (operands[0]) + 1 == REGNO (XEXP (operands[1], 0)));
561 return "move.d [%L1+],%M0\;move.d [%L1],%H0";
562 case 2:
563 /* We could do away with the addq if we knew the address-register
564 isn't ACR. If we knew the address-register is dead, we could do
565 away with the subq too. */
566 return "move.d [%L1],%M0\;addq 4,%L1\;move.d [%L1],%H0\;subq 4,%L1";
567 case 4:
568 return "move.d %M1,[%L0]\;addq 4,%L0\;move.d %H1,[%L0]\;subq 4,%L0";
569 case 6:
570 return "move [%L1],%M0\;addq 4,%L1\;move [%L1],%H0\;subq 4,%L1";
571 case 7:
572 return "move %M1,[%L0]\;addq 4,%L0\;move %H1,[%L0]\;subq 4,%L0";
573
574 default:
575 return "#";
576 }
577}
578 ;; The non-split cases clobber cc0 because of their adds and subs.
579 ;; Beware that NOTICE_UPDATE_CC is called before the forced split happens.
580 [(set_attr "cc" "*,*,clobber,*,clobber,clobber,*,*")])
581
582;; Much like "*movdi_insn_non_v32". Overlapping registers and constants
583;; is handled so much better in cris_split_movdx.
0b85d816
HPN
584(define_split
585 [(set (match_operand:DI 0 "nonimmediate_operand" "")
586 (match_operand:DI 1 "general_operand" ""))]
45d5d09c
HPN
587 "TARGET_V32
588 && reload_completed
589 && (!MEM_P (operands[0]) || !REG_P (XEXP (operands[0], 0)))
590 && (!MEM_P (operands[1]) || !REG_P (XEXP (operands[1], 0)))"
0b85d816
HPN
591 [(match_dup 2)]
592 "operands[2] = cris_split_movdx (operands);")
593\f
594;; Side-effect patterns for move.S1 [rx=ry+rx.S2],rw
595;; and move.S1 [rx=ry+i],rz
596;; Then movs.S1 and movu.S1 for both modes.
597;;
598;; move.S1 [rx=ry+rz.S],rw avoiding when rx is ry, or rw is rx
599;; FIXME: These could have anonymous mode for operand 0.
45d5d09c 600;; FIXME: Special registers' alternatives too.
0b85d816 601
22c3c091
HPN
602(define_insn "*mov_side<mode>_biap"
603 [(set (match_operand:BW 0 "register_operand" "=r,r")
604 (mem:BW (plus:SI
0b85d816
HPN
605 (mult:SI (match_operand:SI 1 "register_operand" "r,r")
606 (match_operand:SI 2 "const_int_operand" "n,n"))
607 (match_operand:SI 3 "register_operand" "r,r"))))
608 (set (match_operand:SI 4 "register_operand" "=*3,r")
609 (plus:SI (mult:SI (match_dup 1)
610 (match_dup 2))
611 (match_dup 3)))]
612 "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
613 "@
614 #
22c3c091 615 move<m> [%4=%3+%1%T2],%0")
0b85d816 616
8ad46d34 617(define_insn "*mov_sidesisf_biap"
477c433d 618 [(set (match_operand 0 "register_operand" "=r,r,x,x")
8ad46d34 619 (mem (plus:SI
477c433d
HPN
620 (mult:SI (match_operand:SI 1 "register_operand" "r,r,r,r")
621 (match_operand:SI 2 "const_int_operand" "n,n,n,n"))
622 (match_operand:SI 3 "register_operand" "r,r,r,r"))))
623 (set (match_operand:SI 4 "register_operand" "=*3,r,*3,r")
0b85d816
HPN
624 (plus:SI (mult:SI (match_dup 1)
625 (match_dup 2))
626 (match_dup 3)))]
8ad46d34
HPN
627 "GET_MODE_SIZE (GET_MODE (operands[0])) == UNITS_PER_WORD
628 && cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
0b85d816
HPN
629 "@
630 #
477c433d
HPN
631 move.%s0 [%4=%3+%1%T2],%0
632 #
633 move [%4=%3+%1%T2],%0")
0b85d816
HPN
634\f
635;; move.S1 [rx=ry+i],rz
636;; avoiding move.S1 [ry=ry+i],rz
637;; and move.S1 [rz=ry+i],rz
638;; Note that "i" is allowed to be a register.
0b85d816 639
22c3c091 640(define_insn "*mov_side<mode>"
1165f377 641 [(set (match_operand:BW 0 "register_operand" "=r,r,r,r,r")
22c3c091 642 (mem:BW
1165f377
HPN
643 (plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r,r,r,R,R")
644 (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn,r,r"))))
645 (set (match_operand:SI 3 "register_operand" "=*1,r,r,*2,r")
0b85d816
HPN
646 (plus:SI (match_dup 1)
647 (match_dup 2)))]
648 "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
0b85d816 649{
1165f377 650 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 651 && (!CONST_INT_P (operands[2])
0b85d816
HPN
652 || INTVAL (operands[2]) > 127
653 || INTVAL (operands[2]) < -128
06cadf63
AS
654 || satisfies_constraint_N (operands[2])
655 || satisfies_constraint_J (operands[2])))
22c3c091 656 return "#";
1165f377
HPN
657 if (which_alternative == 4)
658 return "move<m> [%3=%2%S1],%0";
22c3c091
HPN
659 return "move<m> [%3=%1%S2],%0";
660})
0b85d816 661
8ad46d34 662(define_insn "*mov_sidesisf"
1165f377 663 [(set (match_operand 0 "register_operand" "=r,r,r,x,x,x,r,r,x,x")
8ad46d34 664 (mem
477c433d 665 (plus:SI
1165f377
HPN
666 (match_operand:SI 1 "cris_bdap_operand" "%r,r,r,r,r,r,R,R,R,R")
667 (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn,r>Rn,r,>Rn,r,r,r,r"))))
668 (set (match_operand:SI 3 "register_operand" "=*1,r,r,*1,r,r,*2,r,*2,r")
0b85d816
HPN
669 (plus:SI (match_dup 1)
670 (match_dup 2)))]
8ad46d34
HPN
671 "GET_MODE_SIZE (GET_MODE (operands[0])) == UNITS_PER_WORD
672 && cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
0b85d816 673{
1165f377
HPN
674 if ((which_alternative == 0
675 || which_alternative == 3
676 || which_alternative == 6
677 || which_alternative == 8)
991c42ac 678 && (!CONST_INT_P (operands[2])
0b85d816
HPN
679 || INTVAL (operands[2]) > 127
680 || INTVAL (operands[2]) < -128
06cadf63
AS
681 || satisfies_constraint_N (operands[2])
682 || satisfies_constraint_J (operands[2])))
477c433d
HPN
683 return "#";
684 if (which_alternative < 3)
685 return "move.%s0 [%3=%1%S2],%0";
1165f377
HPN
686 if (which_alternative == 7)
687 return "move.%s0 [%3=%2%S1],%0";
688 if (which_alternative == 9)
689 return "move [%3=%2%S1],%0";
477c433d
HPN
690 return "move [%3=%1%S2],%0";
691})
0b85d816
HPN
692\f
693;; Other way around; move to memory.
694
049746c2
HPN
695;; Note that the condition (which for side-effect patterns is usually a
696;; call to cris_side_effect_mode_ok), isn't consulted for register
697;; allocation preferences -- constraints is the method for that. The
698;; drawback is that we can't exclude register allocation to cause
699;; "move.s rw,[rx=ry+rz.S]" when rw==rx without also excluding rx==ry or
700;; rx==rz if we use an earlyclobber modifier for the constraint for rx.
701;; Instead of that, we recognize and split the cases where dangerous
702;; register combinations are spotted: where a register is set in the
703;; side-effect, and used in the main insn. We don't handle the case where
704;; the set in the main insn overlaps the set in the side-effect; that case
705;; must be handled in gcc. We handle just the case where the set in the
706;; side-effect overlaps the input operand of the main insn (i.e. just
707;; moves to memory).
0b85d816
HPN
708
709;;
049746c2 710;; move.s rz,[ry=rx+rw.S]
0b85d816 711
22c3c091
HPN
712(define_insn "*mov_side<mode>_biap_mem"
713 [(set (mem:BW (plus:SI
0b85d816
HPN
714 (mult:SI (match_operand:SI 0 "register_operand" "r,r,r")
715 (match_operand:SI 1 "const_int_operand" "n,n,n"))
716 (match_operand:SI 2 "register_operand" "r,r,r")))
22c3c091 717 (match_operand:BW 3 "register_operand" "r,r,r"))
049746c2 718 (set (match_operand:SI 4 "register_operand" "=*2,!3,r")
0b85d816
HPN
719 (plus:SI (mult:SI (match_dup 0)
720 (match_dup 1))
721 (match_dup 2)))]
722 "cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
723 "@
724 #
725 #
22c3c091 726 move<m> %3,[%4=%2+%0%T1]")
0b85d816 727
8ad46d34
HPN
728(define_insn "*mov_sidesisf_biap_mem"
729 [(set (mem (plus:SI
477c433d
HPN
730 (mult:SI (match_operand:SI 0 "register_operand" "r,r,r,r,r,r")
731 (match_operand:SI 1 "const_int_operand" "n,n,n,n,n,n"))
732 (match_operand:SI 2 "register_operand" "r,r,r,r,r,r")))
733 (match_operand 3 "register_operand" "r,r,r,x,x,x"))
734 (set (match_operand:SI 4 "register_operand" "=*2,!3,r,*2,!3,r")
0b85d816
HPN
735 (plus:SI (mult:SI (match_dup 0)
736 (match_dup 1))
737 (match_dup 2)))]
8ad46d34
HPN
738 "GET_MODE_SIZE (GET_MODE (operands[3])) == UNITS_PER_WORD
739 && cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
0b85d816
HPN
740 "@
741 #
742 #
477c433d
HPN
743 move.%s3 %3,[%4=%2+%0%T1]
744 #
745 #
746 move %3,[%4=%2+%0%T1]")
0b85d816 747
049746c2
HPN
748;; Split for the case above where we're out of luck with register
749;; allocation (again, the condition isn't checked for that), and we end up
750;; with the set in the side-effect getting the same register as the input
751;; register.
0b85d816
HPN
752
753(define_split
754 [(parallel
dbb138ce
HPN
755 [(set (match_operator
756 6 "cris_mem_op"
757 [(plus:SI
758 (mult:SI (match_operand:SI 0 "register_operand" "")
759 (match_operand:SI 1 "const_int_operand" ""))
760 (match_operand:SI 2 "register_operand" ""))])
0b85d816
HPN
761 (match_operand 3 "register_operand" ""))
762 (set (match_operand:SI 4 "register_operand" "")
763 (plus:SI (mult:SI (match_dup 0)
764 (match_dup 1))
765 (match_dup 2)))])]
766 "reload_completed && reg_overlap_mentioned_p (operands[4], operands[3])"
767 [(set (match_dup 5) (match_dup 3))
768 (set (match_dup 4) (match_dup 2))
769 (set (match_dup 4)
770 (plus:SI (mult:SI (match_dup 0)
771 (match_dup 1))
772 (match_dup 4)))]
773 "operands[5]
dbb138ce
HPN
774 = replace_equiv_address (operands[6],
775 gen_rtx_PLUS (SImode,
776 gen_rtx_MULT (SImode,
777 operands[0],
778 operands[1]),
779 operands[2]));")
0b85d816
HPN
780\f
781;; move.s rx,[ry=rz+i]
782;; FIXME: These could have anonymous mode for operand 2.
783
784;; QImode
785
22c3c091
HPN
786(define_insn "*mov_side<mode>_mem"
787 [(set (mem:BW
1165f377
HPN
788 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r,R,R,R")
789 (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r>Rn,r,>Rn,r,r,r")))
790 (match_operand:BW 2 "register_operand" "r,r,r,r,r,r,r"))
791 (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r,*1,!*2,r")
0b85d816
HPN
792 (plus:SI (match_dup 0)
793 (match_dup 1)))]
794 "cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
0b85d816 795{
1165f377 796 if ((which_alternative == 0 || which_alternative == 4)
991c42ac 797 && (!CONST_INT_P (operands[1])
0b85d816
HPN
798 || INTVAL (operands[1]) > 127
799 || INTVAL (operands[1]) < -128
06cadf63
AS
800 || satisfies_constraint_N (operands[1])
801 || satisfies_constraint_J (operands[1])))
22c3c091 802 return "#";
1165f377 803 if (which_alternative == 1 || which_alternative == 5)
22c3c091 804 return "#";
1165f377
HPN
805 if (which_alternative == 6)
806 return "move.%s2 %2,[%3=%1%S0]";
22c3c091
HPN
807 return "move<m> %2,[%3=%0%S1]";
808})
0b85d816
HPN
809
810;; SImode
811
8ad46d34
HPN
812(define_insn "*mov_sidesisf_mem"
813 [(set (mem
477c433d
HPN
814 (plus:SI
815 (match_operand:SI
4a60d778
HPN
816 0 "cris_bdap_operand"
817 "%r, r, r,r, r, r,r, R,R, R,R, R")
477c433d 818 (match_operand:SI
4a60d778
HPN
819 1 "cris_bdap_operand"
820 "r>Rn,r>Rn,r,>Rn,r>Rn,r,>Rn,r,r, r,r, r")))
821 (match_operand 2 "register_operand"
822 "r, r, r,r, x, x,x, r,r, r,x, x"))
823 (set (match_operand:SI 3 "register_operand"
824 "=*0,!2, r,r, *0, r,r, *1,!*2,r,*1,r")
0b85d816
HPN
825 (plus:SI (match_dup 0)
826 (match_dup 1)))]
8ad46d34
HPN
827 "GET_MODE_SIZE (GET_MODE (operands[2])) == UNITS_PER_WORD
828 && cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
0b85d816 829{
477c433d 830 if ((which_alternative == 0 || which_alternative == 4)
991c42ac 831 && (!CONST_INT_P (operands[1])
0b85d816
HPN
832 || INTVAL (operands[1]) > 127
833 || INTVAL (operands[1]) < -128
06cadf63
AS
834 || satisfies_constraint_N (operands[1])
835 || satisfies_constraint_J (operands[1])))
477c433d 836 return "#";
1165f377 837 if (which_alternative == 1
4a60d778 838 || which_alternative == 7
1165f377 839 || which_alternative == 8
4a60d778 840 || which_alternative == 10)
477c433d
HPN
841 return "#";
842 if (which_alternative < 4)
843 return "move.%s2 %2,[%3=%0%S1]";
4a60d778 844 if (which_alternative == 9)
1165f377 845 return "move.%s2 %2,[%3=%1%S0]";
4a60d778 846 if (which_alternative == 11)
1165f377 847 return "move %2,[%3=%1%S0]";
477c433d
HPN
848 return "move %2,[%3=%0%S1]";
849})
0b85d816
HPN
850
851;; Like the biap case, a split where the set in the side-effect gets the
049746c2
HPN
852;; same register as the input register to the main insn, since the
853;; condition isn't checked at register allocation.
0b85d816
HPN
854
855(define_split
856 [(parallel
dbb138ce
HPN
857 [(set (match_operator
858 4 "cris_mem_op"
859 [(plus:SI
860 (match_operand:SI 0 "cris_bdap_operand" "")
861 (match_operand:SI 1 "cris_bdap_operand" ""))])
049746c2 862 (match_operand 2 "register_operand" ""))
0b85d816
HPN
863 (set (match_operand:SI 3 "register_operand" "")
864 (plus:SI (match_dup 0) (match_dup 1)))])]
865 "reload_completed && reg_overlap_mentioned_p (operands[3], operands[2])"
866 [(set (match_dup 4) (match_dup 2))
867 (set (match_dup 3) (match_dup 0))
868 (set (match_dup 3) (plus:SI (match_dup 3) (match_dup 1)))]
dbb138ce 869 "")
0b85d816
HPN
870\f
871;; Clear memory side-effect patterns. It is hard to get to the mode if
872;; the MEM was anonymous, so there will be one for each mode.
873
22c3c091 874;; clear.[bwd] [ry=rx+rw.s2]
0b85d816 875
22c3c091
HPN
876(define_insn "*clear_side<mode>_biap"
877 [(set (mem:BWD (plus:SI
878 (mult:SI (match_operand:SI 0 "register_operand" "r,r")
879 (match_operand:SI 1 "const_int_operand" "n,n"))
880 (match_operand:SI 2 "register_operand" "r,r")))
0b85d816
HPN
881 (const_int 0))
882 (set (match_operand:SI 3 "register_operand" "=*2,r")
883 (plus:SI (mult:SI (match_dup 0)
884 (match_dup 1))
885 (match_dup 2)))]
886 "cris_side_effect_mode_ok (MULT, operands, 3, 2, 0, 1, -1)"
887 "@
888 #
22c3c091 889 clear<m> [%3=%2+%0%T1]")
0b85d816 890
22c3c091 891;; clear.[bwd] [ry=rz+i]
0b85d816 892
22c3c091
HPN
893(define_insn "*clear_side<mode>"
894 [(set (mem:BWD
1165f377
HPN
895 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,R,R")
896 (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))
0b85d816 897 (const_int 0))
1165f377 898 (set (match_operand:SI 2 "register_operand" "=*0,r,r,*1,r")
0b85d816
HPN
899 (plus:SI (match_dup 0)
900 (match_dup 1)))]
901 "cris_side_effect_mode_ok (PLUS, operands, 2, 0, 1, -1, -1)"
0b85d816 902{
1165f377 903 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 904 && (!CONST_INT_P (operands[1])
0b85d816
HPN
905 || INTVAL (operands[1]) > 127
906 || INTVAL (operands[1]) < -128
06cadf63
AS
907 || satisfies_constraint_N (operands[1])
908 || satisfies_constraint_J (operands[1])))
22c3c091 909 return "#";
1165f377
HPN
910 if (which_alternative == 4)
911 return "clear<m> [%2=%1%S0]";
22c3c091
HPN
912 return "clear<m> [%2=%0%S1]";
913})
0b85d816 914\f
0b85d816
HPN
915;; Normal move patterns from SI on.
916
917(define_expand "movsi"
918 [(set
919 (match_operand:SI 0 "nonimmediate_operand" "")
920 (match_operand:SI 1 "cris_general_operand_or_symbol" ""))]
921 ""
0b85d816
HPN
922{
923 /* If the output goes to a MEM, make sure we have zero or a register as
924 input. */
991c42ac 925 if (MEM_P (operands[0])
0b85d816
HPN
926 && ! REG_S_P (operands[1])
927 && operands[1] != const0_rtx
3a0e695a 928 && can_create_pseudo_p ())
0b85d816
HPN
929 operands[1] = force_reg (SImode, operands[1]);
930
931 /* If we're generating PIC and have an incoming symbol, validize it to a
932 general operand or something that will match a special pattern.
933
934 FIXME: Do we *have* to recognize anything that would normally be a
935 valid symbol? Can we exclude global PIC addresses with an added
936 offset? */
c00fc5cf
HPN
937 if (flag_pic
938 && CONSTANT_ADDRESS_P (operands[1])
45d5d09c 939 && !cris_valid_pic_const (operands[1], false))
c00fc5cf
HPN
940 {
941 enum cris_pic_symbol_type t = cris_pic_symbol_type_of (operands[1]);
942
943 gcc_assert (t != cris_no_symbol);
944
945 if (! REG_S_P (operands[0]))
946 {
947 /* We must have a register as destination for what we're about to
948 do, and for the patterns we generate. */
b3a13419 949 CRIS_ASSERT (can_create_pseudo_p ());
c00fc5cf
HPN
950 operands[1] = force_reg (SImode, operands[1]);
951 }
952 else
953 {
954 /* FIXME: add a REG_EQUAL (or is it REG_EQUIV) note to the
955 destination register for the symbol. It might not be
956 worth it. Measure. */
e3b5732b 957 crtl->uses_pic_offset_table = 1;
45d5d09c 958 if (t == cris_rel_symbol)
c00fc5cf
HPN
959 {
960 /* Change a "move.d sym(+offs),rN" into (allocate register rM)
45d5d09c
HPN
961 for pre-v32:
962 "move.d (const (plus (unspec [sym]
963 CRIS_UNSPEC_GOTREL) offs)),rM" "add.d rPIC,rM,rN"
964 and for v32:
c00fc5cf 965 "move.d (const (plus (unspec [sym]
45d5d09c 966 CRIS_UNSPEC_PCREL) offs)),rN". */
c00fc5cf
HPN
967 rtx tem, rm, rn = operands[0];
968 rtx sym = GET_CODE (operands[1]) != CONST
969 ? operands[1] : get_related_value (operands[1]);
970 HOST_WIDE_INT offs = get_integer_term (operands[1]);
971
b3a13419 972 gcc_assert (can_create_pseudo_p ());
45d5d09c
HPN
973
974 if (TARGET_V32)
975 {
976 tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym),
977 CRIS_UNSPEC_PCREL);
978 if (offs != 0)
979 tem = plus_constant (tem, offs);
980 rm = rn;
981 emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
982 }
983 else
984 {
985 /* We still uses GOT-relative addressing for
986 pre-v32. */
e3b5732b 987 crtl->uses_pic_offset_table = 1;
45d5d09c
HPN
988 tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym),
989 CRIS_UNSPEC_GOTREL);
990 if (offs != 0)
991 tem = plus_constant (tem, offs);
992 rm = gen_reg_rtx (Pmode);
993 emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
994 if (expand_binop (Pmode, add_optab, rm, pic_offset_table_rtx,
995 rn, 0, OPTAB_LIB_WIDEN) != rn)
996 internal_error ("expand_binop failed in movsi gotrel");
997 }
c00fc5cf
HPN
998 DONE;
999 }
1000 else if (t == cris_got_symbol)
1001 {
1002 /* Change a "move.d sym,rN" into (allocate register rM, rO)
1003 "move.d (const (unspec [sym] CRIS_UNSPEC_GOTREAD)),rM"
1004 "add.d rPIC,rM,rO", "move.d [rO],rN" with
1005 the memory access marked as read-only. */
1006 rtx tem, mem, rm, ro, rn = operands[0];
b3a13419 1007 gcc_assert (can_create_pseudo_p ());
c00fc5cf
HPN
1008 tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
1009 CRIS_UNSPEC_GOTREAD);
1010 rm = gen_reg_rtx (Pmode);
1011 emit_move_insn (rm, gen_rtx_CONST (Pmode, tem));
1012 ro = gen_reg_rtx (Pmode);
1013 if (expand_binop (Pmode, add_optab, rm, pic_offset_table_rtx,
1014 ro, 0, OPTAB_LIB_WIDEN) != ro)
1015 internal_error ("expand_binop failed in movsi got");
1016 mem = gen_rtx_MEM (Pmode, ro);
1017
1018 /* This MEM doesn't alias anything. Whether it
1019 aliases other same symbols is unimportant. */
1020 set_mem_alias_set (mem, new_alias_set ());
1021 MEM_NOTRAP_P (mem) = 1;
45d5d09c
HPN
1022
1023 /* We can set the GOT memory read of a non-called symbol
1024 to readonly, but not that of a call symbol, as those
1025 are subject to lazy evaluation and usually have the value
1026 changed from the first call to the second (but
1027 constant thereafter). */
c00fc5cf
HPN
1028 MEM_READONLY_P (mem) = 1;
1029 emit_move_insn (rn, mem);
1030 DONE;
1031 }
1032 else
1033 {
1034 /* We get here when we have to change something that would
1035 be recognizable if it wasn't PIC. A ``sym'' is ok for
1036 PIC symbols both with and without a GOT entry. And ``sym
1037 + offset'' is ok for local symbols, so the only thing it
1038 could be, is a global symbol with an offset. Check and
1039 abort if not. */
1040 rtx reg = gen_reg_rtx (Pmode);
1041 rtx sym = get_related_value (operands[1]);
1042 HOST_WIDE_INT offs = get_integer_term (operands[1]);
1043
b3a13419 1044 gcc_assert (can_create_pseudo_p ()
c00fc5cf
HPN
1045 && t == cris_got_symbol_needing_fixup
1046 && sym != NULL_RTX && offs != 0);
1047
1048 emit_move_insn (reg, sym);
1049 if (expand_binop (SImode, add_optab, reg,
1050 GEN_INT (offs), operands[0], 0,
1051 OPTAB_LIB_WIDEN) != operands[0])
1052 internal_error ("expand_binop failed in movsi got+offs");
1053 DONE;
1054 }
1055 }
1056 }
b6c34129 1057})
0b85d816 1058
c00fc5cf
HPN
1059(define_insn "*movsi_got_load"
1060 [(set (reg:SI CRIS_GOT_REGNUM) (unspec:SI [(const_int 0)] CRIS_UNSPEC_GOT))]
1061 "flag_pic"
45d5d09c
HPN
1062{
1063 return TARGET_V32
1064 ? "lapc _GLOBAL_OFFSET_TABLE_,%:"
1065 : "move.d $pc,%:\;sub.d .:GOTOFF,%:";
1066}
c00fc5cf
HPN
1067 [(set_attr "cc" "clobber")])
1068
0b85d816
HPN
1069(define_insn "*movsi_internal"
1070 [(set
45d5d09c
HPN
1071 (match_operand:SI 0 "nonimmediate_operand"
1072 "=r,r, r,Q>,r,Q>,g,r,r, r,g,rQ>,x, m,x")
1073 (match_operand:SI 1 "cris_general_operand_or_pic_source"
1074 "r,Q>,M,M, I,r, M,n,!S,g,r,x, rQ>,x,gi"))]
c00fc5cf 1075 ;; Note that we prefer not to use the S alternative (if for some reason
45d5d09c 1076 ;; it competes with others) above, but g matches S.
0b85d816 1077 ""
0b85d816
HPN
1078{
1079 /* Better to have c-switch here; it is worth it to optimize the size of
1080 move insns. The alternative would be to try to find more constraint
1081 letters. FIXME: Check again. It seems this could shrink a bit. */
1082 switch (which_alternative)
1083 {
45d5d09c
HPN
1084 case 9:
1085 if (TARGET_V32)
1086 {
1087 if (!flag_pic
1088 && (GET_CODE (operands[1]) == SYMBOL_REF
1089 || GET_CODE (operands[1]) == LABEL_REF
1090 || GET_CODE (operands[1]) == CONST))
1091 {
1092 /* FIXME: Express this through (set_attr cc none) instead,
1093 since we can't express the ``none'' at this point. FIXME:
1094 Use lapc for everything except const_int and when next cc0
1095 user would want the flag setting. */
1096 CC_STATUS_INIT;
1097 return "lapc %1,%0";
1098 }
1099 if (flag_pic == 1
1100 && GET_CODE (operands[1]) == CONST
1101 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
1102 && XINT (XEXP (operands[1], 0), 1) == CRIS_UNSPEC_GOTREAD)
1103 return "movu.w %1,%0";
1104 }
1105 /* FALLTHROUGH */
0b85d816
HPN
1106 case 0:
1107 case 1:
1108 case 5:
0b85d816 1109 case 10:
22c3c091 1110 return "move.d %1,%0";
0b85d816 1111
f60c7155
HPN
1112 case 11:
1113 case 12:
1114 case 13:
1115 case 14:
22c3c091 1116 return "move %d1,%0";
f60c7155 1117
0b85d816
HPN
1118 case 2:
1119 case 3:
1120 case 6:
22c3c091 1121 return "clear.d %0";
0b85d816
HPN
1122
1123 /* Constants -32..31 except 0. */
1124 case 4:
22c3c091 1125 return "moveq %1,%0";
0b85d816
HPN
1126
1127 /* We can win a little on constants -32768..-33, 32..65535. */
1128 case 7:
1129 if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) < 65536)
1130 {
1131 if (INTVAL (operands[1]) < 256)
22c3c091
HPN
1132 return "movu.b %1,%0";
1133 return "movu.w %1,%0";
0b85d816
HPN
1134 }
1135 else if (INTVAL (operands[1]) >= -32768 && INTVAL (operands[1]) < 32768)
1136 {
1137 if (INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) < 128)
22c3c091
HPN
1138 return "movs.b %1,%0";
1139 return "movs.w %1,%0";
0b85d816 1140 }
22c3c091 1141 return "move.d %1,%0";
0b85d816 1142
d29b4b1b 1143 case 8:
c00fc5cf
HPN
1144 {
1145 rtx tem = operands[1];
1146 gcc_assert (GET_CODE (tem) == CONST);
1147 tem = XEXP (tem, 0);
1148 if (GET_CODE (tem) == PLUS
1149 && GET_CODE (XEXP (tem, 0)) == UNSPEC
45d5d09c
HPN
1150 && (XINT (XEXP (tem, 0), 1) == CRIS_UNSPEC_GOTREL
1151 || XINT (XEXP (tem, 0), 1) == CRIS_UNSPEC_PCREL)
991c42ac 1152 && CONST_INT_P (XEXP (tem, 1)))
c00fc5cf
HPN
1153 tem = XEXP (tem, 0);
1154 gcc_assert (GET_CODE (tem) == UNSPEC);
1155 switch (XINT (tem, 1))
1156 {
1157 case CRIS_UNSPEC_GOTREAD:
1158 case CRIS_UNSPEC_PLTGOTREAD:
1159 /* Using sign-extend mostly to be consistent with the
1160 indexed addressing mode. */
1161 if (flag_pic == 1)
1162 return "movs.w %1,%0";
45d5d09c
HPN
1163 return "move.d %1,%0";
1164
c00fc5cf 1165 case CRIS_UNSPEC_GOTREL:
45d5d09c
HPN
1166 case CRIS_UNSPEC_PLT_GOTREL:
1167 gcc_assert (!TARGET_V32);
c00fc5cf
HPN
1168 return "move.d %1,%0";
1169
45d5d09c
HPN
1170 case CRIS_UNSPEC_PCREL:
1171 case CRIS_UNSPEC_PLT_PCREL:
1172 gcc_assert (TARGET_V32);
1173 return "lapc %1,%0";
1174
c00fc5cf
HPN
1175 default:
1176 gcc_unreachable ();
1177 }
1178 }
0b85d816 1179 default:
22c3c091 1180 return "BOGUS: %1 to %0";
0b85d816 1181 }
22c3c091 1182}
f60c7155
HPN
1183 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,no,no,no,yes,yes,no,no")
1184 (set_attr "cc" "*,*,*,*,*,*,*,*,*,*,*,none,none,none,none")])
0b85d816
HPN
1185\f
1186;; Extend operations with side-effect from mem to register, using
1187;; MOVS/MOVU. These are from mem to register only.
1188;;
1189;; [rx=ry+rz.S]
1190;;
1191;; QImode to HImode
1192;;
1193;; FIXME: Can we omit extend to HImode, since GCC should truncate for
1194;; HImode by itself? Perhaps use only anonymous modes?
1195
1196(define_insn "*ext_sideqihi_biap"
1197 [(set (match_operand:HI 0 "register_operand" "=r,r")
1198 (match_operator:HI
1199 5 "cris_extend_operator"
1200 [(mem:QI (plus:SI
1201 (mult:SI (match_operand:SI 1 "register_operand" "r,r")
1202 (match_operand:SI 2 "const_int_operand" "n,n"))
1203 (match_operand:SI 3 "register_operand" "r,r")))]))
1204 (set (match_operand:SI 4 "register_operand" "=*3,r")
1205 (plus:SI (mult:SI (match_dup 1)
1206 (match_dup 2))
1207 (match_dup 3)))]
1208 "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
1209 "@
1210 #
1211 mov%e5.%m5 [%4=%3+%1%T2],%0")
1212
22c3c091 1213(define_insn "*ext_side<mode>si_biap"
0b85d816
HPN
1214 [(set (match_operand:SI 0 "register_operand" "=r,r")
1215 (match_operator:SI
1216 5 "cris_extend_operator"
22c3c091 1217 [(mem:BW (plus:SI
0b85d816
HPN
1218 (mult:SI (match_operand:SI 1 "register_operand" "r,r")
1219 (match_operand:SI 2 "const_int_operand" "n,n"))
1220 (match_operand:SI 3 "register_operand" "r,r")))]))
1221 (set (match_operand:SI 4 "register_operand" "=*3,r")
1222 (plus:SI (mult:SI (match_dup 1)
1223 (match_dup 2))
1224 (match_dup 3)))]
1225 "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
1226 "@
1227 #
22c3c091 1228 mov%e5<m> [%4=%3+%1%T2],%0")
0b85d816
HPN
1229\f
1230;; Same but [rx=ry+i]
1231
1232;; QImode to HImode
1233
1234(define_insn "*ext_sideqihi"
1165f377 1235 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
0b85d816
HPN
1236 (match_operator:HI
1237 4 "cris_extend_operator"
1238 [(mem:QI (plus:SI
1165f377
HPN
1239 (match_operand:SI 1 "cris_bdap_operand" "%r,r,r,R,R")
1240 (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))]))
1241 (set (match_operand:SI 3 "register_operand" "=*1,r,r,*2,r")
0b85d816
HPN
1242 (plus:SI (match_dup 1)
1243 (match_dup 2)))]
1244 "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
0b85d816 1245{
1165f377 1246 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 1247 && (!CONST_INT_P (operands[2])
0b85d816
HPN
1248 || INTVAL (operands[2]) > 127
1249 || INTVAL (operands[2]) < -128
06cadf63
AS
1250 || satisfies_constraint_N (operands[2])
1251 || satisfies_constraint_J (operands[2])))
22c3c091 1252 return "#";
1165f377
HPN
1253 if (which_alternative == 4)
1254 return "mov%e4.%m4 [%3=%2%S1],%0";
22c3c091
HPN
1255 return "mov%e4.%m4 [%3=%1%S2],%0";
1256})
0b85d816 1257
22c3c091 1258(define_insn "*ext_side<mode>si"
1165f377 1259 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
0b85d816
HPN
1260 (match_operator:SI
1261 4 "cris_extend_operator"
22c3c091 1262 [(mem:BW (plus:SI
1165f377
HPN
1263 (match_operand:SI 1 "cris_bdap_operand" "%r,r,r,R,R")
1264 (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))]))
1265 (set (match_operand:SI 3 "register_operand" "=*1,r,r,*2,r")
0b85d816
HPN
1266 (plus:SI (match_dup 1)
1267 (match_dup 2)))]
1268 "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
0b85d816 1269{
1165f377 1270 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 1271 && (!CONST_INT_P (operands[2])
0b85d816
HPN
1272 || INTVAL (operands[2]) > 127
1273 || INTVAL (operands[2]) < -128
06cadf63
AS
1274 || satisfies_constraint_N (operands[2])
1275 || satisfies_constraint_J (operands[2])))
22c3c091 1276 return "#";
1165f377
HPN
1277 if (which_alternative == 4)
1278 return "mov%e4<m> [%3=%2%S1],%0";
22c3c091
HPN
1279 return "mov%e4<m> [%3=%1%S2],%0";
1280})
0b85d816
HPN
1281\f
1282;; FIXME: See movsi.
1283
1284(define_insn "movhi"
1285 [(set
f60c7155
HPN
1286 (match_operand:HI 0 "nonimmediate_operand" "=r,r, r,Q>,r,Q>,r,r,r,g,g,r,r,x")
1287 (match_operand:HI 1 "general_operand" "r,Q>,M,M, I,r, L,O,n,M,r,g,x,r"))]
0b85d816 1288 ""
0b85d816
HPN
1289{
1290 switch (which_alternative)
1291 {
1292 case 0:
1293 case 1:
1294 case 5:
1295 case 10:
1296 case 11:
22c3c091 1297 return "move.w %1,%0";
f60c7155
HPN
1298 case 12:
1299 case 13:
22c3c091 1300 return "move %1,%0";
0b85d816
HPN
1301 case 2:
1302 case 3:
1303 case 9:
22c3c091 1304 return "clear.w %0";
0b85d816 1305 case 4:
22c3c091 1306 return "moveq %1,%0";
0b85d816
HPN
1307 case 6:
1308 case 8:
1309 if (INTVAL (operands[1]) < 256 && INTVAL (operands[1]) >= -128)
1310 {
1311 if (INTVAL (operands[1]) > 0)
22c3c091
HPN
1312 return "movu.b %1,%0";
1313 return "movs.b %1,%0";
0b85d816 1314 }
22c3c091 1315 return "move.w %1,%0";
0b85d816 1316 case 7:
22c3c091 1317 return "movEq %b1,%0";
0b85d816 1318 default:
22c3c091 1319 return "BOGUS: %1 to %0";
0b85d816 1320 }
22c3c091 1321}
f60c7155
HPN
1322 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,yes,no,no,no,no,yes,yes")
1323 (set_attr "cc" "*,*,none,none,*,none,*,clobber,*,none,none,*,none,none")])
0b85d816
HPN
1324
1325(define_insn "movstricthi"
1326 [(set
1327 (strict_low_part
23369bef
HPN
1328 (match_operand:HI 0 "nonimmediate_operand" "+r,r, r,Q>,Q>,g,r,g"))
1329 (match_operand:HI 1 "general_operand" "r,Q>,M,M, r, M,g,r"))]
0b85d816
HPN
1330 ""
1331 "@
1332 move.w %1,%0
1333 move.w %1,%0
1334 clear.w %0
1335 clear.w %0
1336 move.w %1,%0
1337 clear.w %0
1338 move.w %1,%0
1339 move.w %1,%0"
1340 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
f60c7155 1341
22c3c091
HPN
1342(define_expand "reload_in<mode>"
1343 [(set (match_operand:BW 2 "register_operand" "=r")
1344 (match_operand:BW 1 "memory_operand" "m"))
1345 (set (match_operand:BW 0 "register_operand" "=x")
f60c7155
HPN
1346 (match_dup 2))]
1347 ""
1348 "")
1349
22c3c091 1350(define_expand "reload_out<mode>"
11e30dd8 1351 [(set (match_operand:BW 2 "register_operand" "=&r")
22c3c091
HPN
1352 (match_operand:BW 1 "register_operand" "x"))
1353 (set (match_operand:BW 0 "memory_operand" "=m")
f60c7155
HPN
1354 (match_dup 2))]
1355 ""
1356 "")
0b85d816
HPN
1357\f
1358(define_insn "movqi"
f60c7155
HPN
1359 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,Q>,r, r,Q>,r,g,g,r,r,r,x")
1360 (match_operand:QI 1 "general_operand" "r,r, Q>,M,M, I,M,r,O,g,x,r"))]
0b85d816
HPN
1361 ""
1362 "@
1363 move.b %1,%0
1364 move.b %1,%0
1365 move.b %1,%0
1366 clear.b %0
1367 clear.b %0
1368 moveq %1,%0
1369 clear.b %0
1370 move.b %1,%0
1371 moveq %b1,%0
f60c7155
HPN
1372 move.b %1,%0
1373 move %1,%0
1374 move %1,%0"
1375 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,yes,no,yes,yes")
1376 (set_attr "cc" "*,*,*,*,*,*,*,*,clobber,*,none,none")])
0b85d816
HPN
1377
1378(define_insn "movstrictqi"
1379 [(set (strict_low_part
23369bef
HPN
1380 (match_operand:QI 0 "nonimmediate_operand" "+r,Q>,r, r,Q>,g,g,r"))
1381 (match_operand:QI 1 "general_operand" "r,r, Q>,M,M, M,r,g"))]
0b85d816
HPN
1382 ""
1383 "@
1384 move.b %1,%0
1385 move.b %1,%0
1386 move.b %1,%0
1387 clear.b %0
1388 clear.b %0
1389 clear.b %0
1390 move.b %1,%0
1391 move.b %1,%0"
1392 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
1393
1394;; The valid "quick" bit-patterns are, except for 0.0, denormalized
1395;; values REALLY close to 0, and some NaN:s (I think; their exponent is
1396;; all ones); the worthwhile one is "0.0".
1397;; It will use clear, so we know ALL types of immediate 0 never change cc.
1398
1399(define_insn "movsf"
f60c7155
HPN
1400 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,Q>,r, r,Q>,g,g,r,r,x,Q>,m,x, x")
1401 (match_operand:SF 1 "general_operand" "r,r, Q>,G,G, G,r,g,x,r,x, x,Q>,g"))]
0b85d816
HPN
1402 ""
1403 "@
1404 move.d %1,%0
1405 move.d %1,%0
1406 move.d %1,%0
1407 clear.d %0
1408 clear.d %0
1409 clear.d %0
1410 move.d %1,%0
f60c7155
HPN
1411 move.d %1,%0
1412 move %1,%0
1413 move %1,%0
1414 move %1,%0
1415 move %1,%0
1416 move %1,%0
1417 move %1,%0"
1418 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no,yes,yes,yes,no,yes,no")])
45d5d09c
HPN
1419\f
1420;; Movem patterns. Primarily for use in function prologue and epilogue.
1421;; The V32 variants have an ordering matching the expectations of the
1422;; standard names "load_multiple" and "store_multiple"; pre-v32 movem
1423;; store R0 in the highest memory location.
1424
1425(define_expand "load_multiple"
1426 [(match_operand:SI 0 "register_operand" "")
1427 (match_operand:SI 1 "memory_operand" "")
1428 (match_operand:SI 2 "const_int_operand" "")]
1429 "TARGET_V32"
1430{
1431 rtx indreg;
1432
1433 /* Apparently the predicate isn't checked, so we need to do so
1434 manually. Once happened for libstdc++-v3 locale_facets.tcc. */
1435 if (!MEM_P (operands[1]))
1436 FAIL;
1437
1438 indreg = XEXP (operands[1], 0);
1439
1440 if (GET_CODE (indreg) == POST_INC)
1441 indreg = XEXP (indreg, 0);
1442 if (!REG_P (indreg)
1443 || GET_CODE (operands[2]) != CONST_INT
1444 || !REG_P (operands[0])
1445 || REGNO (operands[0]) != 0
1446 || INTVAL (operands[2]) > CRIS_SP_REGNUM
1447 || (int) REGNO (indreg) < INTVAL (operands[2]))
1448 FAIL;
1449 gcc_unreachable ();
1450 emit_insn (cris_gen_movem_load (operands[1], operands[2], 0));
1451 DONE;
1452})
1453
1454(define_expand "store_multiple"
1455 [(match_operand:SI 0 "memory_operand" "")
1456 (match_operand:SI 1 "register_operand" "")
1457 (match_operand:SI 2 "const_int_operand" "")]
1458 "TARGET_V32"
1459{
1460 rtx indreg;
1461
1462 /* See load_multiple. */
1463 if (!MEM_P (operands[0]))
1464 FAIL;
1465
1466 indreg = XEXP (operands[0], 0);
1467
1468 if (GET_CODE (indreg) == POST_INC)
1469 indreg = XEXP (indreg, 0);
1470 if (!REG_P (indreg)
1471 || GET_CODE (operands[2]) != CONST_INT
1472 || !REG_P (operands[1])
1473 || REGNO (operands[1]) != 0
1474 || INTVAL (operands[2]) > CRIS_SP_REGNUM
1475 || (int) REGNO (indreg) < INTVAL (operands[2]))
1476 FAIL;
1477 gcc_unreachable ();
1478 cris_emit_movem_store (operands[0], operands[2], 0, false);
1479 DONE;
1480})
04539954 1481
04539954
HPN
1482(define_insn "*cris_load_multiple"
1483 [(match_parallel 0 "cris_load_multiple_op"
1484 [(set (match_operand:SI 1 "register_operand" "=r,r")
1485 (match_operand:SI 2 "memory_operand" "Q,m"))])]
1486 ""
1487 "movem %O0,%o0"
1488 [(set_attr "cc" "none")
1489 (set_attr "slottable" "yes,no")
1490 ;; Not true, but setting the length to 0 causes return sequences (ret
1491 ;; movem) to have the cost they had when (return) included the movem
1492 ;; and reduces the performance penalty taken for needing to emit an
1493 ;; epilogue (in turn copied by bb-reorder) instead of return patterns.
1494 ;; FIXME: temporary change until all insn lengths are correctly
1495 ;; described. FIXME: have better target control over bb-reorder.
1496 (set_attr "length" "0")])
d29b4b1b
HPN
1497
1498(define_insn "*cris_store_multiple"
1499 [(match_parallel 0 "cris_store_multiple_op"
1500 [(set (match_operand:SI 2 "memory_operand" "=Q,m")
1501 (match_operand:SI 1 "register_operand" "r,r"))])]
1502 ""
1503 "movem %o0,%O0"
1504 [(set_attr "cc" "none")
1505 (set_attr "slottable" "yes,no")])
0b85d816
HPN
1506\f
1507
1508;; Sign- and zero-extend insns with standard names.
1509;; Those for integer source operand are ordered with the widest source
1510;; type first.
1511
1512;; Sign-extend.
1513
1514(define_insn "extendsidi2"
1515 [(set (match_operand:DI 0 "register_operand" "=r")
1516 (sign_extend:DI (match_operand:SI 1 "general_operand" "g")))]
1517 ""
1518 "move.d %1,%M0\;smi %H0\;neg.d %H0,%H0")
1519
22c3c091 1520(define_insn "extend<mode>di2"
0b85d816 1521 [(set (match_operand:DI 0 "register_operand" "=r")
22c3c091 1522 (sign_extend:DI (match_operand:BW 1 "general_operand" "g")))]
0b85d816 1523 ""
22c3c091 1524 "movs<m> %1,%M0\;smi %H0\;neg.d %H0,%H0")
0b85d816 1525
22c3c091 1526(define_insn "extend<mode>si2"
0b85d816 1527 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
22c3c091 1528 (sign_extend:SI (match_operand:BW 1 "general_operand" "r,Q>,g")))]
0b85d816 1529 ""
22c3c091 1530 "movs<m> %1,%0"
0b85d816
HPN
1531 [(set_attr "slottable" "yes,yes,no")])
1532
839a4992 1533;; To do a byte->word extension, extend to dword, exept that the top half
0b85d816
HPN
1534;; of the register will be clobbered. FIXME: Perhaps this is not needed.
1535
1536(define_insn "extendqihi2"
1537 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1538 (sign_extend:HI (match_operand:QI 1 "general_operand" "r,Q>,g")))]
1539 ""
1540 "movs.b %1,%0"
1541 [(set_attr "slottable" "yes,yes,no")])
1542\f
1543
1544;; Zero-extend. The DImode ones are synthesized by gcc, so we don't
1545;; specify them here.
1546
22c3c091 1547(define_insn "zero_extend<mode>si2"
0b85d816
HPN
1548 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1549 (zero_extend:SI
22c3c091 1550 (match_operand:BW 1 "nonimmediate_operand" "r,Q>,m")))]
0b85d816 1551 ""
22c3c091 1552 "movu<m> %1,%0"
0b85d816
HPN
1553 [(set_attr "slottable" "yes,yes,no")])
1554
1555;; Same comment as sign-extend QImode to HImode above applies.
1556
1557(define_insn "zero_extendqihi2"
1558 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1559 (zero_extend:HI
1560 (match_operand:QI 1 "nonimmediate_operand" "r,Q>,m")))]
1561 ""
1562 "movu.b %1,%0"
1563 [(set_attr "slottable" "yes,yes,no")])
1564\f
1565;; All kinds of arithmetic and logical instructions.
1566;;
1567;; First, anonymous patterns to match addressing modes with
1568;; side-effects.
1569;;
1570;; op.S [rx=ry+I],rz; (add, sub, or, and, bound).
1571;;
1572;; [rx=ry+rz.S]
0b85d816 1573
22c3c091
HPN
1574(define_insn "*op_side<mode>_biap"
1575 [(set (match_operand:BWD 0 "register_operand" "=r,r")
1576 (match_operator:BWD
0b85d816 1577 6 "cris_orthogonal_operator"
22c3c091
HPN
1578 [(match_operand:BWD 1 "register_operand" "0,0")
1579 (mem:BWD (plus:SI
1580 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1581 (match_operand:SI 3 "const_int_operand" "n,n"))
1582 (match_operand:SI 4 "register_operand" "r,r")))]))
0b85d816
HPN
1583 (set (match_operand:SI 5 "register_operand" "=*4,r")
1584 (plus:SI (mult:SI (match_dup 2)
1585 (match_dup 3))
1586 (match_dup 4)))]
1587 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1588 "@
1589 #
22c3c091 1590 %x6<m> [%5=%4+%2%T3],%0")
0b85d816
HPN
1591\f
1592;; [rx=ry+i] ([%4=%2+%3])
0b85d816 1593
22c3c091 1594(define_insn "*op_side<mode>"
1165f377 1595 [(set (match_operand:BWD 0 "register_operand" "=r,r,r,r,r")
22c3c091 1596 (match_operator:BWD
0b85d816 1597 5 "cris_orthogonal_operator"
1165f377 1598 [(match_operand:BWD 1 "register_operand" "0,0,0,0,0")
22c3c091 1599 (mem:BWD (plus:SI
1165f377
HPN
1600 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r,R,R")
1601 (match_operand:SI 3 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))]))
1602 (set (match_operand:SI 4 "register_operand" "=*2,r,r,*3,r")
0b85d816
HPN
1603 (plus:SI (match_dup 2)
1604 (match_dup 3)))]
1605 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
0b85d816 1606{
1165f377 1607 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 1608 && (!CONST_INT_P (operands[3])
0b85d816
HPN
1609 || INTVAL (operands[3]) > 127
1610 || INTVAL (operands[3]) < -128
06cadf63
AS
1611 || satisfies_constraint_N (operands[3])
1612 || satisfies_constraint_J (operands[3])))
22c3c091 1613 return "#";
1165f377
HPN
1614 if (which_alternative == 4)
1615 return "%x5.%s0 [%4=%3%S2],%0";
22c3c091
HPN
1616 return "%x5<m> [%4=%2%S3],%0";
1617})
0b85d816
HPN
1618\f
1619;; To match all cases for commutative operations we may have to have the
1620;; following pattern for add, or & and. I do not know really, but it does
1621;; not break anything.
1622;;
1623;; FIXME: This really ought to be checked.
1624;;
1625;; op.S [rx=ry+I],rz;
1626;;
1627;; [rx=ry+rz.S]
0b85d816 1628
22c3c091
HPN
1629(define_insn "*op_swap_side<mode>_biap"
1630 [(set (match_operand:BWD 0 "register_operand" "=r,r")
1631 (match_operator:BWD
0b85d816 1632 6 "cris_commutative_orth_op"
22c3c091 1633 [(mem:BWD (plus:SI
0b85d816
HPN
1634 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1635 (match_operand:SI 3 "const_int_operand" "n,n"))
1636 (match_operand:SI 4 "register_operand" "r,r")))
22c3c091 1637 (match_operand:BWD 1 "register_operand" "0,0")]))
0b85d816
HPN
1638 (set (match_operand:SI 5 "register_operand" "=*4,r")
1639 (plus:SI (mult:SI (match_dup 2)
1640 (match_dup 3))
1641 (match_dup 4)))]
1642 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1643 "@
1644 #
22c3c091 1645 %x6<m> [%5=%4+%2%T3],%0")
0b85d816
HPN
1646\f
1647;; [rx=ry+i] ([%4=%2+%3])
1648;; FIXME: These could have anonymous mode for operand 0.
1649
1650;; QImode
1651
22c3c091 1652(define_insn "*op_swap_side<mode>"
1165f377 1653 [(set (match_operand:BWD 0 "register_operand" "=r,r,r,r,r")
22c3c091 1654 (match_operator:BWD
0b85d816 1655 5 "cris_commutative_orth_op"
22c3c091 1656 [(mem:BWD
1165f377
HPN
1657 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r,R,R")
1658 (match_operand:SI 3 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))
1659 (match_operand:BWD 1 "register_operand" "0,0,0,0,0")]))
1660 (set (match_operand:SI 4 "register_operand" "=*2,r,r,*3,r")
0b85d816
HPN
1661 (plus:SI (match_dup 2)
1662 (match_dup 3)))]
1663 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
0b85d816 1664{
1165f377 1665 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 1666 && (!CONST_INT_P (operands[3])
0b85d816
HPN
1667 || INTVAL (operands[3]) > 127
1668 || INTVAL (operands[3]) < -128
06cadf63
AS
1669 || satisfies_constraint_N (operands[3])
1670 || satisfies_constraint_J (operands[3])))
22c3c091 1671 return "#";
1165f377
HPN
1672 if (which_alternative == 4)
1673 return "%x5<m> [%4=%3%S2],%0";
22c3c091
HPN
1674 return "%x5<m> [%4=%2%S3],%0";
1675})
0b85d816
HPN
1676\f
1677;; Add operations, standard names.
1678
1679;; Note that for the 'P' constraint, the high part can be -1 or 0. We
1680;; output the insn through the 'A' output modifier as "adds.w" and "addq",
1681;; respectively.
45d5d09c
HPN
1682(define_expand "adddi3"
1683 [(set (match_operand:DI 0 "register_operand")
1684 (plus:DI (match_operand:DI 1 "register_operand")
1685 (match_operand:DI 2 "general_operand")))]
1686 ""
1687{
1688 if (MEM_P (operands[2]) && TARGET_V32)
1689 operands[2] = force_reg (DImode, operands[2]);
1690})
1691
1692(define_insn "*adddi3_non_v32"
0b85d816
HPN
1693 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
1694 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,r")
1695 (match_operand:DI 2 "general_operand" "J,N,P,g,!To")))]
45d5d09c 1696 "!TARGET_V32"
0b85d816
HPN
1697 "@
1698 addq %2,%M0\;ax\;addq 0,%H0
1699 subq %n2,%M0\;ax\;subq 0,%H0
1700 add%e2.%z2 %2,%M0\;ax\;%A2 %H2,%H0
1701 add.d %M2,%M0\;ax\;add.d %H2,%H0
1702 add.d %M2,%M1,%M0\;ax\;add.d %H2,%H1,%H0")
1703
45d5d09c
HPN
1704; It seems no use allowing a memory operand for this one, because we'd
1705; need a scratch register for incrementing the address.
1706(define_insn "*adddi3_v32"
1707 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1708 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0")
1709 (match_operand:DI 2 "nonmemory_operand" "J,N,P,r,n")))]
1710 "TARGET_V32"
1711 "@
1712 addq %2,%M0\;addc 0,%H0
1713 subq %n2,%M0\;ax\;subq 0,%H0
1714 add%e2.%z2 %2,%M0\;addc %H2,%H0
1715 add.d %M2,%M0\;addc %H2,%H0
1716 add.d %M2,%M0\;addc %H2,%H0")
1717
1718(define_expand "add<mode>3"
1719 [(set (match_operand:BWD 0 "register_operand")
1720 (plus:BWD
1721 (match_operand:BWD 1 "register_operand")
1722 (match_operand:BWD 2 "general_operand")))]
1723 ""
1724 "")
1725
1726(define_insn "*addsi3_non_v32"
c00fc5cf 1727 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r,r, r")
0b85d816 1728 (plus:SI
c00fc5cf
HPN
1729 (match_operand:SI 1 "register_operand" "%0,0, 0,0,0,0, 0,r, r")
1730 (match_operand:SI 2 "general_operand" "r,Q>,J,N,n,!S,g,!To,0")))]
0b85d816
HPN
1731
1732;; The last constraint is due to that after reload, the '%' is not
1733;; honored, and canonicalization doesn't care about keeping the same
1734;; register as in destination. This will happen after insn splitting.
1735;; gcc <= 2.7.2. FIXME: Check for gcc-2.9x
1736
45d5d09c 1737 "!TARGET_V32"
0b85d816
HPN
1738{
1739 switch (which_alternative)
1740 {
1741 case 0:
1742 case 1:
22c3c091 1743 return "add.d %2,%0";
0b85d816 1744 case 2:
22c3c091 1745 return "addq %2,%0";
0b85d816 1746 case 3:
22c3c091 1747 return "subq %n2,%0";
0b85d816
HPN
1748 case 4:
1749 /* 'Known value', but not in -63..63.
1750 Check if addu/subu may be used. */
1751 if (INTVAL (operands[2]) > 0)
1752 {
1753 if (INTVAL (operands[2]) < 256)
22c3c091 1754 return "addu.b %2,%0";
0b85d816 1755 if (INTVAL (operands[2]) < 65536)
22c3c091 1756 return "addu.w %2,%0";
0b85d816
HPN
1757 }
1758 else
1759 {
1760 if (INTVAL (operands[2]) >= -255)
22c3c091 1761 return "subu.b %n2,%0";
0b85d816 1762 if (INTVAL (operands[2]) >= -65535)
22c3c091 1763 return "subu.w %n2,%0";
0b85d816 1764 }
22c3c091 1765 return "add.d %2,%0";
0b85d816 1766 case 5:
c00fc5cf
HPN
1767 {
1768 rtx tem = operands[2];
1769 gcc_assert (GET_CODE (tem) == CONST);
1770 tem = XEXP (tem, 0);
1771 if (GET_CODE (tem) == PLUS
1772 && GET_CODE (XEXP (tem, 0)) == UNSPEC
45d5d09c
HPN
1773 /* We don't allow CRIS_UNSPEC_PCREL here; we can't have a
1774 pc-relative operand in an add insn. */
c00fc5cf 1775 && XINT (XEXP (tem, 0), 1) == CRIS_UNSPEC_GOTREL
991c42ac 1776 && CONST_INT_P (XEXP (tem, 1)))
c00fc5cf
HPN
1777 tem = XEXP (tem, 0);
1778 gcc_assert (GET_CODE (tem) == UNSPEC);
1779 switch (XINT (tem, 1))
1780 {
1781 case CRIS_UNSPEC_GOTREAD:
1782 case CRIS_UNSPEC_PLTGOTREAD:
1783 /* Using sign-extend mostly to be consistent with the
1784 indexed addressing mode. */
1785 if (flag_pic == 1)
1786 return "adds.w %2,%0";
45d5d09c
HPN
1787 return "add.d %2,%0";
1788
1789 case CRIS_UNSPEC_PLT_GOTREL:
c00fc5cf
HPN
1790 case CRIS_UNSPEC_GOTREL:
1791 return "add.d %2,%0";
1792 default:
1793 gcc_unreachable ();
1794 }
1795 }
1796 case 6:
45d5d09c 1797 return "add%u2 %2,%0";
0b85d816 1798 case 7:
c00fc5cf
HPN
1799 return "add.d %2,%1,%0";
1800 case 8:
22c3c091 1801 return "add.d %1,%0";
0b85d816 1802 default:
22c3c091 1803 return "BOGUS addsi %2+%1 to %0";
0b85d816 1804 }
22c3c091 1805}
c00fc5cf 1806 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,no,yes")])
45d5d09c
HPN
1807
1808; FIXME: Check what's best: having the three-operand ACR alternative
1809; before or after the corresponding-operand2 alternative. Check for
1810; *all* insns. FIXME: constant constraint letter for -128..127.
1811(define_insn "*addsi3_v32"
1812 [(set (match_operand:SI 0 "register_operand" "=r,!a,r,!a, r,r,!a,r,!a,r,r,r,!a")
1813 (plus:SI
1814 (match_operand:SI 1 "register_operand" "%0,r, 0, r, 0,0,r, 0,r, 0,0,0,r")
1815 (match_operand:SI 2 "general_operand" "r, r, Q>,Q>,J,N,NJ,L,L, P,n,g,g")))]
1816 "TARGET_V32"
1817 "@
1818 add.d %2,%0
1819 addi %2.b,%1,%0
1820 add.d %2,%0
1821 addo.d %2,%1,%0
1822 addq %2,%0
1823 subq %n2,%0
1824 addoq %2,%1,%0
1825 adds.w %2,%0
1826 addo %2,%1,%0
1827 addu.w %2,%0
1828 add.d %2,%0
1829 add%u2 %2,%0
1830 addo.%Z2 %2,%1,%0"
1831 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,yes,no,no,no,no,no,no")
d8ec9c14 1832 (set_attr "cc" "*,none,*,none,*,*,none,*,none,*,*,*,none")])
0b85d816 1833\f
45d5d09c 1834(define_insn "*addhi3_non_v32"
23369bef
HPN
1835 [(set (match_operand:HI 0 "register_operand" "=r,r, r,r,r,r")
1836 (plus:HI (match_operand:HI 1 "register_operand" "%0,0, 0,0,0,r")
1837 (match_operand:HI 2 "general_operand" "r,Q>,J,N,g,!To")))]
45d5d09c 1838 "!TARGET_V32"
0b85d816
HPN
1839 "@
1840 add.w %2,%0
1841 add.w %2,%0
1842 addq %2,%0
1843 subq %n2,%0
1844 add.w %2,%0
1845 add.w %2,%1,%0"
1846 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
1847 (set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
1848
45d5d09c
HPN
1849(define_insn "*addhi3_v32"
1850 [(set (match_operand:HI 0 "register_operand" "=r, !a,r,!a, r,r,!a,r,!a")
1851 (plus:HI
1852 (match_operand:HI 1 "register_operand" "%0,r, 0, r, 0,0,r, 0,r")
1853 (match_operand:HI 2 "general_operand" "r, r, Q>,Q>,J,N,NJ,g,g")))]
1854 "TARGET_V32"
1855 "@
1856 add.w %2,%0
1857 addi %2.b,%1,%0
1858 add.w %2,%0
1859 addo.w %2,%1,%0
1860 addq %2,%0
1861 subq %n2,%0
1862 addoq %2,%1,%0
1863 add.w %2,%0
1864 addo.w %2,%1,%0"
1865 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,yes,no,no")
1866 (set_attr "cc" "*,none,*,none,clobber,clobber,none,*,none")])
1867
1868(define_insn "*addqi3_non_v32"
23369bef
HPN
1869 [(set (match_operand:QI 0 "register_operand" "=r,r, r,r,r,r,r")
1870 (plus:QI (match_operand:QI 1 "register_operand" "%0,0, 0,0,0,0,r")
1871 (match_operand:QI 2 "general_operand" "r,Q>,J,N,O,g,!To")))]
45d5d09c 1872 "!TARGET_V32"
0b85d816
HPN
1873 "@
1874 add.b %2,%0
1875 add.b %2,%0
1876 addq %2,%0
1877 subq %n2,%0
1878 subQ -%b2,%0
1879 add.b %2,%0
1880 add.b %2,%1,%0"
1881 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no")
1882 (set_attr "cc" "normal,normal,clobber,clobber,clobber,normal,normal")])
45d5d09c
HPN
1883
1884(define_insn "*addqi3_v32"
1885 [(set (match_operand:QI 0 "register_operand" "=r,!a,r,!a, r,r,!a,r,r,!a")
1886 (plus:QI
1887 (match_operand:QI 1 "register_operand" "%0,r, 0, r, 0,0,r, 0,0,r")
1888 (match_operand:QI 2 "general_operand" "r,r, Q>,Q>,J,N,NJ,O,g,g")))]
1889 "TARGET_V32"
1890 "@
1891 add.b %2,%0
1892 addi %2.b,%1,%0
1893 add.b %2,%0
1894 addo.b %2,%1,%0
1895 addq %2,%0
1896 subq %n2,%0
1897 addoq %2,%1,%0
1898 subQ -%b2,%0
1899 add.b %2,%0
1900 addo.b %2,%1,%0"
1901 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,yes,yes,no,no")
1902 (set_attr "cc" "*,none,*,none,clobber,clobber,none,clobber,*,none")])
0b85d816
HPN
1903\f
1904;; Subtract.
1905;;
1906;; Note that because of insn canonicalization these will *seldom* but
1907;; rarely be used with a known constant as an operand.
1908
1909;; Note that for the 'P' constraint, the high part can be -1 or 0. We
1910;; output the insn through the 'D' output modifier as "subs.w" and "subq",
1911;; respectively.
45d5d09c
HPN
1912(define_expand "subdi3"
1913 [(set (match_operand:DI 0 "register_operand")
1914 (minus:DI (match_operand:DI 1 "register_operand")
1915 (match_operand:DI 2 "general_operand")))]
1916 ""
1917{
1918 if (TARGET_V32 && MEM_P (operands[2]))
1919 operands[2] = force_reg (DImode, operands[2]);
1920})
1921
1922(define_insn "*subdi3_non_v32"
0b85d816
HPN
1923 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
1924 (minus:DI (match_operand:DI 1 "register_operand" "0,0,0,0,r")
1925 (match_operand:DI 2 "general_operand" "J,N,P,g,!To")))]
45d5d09c 1926 "!TARGET_V32"
0b85d816
HPN
1927 "@
1928 subq %2,%M0\;ax\;subq 0,%H0
1929 addq %n2,%M0\;ax\;addq 0,%H0
1930 sub%e2.%z2 %2,%M0\;ax\;%D2 %H2,%H0
1931 sub.d %M2,%M0\;ax\;sub.d %H2,%H0
1932 sub.d %M2,%M1,%M0\;ax\;sub.d %H2,%H1,%H0")
1933
45d5d09c
HPN
1934(define_insn "*subdi3_v32"
1935 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r")
1936 (minus:DI (match_operand:DI 1 "register_operand" "0,0,0,0")
1937 (match_operand:DI 2 "nonmemory_operand" "J,N,P,r")))]
1938 "TARGET_V32"
1939 "@
1940 subq %2,%M0\;ax\;subq 0,%H0
1941 addq %n2,%M0\;ax\;addq 0,%H0
1942 sub%e2.%z2 %2,%M0\;ax\;%D2 %H2,%H0
1943 sub.d %M2,%M0\;ax\;sub.d %H2,%H0")
1944
1945(define_expand "sub<mode>3"
1946 [(set (match_operand:BWD 0 "register_operand")
1947 (minus:BWD
1948 (match_operand:BWD 1 "register_operand")
1949 (match_operand:BWD 2 "general_operand")))]
1950 ""
1951 "")
1952
1953(define_insn "*subsi3_non_v32"
23369bef 1954 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r,r,r")
0b85d816 1955 (minus:SI
23369bef
HPN
1956 (match_operand:SI 1 "register_operand" "0,0, 0,0,0,0,0,r")
1957 (match_operand:SI 2 "general_operand" "r,Q>,J,N,P,n,g,!To")))]
45d5d09c 1958 "!TARGET_V32"
0b85d816
HPN
1959
1960;; This does not do the optimal: "addu.w 65535,r0" when %2 is negative.
1961;; But then again, %2 should not be negative.
1962
1963 "@
1964 sub.d %2,%0
1965 sub.d %2,%0
1966 subq %2,%0
1967 addq %n2,%0
1968 sub%e2.%z2 %2,%0
1969 sub.d %2,%0
1970 sub.d %2,%0
1971 sub.d %2,%1,%0"
1972 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,no")])
45d5d09c
HPN
1973
1974(define_insn "*subsi3_v32"
1975 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
1976 (minus:SI
1977 (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0")
1978 (match_operand:SI 2 "general_operand" "r,Q>,J,N,P,n,g")))]
1979 "TARGET_V32"
1980 "@
1981 sub.d %2,%0
1982 sub.d %2,%0
1983 subq %2,%0
1984 addq %n2,%0
1985 sub%e2.%z2 %2,%0
1986 sub.d %2,%0
1987 sub.d %2,%0"
1988 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no")])
0b85d816 1989\f
45d5d09c 1990(define_insn "*sub<mode>3_nonv32"
22c3c091
HPN
1991 [(set (match_operand:BW 0 "register_operand" "=r,r, r,r,r,r")
1992 (minus:BW (match_operand:BW 1 "register_operand" "0,0, 0,0,0,r")
1993 (match_operand:BW 2 "general_operand" "r,Q>,J,N,g,!To")))]
45d5d09c 1994 "!TARGET_V32"
0b85d816 1995 "@
22c3c091
HPN
1996 sub<m> %2,%0
1997 sub<m> %2,%0
0b85d816
HPN
1998 subq %2,%0
1999 addq %n2,%0
22c3c091
HPN
2000 sub<m> %2,%0
2001 sub<m> %2,%1,%0"
0b85d816
HPN
2002 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
2003 (set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
45d5d09c
HPN
2004
2005(define_insn "*sub<mode>3_v32"
2006 [(set (match_operand:BW 0 "register_operand" "=r,r,r,r,r")
2007 (minus:BW (match_operand:BW 1 "register_operand" "0,0,0,0,0")
2008 (match_operand:BW 2 "general_operand" "r,Q>,J,N,g")))]
2009 "TARGET_V32"
2010 "@
2011 sub<m> %2,%0
2012 sub<m> %2,%0
2013 subq %2,%0
2014 addq %n2,%0
2015 sub<m> %2,%0"
2016 [(set_attr "slottable" "yes,yes,yes,yes,no")
2017 (set_attr "cc" "normal,normal,clobber,clobber,normal")])
0b85d816
HPN
2018\f
2019;; CRIS has some add/sub-with-sign/zero-extend instructions.
2020;; Although these perform sign/zero-extension to SImode, they are
2021;; equally applicable for the HImode case.
2022;; FIXME: Check; GCC should handle the widening.
2023;; Note that these must be located after the normal add/sub patterns,
2024;; so not to get constants into any less specific operands.
2025;;
2026;; Extend with add/sub and side-effect.
2027;;
2028;; ADDS/SUBS/ADDU/SUBU and BOUND, which needs a check for zero_extend
2029;;
2030;; adds/subs/addu/subu bound [rx=ry+rz.S]
0b85d816 2031
22c3c091
HPN
2032;; QImode to HImode
2033;; FIXME: GCC should widen.
0b85d816 2034
22c3c091
HPN
2035(define_insn "*extopqihi_side_biap"
2036 [(set (match_operand:HI 0 "register_operand" "=r,r")
2037 (match_operator:HI
2038 6 "cris_additive_operand_extend_operator"
2039 [(match_operand:HI 1 "register_operand" "0,0")
2040 (match_operator:HI
0b85d816
HPN
2041 7 "cris_extend_operator"
2042 [(mem:QI (plus:SI
2043 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2044 (match_operand:SI 3 "const_int_operand" "n,n"))
2045 (match_operand:SI 4 "register_operand" "r,r")))])]))
2046 (set (match_operand:SI 5 "register_operand" "=*4,r")
2047 (plus:SI (mult:SI (match_dup 2)
2048 (match_dup 3))
2049 (match_dup 4)))]
22c3c091 2050 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
0b85d816
HPN
2051 "@
2052 #
2053 %x6%e7.%m7 [%5=%4+%2%T3],%0")
2054
22c3c091 2055(define_insn "*extop<mode>si_side_biap"
0b85d816
HPN
2056 [(set (match_operand:SI 0 "register_operand" "=r,r")
2057 (match_operator:SI
2058 6 "cris_operand_extend_operator"
2059 [(match_operand:SI 1 "register_operand" "0,0")
2060 (match_operator:SI
2061 7 "cris_extend_operator"
22c3c091 2062 [(mem:BW (plus:SI
0b85d816
HPN
2063 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2064 (match_operand:SI 3 "const_int_operand" "n,n"))
2065 (match_operand:SI 4 "register_operand" "r,r")))])]))
2066 (set (match_operand:SI 5 "register_operand" "=*4,r")
2067 (plus:SI (mult:SI (match_dup 2)
2068 (match_dup 3))
2069 (match_dup 4)))]
d2f55c5c 2070 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[7]) == ZERO_EXTEND)
0b85d816
HPN
2071 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
2072 "@
2073 #
22c3c091 2074 %x6%e7<m> [%5=%4+%2%T3],%0")
0b85d816
HPN
2075\f
2076
2077;; [rx=ry+i]
0b85d816
HPN
2078
2079;; QImode to HImode
2080
2081(define_insn "*extopqihi_side"
1165f377 2082 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
0b85d816 2083 (match_operator:HI
d2f55c5c 2084 5 "cris_additive_operand_extend_operator"
1165f377 2085 [(match_operand:HI 1 "register_operand" "0,0,0,0,0")
0b85d816
HPN
2086 (match_operator:HI
2087 6 "cris_extend_operator"
2088 [(mem:QI
1165f377
HPN
2089 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r,R,R")
2090 (match_operand:SI 3 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")
0b85d816 2091 ))])]))
1165f377 2092 (set (match_operand:SI 4 "register_operand" "=*2,r,r,*3,r")
0b85d816
HPN
2093 (plus:SI (match_dup 2)
2094 (match_dup 3)))]
d2f55c5c 2095 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
0b85d816 2096{
1165f377 2097 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 2098 && (!CONST_INT_P (operands[3])
0b85d816
HPN
2099 || INTVAL (operands[3]) > 127
2100 || INTVAL (operands[3]) < -128
06cadf63
AS
2101 || satisfies_constraint_N (operands[3])
2102 || satisfies_constraint_J (operands[3])))
22c3c091 2103 return "#";
1165f377 2104 if (which_alternative == 4)
9c514326
HPN
2105 return "%x5%E6.%m6 [%4=%3%S2],%0";
2106 return "%x5%E6.%m6 [%4=%2%S3],%0";
22c3c091 2107})
0b85d816 2108
22c3c091 2109(define_insn "*extop<mode>si_side"
1165f377 2110 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
0b85d816
HPN
2111 (match_operator:SI
2112 5 "cris_operand_extend_operator"
1165f377 2113 [(match_operand:SI 1 "register_operand" "0,0,0,0,0")
0b85d816
HPN
2114 (match_operator:SI
2115 6 "cris_extend_operator"
22c3c091 2116 [(mem:BW
1165f377
HPN
2117 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r,R,R")
2118 (match_operand:SI 3 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")
0b85d816 2119 ))])]))
1165f377 2120 (set (match_operand:SI 4 "register_operand" "=*2,r,r,*3,r")
0b85d816
HPN
2121 (plus:SI (match_dup 2)
2122 (match_dup 3)))]
2123 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
2124 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
0b85d816 2125{
1165f377 2126 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 2127 && (!CONST_INT_P (operands[3])
0b85d816
HPN
2128 || INTVAL (operands[3]) > 127
2129 || INTVAL (operands[3]) < -128
06cadf63
AS
2130 || satisfies_constraint_N (operands[3])
2131 || satisfies_constraint_J (operands[3])))
22c3c091 2132 return "#";
1165f377 2133 if (which_alternative == 4)
9c514326
HPN
2134 return "%x5%E6<m> [%4=%3%S2],%0";
2135 return "%x5%E6<m> [%4=%2%S3],%0";
22c3c091 2136})
0b85d816
HPN
2137\f
2138
2139;; As with op.S we may have to add special pattern to match commuted
45d5d09c 2140;; operands to adds/addu and bound
0b85d816
HPN
2141;;
2142;; adds/addu/bound [rx=ry+rz.S]
2143
2144;; QImode to HImode
2145;; FIXME: GCC should widen.
0b85d816
HPN
2146
2147(define_insn "*extopqihi_swap_side_biap"
2148 [(set (match_operand:HI 0 "register_operand" "=r,r")
d2f55c5c
HPN
2149 (plus:HI
2150 (match_operator:HI
2151 6 "cris_extend_operator"
2152 [(mem:QI (plus:SI
2153 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2154 (match_operand:SI 3 "const_int_operand" "n,n"))
2155 (match_operand:SI 4 "register_operand" "r,r")))])
2156 (match_operand:HI 1 "register_operand" "0,0")))
0b85d816
HPN
2157 (set (match_operand:SI 5 "register_operand" "=*4,r")
2158 (plus:SI (mult:SI (match_dup 2)
2159 (match_dup 3))
2160 (match_dup 4)))]
d2f55c5c 2161 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
0b85d816
HPN
2162 "@
2163 #
d2f55c5c 2164 add%e6.b [%5=%4+%2%T3],%0")
0b85d816 2165
22c3c091 2166(define_insn "*extop<mode>si_swap_side_biap"
0b85d816
HPN
2167 [(set (match_operand:SI 0 "register_operand" "=r,r")
2168 (match_operator:SI
2169 7 "cris_plus_or_bound_operator"
2170 [(match_operator:SI
2171 6 "cris_extend_operator"
22c3c091 2172 [(mem:BW (plus:SI
0b85d816
HPN
2173 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2174 (match_operand:SI 3 "const_int_operand" "n,n"))
2175 (match_operand:SI 4 "register_operand" "r,r")))])
2176 (match_operand:SI 1 "register_operand" "0,0")]))
2177 (set (match_operand:SI 5 "register_operand" "=*4,r")
2178 (plus:SI (mult:SI (match_dup 2)
2179 (match_dup 3))
2180 (match_dup 4)))]
d2f55c5c 2181 "(GET_CODE (operands[7]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
0b85d816
HPN
2182 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
2183 "@
2184 #
9c514326 2185 %x7%E6<m> [%5=%4+%2%T3],%0")
0b85d816
HPN
2186\f
2187;; [rx=ry+i]
0b85d816
HPN
2188;; FIXME: GCC should widen.
2189
2190;; QImode to HImode
2191
2192(define_insn "*extopqihi_swap_side"
1165f377 2193 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
d2f55c5c
HPN
2194 (plus:HI
2195 (match_operator:HI
2196 5 "cris_extend_operator"
2197 [(mem:QI (plus:SI
1165f377
HPN
2198 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r,R,R")
2199 (match_operand:SI 3 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))])
2200 (match_operand:HI 1 "register_operand" "0,0,0,0,0")))
2201 (set (match_operand:SI 4 "register_operand" "=*2,r,r,*3,r")
0b85d816
HPN
2202 (plus:SI (match_dup 2)
2203 (match_dup 3)))]
d2f55c5c 2204 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
0b85d816 2205{
1165f377 2206 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 2207 && (!CONST_INT_P (operands[3])
0b85d816
HPN
2208 || INTVAL (operands[3]) > 127
2209 || INTVAL (operands[3]) < -128
06cadf63
AS
2210 || satisfies_constraint_N (operands[3])
2211 || satisfies_constraint_J (operands[3])))
22c3c091 2212 return "#";
1165f377
HPN
2213 if (which_alternative == 4)
2214 return "add%e5.b [%4=%3%S2],%0";
22c3c091
HPN
2215 return "add%e5.b [%4=%2%S3],%0";
2216})
0b85d816 2217
22c3c091 2218(define_insn "*extop<mode>si_swap_side"
1165f377 2219 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
0b85d816
HPN
2220 (match_operator:SI
2221 6 "cris_plus_or_bound_operator"
2222 [(match_operator:SI
2223 5 "cris_extend_operator"
22c3c091 2224 [(mem:BW (plus:SI
1165f377
HPN
2225 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r,R,R")
2226 (match_operand:SI 3 "cris_bdap_operand" "r>Rn,r,>Rn,r,r")))])
2227 (match_operand:SI 1 "register_operand" "0,0,0,0,0")]))
2228 (set (match_operand:SI 4 "register_operand" "=*2,r,r,*3,r")
0b85d816
HPN
2229 (plus:SI (match_dup 2)
2230 (match_dup 3)))]
2231 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[5]) == ZERO_EXTEND)
2232 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
0b85d816 2233{
1165f377 2234 if ((which_alternative == 0 || which_alternative == 3)
991c42ac 2235 && (!CONST_INT_P (operands[3])
0b85d816
HPN
2236 || INTVAL (operands[3]) > 127
2237 || INTVAL (operands[3]) < -128
06cadf63
AS
2238 || satisfies_constraint_N (operands[3])
2239 || satisfies_constraint_J (operands[3])))
22c3c091 2240 return "#";
1165f377 2241 if (which_alternative == 4)
9c514326
HPN
2242 return \"%x6%E5.%m5 [%4=%3%S2],%0\";
2243 return "%x6%E5<m> [%4=%2%S3],%0";
22c3c091 2244})
0b85d816
HPN
2245\f
2246;; Extend versions (zero/sign) of normal add/sub (no side-effects).
0b85d816
HPN
2247
2248;; QImode to HImode
2249;; FIXME: GCC should widen.
2250
45d5d09c 2251(define_insn "*extopqihi_non_v32"
0b85d816
HPN
2252 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2253 (match_operator:HI
d2f55c5c 2254 3 "cris_additive_operand_extend_operator"
0b85d816
HPN
2255 [(match_operand:HI 1 "register_operand" "0,0,0,r")
2256 (match_operator:HI
2257 4 "cris_extend_operator"
2258 [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])]))]
45d5d09c 2259 "!TARGET_V32 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
0b85d816
HPN
2260 && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
2261 "@
9c514326
HPN
2262 %x3%E4.%m4 %2,%0
2263 %x3%E4.%m4 %2,%0
2264 %x3%E4.%m4 %2,%0
2265 %x3%E4.%m4 %2,%1,%0"
0b85d816
HPN
2266 [(set_attr "slottable" "yes,yes,no,no")
2267 (set_attr "cc" "clobber")])
2268
45d5d09c
HPN
2269(define_insn "*extopqihi_v32"
2270 [(set (match_operand:HI 0 "register_operand" "=r,r")
2271 (match_operator:HI
2272 3 "cris_additive_operand_extend_operator"
2273 [(match_operand:HI 1 "register_operand" "0,0")
2274 (match_operator:HI
2275 4 "cris_extend_operator"
2276 [(match_operand:QI 2 "nonimmediate_operand" "r,m")])]))]
2277 "TARGET_V32"
2278 "%x3%e4.%m4 %2,%0"
2279 [(set_attr "slottable" "yes")
2280 (set_attr "cc" "clobber")])
2281
0b85d816
HPN
2282;; QImode to SImode
2283
45d5d09c 2284(define_insn "*extop<mode>si_non_v32"
0b85d816
HPN
2285 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2286 (match_operator:SI
2287 3 "cris_operand_extend_operator"
2288 [(match_operand:SI 1 "register_operand" "0,0,0,r")
2289 (match_operator:SI
2290 4 "cris_extend_operator"
22c3c091 2291 [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])]))]
45d5d09c
HPN
2292 "!TARGET_V32
2293 && (GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
0b85d816
HPN
2294 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
2295 && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
2296 "@
9c514326
HPN
2297 %x3%E4<m> %2,%0
2298 %x3%E4<m> %2,%0
2299 %x3%E4<m> %2,%0
2300 %x3%E4<m> %2,%1,%0"
0b85d816 2301 [(set_attr "slottable" "yes,yes,no,no")])
0b85d816 2302
45d5d09c
HPN
2303(define_insn "*extop<mode>si_v32"
2304 [(set (match_operand:SI 0 "register_operand" "=r,r")
2305 (match_operator:SI
2306 3 "cris_additive_operand_extend_operator"
2307 [(match_operand:SI 1 "register_operand" "0,0")
2308 (match_operator:SI
2309 4 "cris_extend_operator"
2310 [(match_operand:BW 2 "nonimmediate_operand" "r,m")])]))]
2311 "TARGET_V32"
2312 "%x3%e4.%m4 %2,%0"
2313 [(set_attr "slottable" "yes")])
2314\f
0b85d816 2315;; As with the side-effect patterns, may have to have swapped operands for add.
45d5d09c 2316;; For commutative operands, these are the canonical forms.
0b85d816
HPN
2317
2318;; QImode to HImode
2319
45d5d09c 2320(define_insn "*addxqihi_swap_non_v32"
0b85d816 2321 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
d2f55c5c
HPN
2322 (plus:HI
2323 (match_operator:HI
2324 3 "cris_extend_operator"
2325 [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])
2326 (match_operand:HI 1 "register_operand" "0,0,0,r")))]
45d5d09c 2327 "!TARGET_V32 && operands[1] != frame_pointer_rtx"
0b85d816 2328 "@
d2f55c5c
HPN
2329 add%e3.b %2,%0
2330 add%e3.b %2,%0
2331 add%e3.b %2,%0
2332 add%e3.b %2,%1,%0"
0b85d816
HPN
2333 [(set_attr "slottable" "yes,yes,no,no")
2334 (set_attr "cc" "clobber")])
2335
45d5d09c
HPN
2336;; A case for v32, to catch the "addo" insn in addition to "adds". We
2337;; only care to match the canonical form; there should be no other.
2338
2339(define_insn "*addsbw_v32"
2340 [(set (match_operand:HI 0 "register_operand" "=r,r,!a")
2341 (plus:HI
2342 (sign_extend:HI
2343 (match_operand:QI 2 "nonimmediate_operand" "r,m,m"))
2344 (match_operand:HI 1 "register_operand" "0,0,r")))]
2345 "TARGET_V32"
2346 "@
2347 adds.b %2,%0
2348 adds.b %2,%0
2349 addo.b %2,%1,%0"
2350 [(set_attr "slottable" "yes")
2351 (set_attr "cc" "clobber,clobber,none")])
2352
2353(define_insn "*addubw_v32"
2354 [(set (match_operand:HI 0 "register_operand" "=r,r")
2355 (plus:HI
2356 (zero_extend:HI
2357 (match_operand:QI 2 "nonimmediate_operand" "r,m"))
2358 (match_operand:HI 1 "register_operand" "0,0")))]
2359 "TARGET_V32"
2360 "addu.b %2,%0"
2361 [(set_attr "slottable" "yes")
2362 (set_attr "cc" "clobber")])
2363
2364(define_insn "*extop<mode>si_swap_non_v32"
0b85d816
HPN
2365 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2366 (match_operator:SI
2367 4 "cris_plus_or_bound_operator"
2368 [(match_operator:SI
2369 3 "cris_extend_operator"
22c3c091 2370 [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])
0b85d816 2371 (match_operand:SI 1 "register_operand" "0,0,0,r")]))]
45d5d09c
HPN
2372 "!TARGET_V32
2373 && (GET_CODE (operands[4]) != UMIN || GET_CODE (operands[3]) == ZERO_EXTEND)
0b85d816
HPN
2374 && operands[1] != frame_pointer_rtx"
2375 "@
9c514326
HPN
2376 %x4%E3<m> %2,%0
2377 %x4%E3<m> %2,%0
2378 %x4%E3<m> %2,%0
2379 %x4%E3<m> %2,%1,%0"
0b85d816 2380 [(set_attr "slottable" "yes,yes,no,no")])
45d5d09c
HPN
2381
2382(define_insn "*adds<mode>_v32"
2383 [(set (match_operand:SI 0 "register_operand" "=r,r,!a")
2384 (plus:SI
2385 (sign_extend:SI
2386 (match_operand:BW 2 "nonimmediate_operand" "r,m,m"))
2387 (match_operand:SI 1 "register_operand" "0,0,r")))]
2388 "TARGET_V32"
2389 "@
2390 adds<m> %2,%0
2391 adds<m> %2,%0
2392 addo<m> %2,%1,%0"
2393 [(set_attr "slottable" "yes")
2394 (set_attr "cc" "*,*,none")])
2395
2396(define_insn "*addu<mode>_v32"
2397 [(set (match_operand:SI 0 "register_operand" "=r,r")
2398 (plus:SI
2399 (zero_extend:SI
2400 (match_operand:BW 2 "nonimmediate_operand" "r,m"))
2401 (match_operand:SI 1 "register_operand" "0,0")))]
2402 "TARGET_V32 && operands[1] != frame_pointer_rtx"
2403 "addu<m> %2,%0"
2404 [(set_attr "slottable" "yes")])
2405
2406(define_insn "*bound<mode>_v32"
2407 [(set (match_operand:SI 0 "register_operand" "=r")
2408 (umin:SI
2409 (zero_extend:SI
2410 (match_operand:BW 2 "register_operand" "r"))
2411 (match_operand:SI 1 "register_operand" "0")))]
2412 "TARGET_V32 && operands[1] != frame_pointer_rtx"
2413 "bound<m> %2,%0"
2414 [(set_attr "slottable" "yes")])
0b85d816
HPN
2415\f
2416;; This is the special case when we use what corresponds to the
2417;; instruction above in "casesi". Do *not* change it to use the generic
2418;; pattern and "REG 15" as pc; I did that and it led to madness and
2419;; maintenance problems: Instead of (as imagined) recognizing and removing
2420;; or replacing this pattern with something simpler, other variant
2421;; patterns were recognized or combined, including some prefix variants
2422;; where the value in pc is not that of the next instruction (which means
2423;; this instruction actually *is* special and *should* be marked as such).
2424;; When switching from the "generic pattern match" approach to this simpler
2425;; approach, there were insignificant differences in gcc, ipps and
2426;; product code, somehow due to scratching reload behind the ear or
2427;; something. Testcase "gcc" looked .01% slower and 4 bytes bigger;
2428;; product code became .001% smaller but "looked better". The testcase
2429;; "ipps" was just different at register allocation).
2430;;
2431;; Assumptions in the jump optimizer forces us to use IF_THEN_ELSE in this
2432;; pattern with the default-label as the else, with the "if" being
2433;; index-is-less-than the max number of cases plus one. The default-label
2434;; is attached to the end of the case-table at time of output.
2435
2436(define_insn "*casesi_adds_w"
2437 [(set (pc)
2438 (if_then_else
2439 (ltu (match_operand:SI 0 "register_operand" "r")
2440 (match_operand:SI 1 "const_int_operand" "n"))
2441 (plus:SI (sign_extend:SI
2442 (mem:HI
2443 (plus:SI (mult:SI (match_dup 0) (const_int 2))
2444 (pc))))
2445 (pc))
2446 (label_ref (match_operand 2 "" ""))))
2447 (use (label_ref (match_operand 3 "" "")))]
45d5d09c 2448 "!TARGET_V32 && operands[0] != frame_pointer_rtx"
0b85d816
HPN
2449 "adds.w [$pc+%0.w],$pc"
2450 [(set_attr "cc" "clobber")])
45d5d09c
HPN
2451
2452;; For V32, we just have a jump, but we need to mark the table as used,
2453;; and the jump insn must have the if_then_else form expected by core
2454;; GCC. Since we don't want to prolong the lifetime of the original
2455;; index value, we compare against "unspec 0". It's a pity we have to
2456;; jump through to get the default label in place and to keep the jump
2457;; table around. FIXME: Look into it some time.
2458
2459(define_insn "*casesi_jump_v32"
2460 [(set (pc)
2461 (if_then_else
2462 (ltu (unspec [(const_int 0)] CRIS_UNSPEC_CASESI)
2463 (match_operand:SI 0 "const_int_operand" "n"))
2464 (match_operand:SI 1 "register_operand" "r")
2465 (label_ref (match_operand 2 "" ""))))
2466 (use (label_ref (match_operand 3 "" "")))]
2467 "TARGET_V32"
2468 "jump %1%#"
2469 [(set_attr "cc" "clobber")
2470 (set_attr "slottable" "has_slot")])
0b85d816
HPN
2471\f
2472;; Multiply instructions.
2473
2474;; Sometimes powers of 2 (which are normally canonicalized to a
2475;; left-shift) appear here, as a result of address reloading.
2476;; As a special, for values 3 and 5, we can match with an addi, so add those.
2477;;
2478;; FIXME: This may be unnecessary now.
2479;; Explicitly named for convenience of having a gen_... function.
2480
2481(define_insn "addi_mul"
2482 [(set (match_operand:SI 0 "register_operand" "=r")
2483 (mult:SI
2484 (match_operand:SI 1 "register_operand" "%0")
2485 (match_operand:SI 2 "const_int_operand" "n")))]
2486 "operands[0] != frame_pointer_rtx
2487 && operands[1] != frame_pointer_rtx
991c42ac 2488 && CONST_INT_P (operands[2])
0b85d816
HPN
2489 && (INTVAL (operands[2]) == 2
2490 || INTVAL (operands[2]) == 4 || INTVAL (operands[2]) == 3
2491 || INTVAL (operands[2]) == 5)"
0b85d816
HPN
2492{
2493 if (INTVAL (operands[2]) == 2)
22c3c091 2494 return "lslq 1,%0";
0b85d816 2495 else if (INTVAL (operands[2]) == 4)
22c3c091 2496 return "lslq 2,%0";
0b85d816 2497 else if (INTVAL (operands[2]) == 3)
22c3c091 2498 return "addi %0.w,%0";
0b85d816 2499 else if (INTVAL (operands[2]) == 5)
22c3c091
HPN
2500 return "addi %0.d,%0";
2501 return "BAD: adr_mulsi: %0=%1*%2";
2502}
0b85d816
HPN
2503[(set_attr "slottable" "yes")
2504 ;; No flags are changed if this insn is "addi", but it does not seem
2505 ;; worth the trouble to distinguish that to the lslq cases.
2506 (set_attr "cc" "clobber")])
2507
2508;; The addi insn as it is normally used.
2509
dd5a833e 2510;; Make the ACR alternative taste bad enough to not choose it as a
45d5d09c
HPN
2511;; preference to avoid spilling problems (unwind-dw2-fde.c at build).
2512;; FIXME: Revisit for new register allocator.
2513
0b85d816 2514(define_insn "*addi"
45d5d09c 2515 [(set (match_operand:SI 0 "register_operand" "=r,!a")
0b85d816 2516 (plus:SI
45d5d09c
HPN
2517 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2518 (match_operand:SI 3 "const_int_operand" "n,n"))
2519 (match_operand:SI 1 "register_operand" "0,r")))]
0b85d816
HPN
2520 "operands[0] != frame_pointer_rtx
2521 && operands[1] != frame_pointer_rtx
991c42ac 2522 && CONST_INT_P (operands[3])
0b85d816
HPN
2523 && (INTVAL (operands[3]) == 1
2524 || INTVAL (operands[3]) == 2 || INTVAL (operands[3]) == 4)"
45d5d09c
HPN
2525 "@
2526 addi %2%T3,%0
2527 addi %2%T3,%1,%0"
0b85d816
HPN
2528 [(set_attr "slottable" "yes")
2529 (set_attr "cc" "none")])
2530
2531;; The mstep instruction. Probably not useful by itself; it's to
2532;; non-linear wrt. the other insns. We used to expand to it, so at least
2533;; it's correct.
2534
2535(define_insn "mstep_shift"
2536 [(set (match_operand:SI 0 "register_operand" "=r")
2537 (if_then_else:SI
2538 (lt:SI (cc0) (const_int 0))
2539 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2540 (const_int 1))
2541 (match_operand:SI 2 "register_operand" "r"))
2542 (ashift:SI (match_operand:SI 3 "register_operand" "0")
2543 (const_int 1))))]
45d5d09c 2544 "!TARGET_V32"
0b85d816
HPN
2545 "mstep %2,%0"
2546 [(set_attr "slottable" "yes")])
2547
2548;; When illegitimate addresses are legitimized, sometimes gcc forgets
2549;; to canonicalize the multiplications.
2550;;
2551;; FIXME: Check gcc > 2.7.2, remove and possibly fix in gcc.
2552
2553(define_insn "mstep_mul"
2554 [(set (match_operand:SI 0 "register_operand" "=r")
2555 (if_then_else:SI
2556 (lt:SI (cc0) (const_int 0))
2557 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
2558 (const_int 2))
2559 (match_operand:SI 2 "register_operand" "r"))
2560 (mult:SI (match_operand:SI 3 "register_operand" "0")
2561 (const_int 2))))]
45d5d09c
HPN
2562 "!TARGET_V32
2563 && operands[0] != frame_pointer_rtx
0b85d816
HPN
2564 && operands[1] != frame_pointer_rtx
2565 && operands[2] != frame_pointer_rtx
2566 && operands[3] != frame_pointer_rtx"
2567 "mstep %2,%0"
2568 [(set_attr "slottable" "yes")])
2569
22c3c091
HPN
2570(define_insn "<u>mul<s><mode>3"
2571 [(set (match_operand:WD 0 "register_operand" "=r")
2572 (mult:WD
2573 (szext:WD (match_operand:<S> 1 "register_operand" "%0"))
2574 (szext:WD (match_operand:<S> 2 "register_operand" "r"))))
f60c7155 2575 (clobber (match_scratch:SI 3 "=h"))]
0b85d816 2576 "TARGET_HAS_MUL_INSNS"
22c3c091 2577 "%!mul<su><mm> %2,%0"
86da66b5 2578 [(set (attr "slottable")
bf0b8cbe 2579 (if_then_else (match_test "TARGET_MUL_BUG")
86da66b5
HPN
2580 (const_string "no")
2581 (const_string "yes")))
22c3c091
HPN
2582 ;; For umuls.[bwd] it's just N unusable here, but let's be safe.
2583 ;; For muls.b, this really extends to SImode, so cc should be
2584 ;; considered clobbered.
2585 ;; For muls.w, it's just N unusable here, but let's be safe.
0b85d816
HPN
2586 (set_attr "cc" "clobber")])
2587
2588;; Note that gcc does not make use of such a thing as umulqisi3. It gets
2589;; confused and will erroneously use it instead of umulhisi3, failing (at
2590;; least) gcc.c-torture/execute/arith-rand.c at all optimization levels.
2591;; Inspection of optab code shows that there must be only one widening
2592;; multiplication per mode widened to.
2593
2594(define_insn "mulsi3"
2595 [(set (match_operand:SI 0 "register_operand" "=r")
ef6201a6 2596 (mult:SI (match_operand:SI 1 "register_operand" "%0")
f60c7155
HPN
2597 (match_operand:SI 2 "register_operand" "r")))
2598 (clobber (match_scratch:SI 3 "=h"))]
0b85d816 2599 "TARGET_HAS_MUL_INSNS"
86da66b5
HPN
2600 "%!muls.d %2,%0"
2601 [(set (attr "slottable")
bf0b8cbe 2602 (if_then_else (match_test "TARGET_MUL_BUG")
86da66b5
HPN
2603 (const_string "no")
2604 (const_string "yes")))
0b85d816
HPN
2605 ;; Just N unusable here, but let's be safe.
2606 (set_attr "cc" "clobber")])
2607\f
2608;; A few multiply variations.
2609
0b85d816
HPN
2610;; When needed, we can get the high 32 bits from the overflow
2611;; register. We don't care to split and optimize these.
2612;;
2613;; Note that cc0 is still valid after the move-from-overflow-register
2614;; insn; no special precaution need to be taken in cris_notice_update_cc.
2615
22c3c091 2616(define_insn "<u>mulsidi3"
0b85d816
HPN
2617 [(set (match_operand:DI 0 "register_operand" "=r")
2618 (mult:DI
22c3c091
HPN
2619 (szext:DI (match_operand:SI 1 "register_operand" "%0"))
2620 (szext:DI (match_operand:SI 2 "register_operand" "r"))))
f60c7155 2621 (clobber (match_scratch:SI 3 "=h"))]
0b85d816 2622 "TARGET_HAS_MUL_INSNS"
22c3c091 2623 "%!mul<su>.d %2,%M0\;move $mof,%H0")
0b85d816 2624
f60c7155
HPN
2625;; These two patterns may be expressible by other means, perhaps by making
2626;; [u]?mulsidi3 a define_expand.
2627
2628;; Due to register allocation braindamage, the clobber 1,2 alternatives
2629;; cause a move into the clobbered register *before* the insn, then
2630;; after the insn, mof is moved too, rather than the clobber assigned
2631;; the last mof target. This became apparent when making MOF and SRP
2632;; visible registers, with the necessary tweak to smulsi3_highpart.
2633;; Because these patterns are used in division by constants, that damage
2634;; is visible (ipps regression tests). Therefore the last two
2635;; alternatives, "helping" reload to avoid an unnecessary move, but
2636;; punished by force of one "?". Check code from "int d (int a) {return
2637;; a / 1000;}" and unsigned. FIXME: Comment above was for 3.2, revisit.
0b85d816 2638
22c3c091 2639(define_insn "<su>mulsi3_highpart"
45d5d09c 2640 [(set (match_operand:SI 0 "register_operand" "=h,h,?r,?r")
0b85d816
HPN
2641 (truncate:SI
2642 (lshiftrt:DI
2643 (mult:DI
22c3c091
HPN
2644 (szext:DI (match_operand:SI 1 "register_operand" "r,r,0,r"))
2645 (szext:DI (match_operand:SI 2 "register_operand" "r,r,r,0")))
0b85d816 2646 (const_int 32))))
f60c7155 2647 (clobber (match_scratch:SI 3 "=1,2,h,h"))]
0b85d816 2648 "TARGET_HAS_MUL_INSNS"
f60c7155 2649 "@
22c3c091
HPN
2650 %!mul<su>.d %2,%1
2651 %!mul<su>.d %1,%2
2652 %!mul<su>.d %2,%1\;move $mof,%0
2653 %!mul<su>.d %1,%2\;move $mof,%0"
f60c7155
HPN
2654 [(set_attr "slottable" "yes,yes,no,no")
2655 (set_attr "cc" "clobber")])
0b85d816
HPN
2656\f
2657;; Divide and modulus instructions. CRIS only has a step instruction.
2658
2659(define_insn "dstep_shift"
2660 [(set (match_operand:SI 0 "register_operand" "=r")
2661 (if_then_else:SI
2662 (geu:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2663 (const_int 1))
2664 (match_operand:SI 2 "register_operand" "r"))
2665 (minus:SI (ashift:SI (match_operand:SI 3 "register_operand" "0")
2666 (const_int 1))
2667 (match_operand:SI 4 "register_operand" "2"))
2668 (ashift:SI (match_operand:SI 5 "register_operand" "0")
2669 (const_int 1))))]
2670 ""
2671 "dstep %2,%0"
45d5d09c
HPN
2672 [(set_attr "slottable" "yes")
2673 (set_attr "cc" "noov32")])
0b85d816
HPN
2674
2675;; Here's a variant with mult instead of ashift.
2676;;
2677;; FIXME: This should be investigated. Which one matches through combination?
2678
2679(define_insn "dstep_mul"
2680 [(set (match_operand:SI 0 "register_operand" "=r")
2681 (if_then_else:SI
2682 (geu:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
2683 (const_int 2))
2684 (match_operand:SI 2 "register_operand" "r"))
2685 (minus:SI (mult:SI (match_operand:SI 3 "register_operand" "0")
2686 (const_int 2))
2687 (match_operand:SI 4 "register_operand" "2"))
2688 (mult:SI (match_operand:SI 5 "register_operand" "0")
2689 (const_int 2))))]
2690 "operands[0] != frame_pointer_rtx
2691 && operands[1] != frame_pointer_rtx
2692 && operands[2] != frame_pointer_rtx
2693 && operands[3] != frame_pointer_rtx"
2694 "dstep %2,%0"
45d5d09c
HPN
2695 [(set_attr "slottable" "yes")
2696 (set_attr "cc" "noov32")])
0b85d816
HPN
2697\f
2698;; Logical operators.
2699
2700;; Bitwise "and".
2701
2702;; There is no use in defining "anddi3", because gcc can expand this by
2703;; itself, and make reasonable code without interference.
2704
2705;; If the first operand is memory or a register and is the same as the
2706;; second operand, and the third operand is -256 or -65536, we can use
2707;; CLEAR instead. Or, if the first operand is a register, and the third
2708;; operand is 255 or 65535, we can zero_extend.
f5143c46 2709;; GCC isn't smart enough to recognize these cases (yet), and they seem
0b85d816
HPN
2710;; to be common enough to be worthwhile.
2711;; FIXME: This should be made obsolete.
2712
2713(define_expand "andsi3"
2714 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2715 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2716 (match_operand:SI 2 "general_operand" "")))]
2717 ""
0b85d816 2718{
991c42ac 2719 if (! (CONST_INT_P (operands[2])
0b85d816
HPN
2720 && (((INTVAL (operands[2]) == -256
2721 || INTVAL (operands[2]) == -65536)
2722 && rtx_equal_p (operands[1], operands[0]))
2723 || ((INTVAL (operands[2]) == 255
2724 || INTVAL (operands[2]) == 65535)
2725 && REG_P (operands[0])))))
2726 {
2727 /* Make intermediate steps if operand0 is not a register or
2728 operand1 is not a register, and hope that the reload pass will
2729 make something useful out of it. Note that the operands are
2730 *not* canonicalized. For the moment, I chicken out on this,
2731 because all or most ports do not describe 'and' with
2732 canonicalized operands, and I seem to remember magic in reload,
2733 checking that operand1 has constraint '%0', in which case
2734 operand0 and operand1 must have similar predicates.
2735 FIXME: Investigate. */
2736 rtx reg0 = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
2737 rtx reg1 = operands[1];
2738
2739 if (! REG_P (reg1))
2740 {
2741 emit_move_insn (reg0, reg1);
2742 reg1 = reg0;
2743 }
2744
2745 emit_insn (gen_rtx_SET (SImode, reg0,
2746 gen_rtx_AND (SImode, reg1, operands[2])));
2747
2748 /* Make sure we get the right *final* destination. */
2749 if (! REG_P (operands[0]))
2750 emit_move_insn (operands[0], reg0);
2751
2752 DONE;
2753 }
22c3c091 2754})
0b85d816
HPN
2755
2756;; Some special cases of andsi3.
2757
2758(define_insn "*andsi_movu"
2759 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
428eae94 2760 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q,To")
0b85d816 2761 (match_operand:SI 2 "const_int_operand" "n,n,n")))]
f38a62ff 2762 "(INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535)
c3e786e7 2763 && !side_effects_p (operands[1])"
0b85d816
HPN
2764 "movu.%z2 %1,%0"
2765 [(set_attr "slottable" "yes,yes,no")])
2766
2767(define_insn "*andsi_clear"
f38a62ff 2768 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q,Q,To,To")
0b85d816
HPN
2769 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
2770 (match_operand:SI 2 "const_int_operand" "P,n,P,n,P,n")))]
f38a62ff 2771 "(INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256)
c3e786e7 2772 && !side_effects_p (operands[0])"
0b85d816
HPN
2773 "@
2774 cLear.b %0
2775 cLear.w %0
2776 cLear.b %0
2777 cLear.w %0
2778 cLear.b %0
2779 cLear.w %0"
2780 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
2781 (set_attr "cc" "none")])
2782
2783;; This is a catch-all pattern, taking care of everything that was not
2784;; matched in the insns above.
2785;;
2786;; Sidenote: the tightening from "nonimmediate_operand" to
2787;; "register_operand" for operand 1 actually increased the register
2788;; pressure (worse code). That will hopefully change with an
2789;; improved reload pass.
2790
45d5d09c 2791(define_insn "*expanded_andsi_non_v32"
23369bef
HPN
2792 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r,r")
2793 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0,r")
2794 (match_operand:SI 2 "general_operand" "I,r,Q>,g,!To")))]
45d5d09c 2795 "!TARGET_V32"
0b85d816
HPN
2796 "@
2797 andq %2,%0
2798 and.d %2,%0
2799 and.d %2,%0
2800 and.d %2,%0
2801 and.d %2,%1,%0"
2802 [(set_attr "slottable" "yes,yes,yes,no,no")])
45d5d09c
HPN
2803
2804(define_insn "*expanded_andsi_v32"
2805 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2806 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
2807 (match_operand:SI 2 "general_operand" "I,r,Q>,g")))]
2808 "TARGET_V32"
2809 "@
2810 andq %2,%0
2811 and.d %2,%0
2812 and.d %2,%0
2813 and.d %2,%0"
2814 [(set_attr "slottable" "yes,yes,yes,no")
2815 (set_attr "cc" "noov32")])
0b85d816
HPN
2816\f
2817;; For both QI and HI we may use the quick patterns. This results in
2818;; useless condition codes, but that is used rarely enough for it to
2819;; normally be a win (could check ahead for use of cc0, but seems to be
2820;; more pain than win).
2821
2822;; FIXME: See note for andsi3
2823
2824(define_expand "andhi3"
2825 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2826 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
2827 (match_operand:HI 2 "general_operand" "")))]
2828 ""
0b85d816 2829{
991c42ac 2830 if (! (CONST_INT_P (operands[2])
0b85d816
HPN
2831 && (((INTVAL (operands[2]) == -256
2832 || INTVAL (operands[2]) == 65280)
2833 && rtx_equal_p (operands[1], operands[0]))
2834 || (INTVAL (operands[2]) == 255
2835 && REG_P (operands[0])))))
2836 {
2837 /* See comment for andsi3. */
2838 rtx reg0 = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (HImode);
2839 rtx reg1 = operands[1];
2840
2841 if (! REG_P (reg1))
2842 {
2843 emit_move_insn (reg0, reg1);
2844 reg1 = reg0;
2845 }
2846
2847 emit_insn (gen_rtx_SET (HImode, reg0,
2848 gen_rtx_AND (HImode, reg1, operands[2])));
2849
2850 /* Make sure we get the right destination. */
2851 if (! REG_P (operands[0]))
2852 emit_move_insn (operands[0], reg0);
2853
2854 DONE;
2855 }
22c3c091 2856})
0b85d816
HPN
2857
2858;; Some fast andhi3 special cases.
2859
2860(define_insn "*andhi_movu"
2861 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
428eae94 2862 (and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q,To")
0b85d816 2863 (const_int 255)))]
c3e786e7 2864 "!side_effects_p (operands[1])"
0b85d816
HPN
2865 "mOvu.b %1,%0"
2866 [(set_attr "slottable" "yes,yes,no")])
2867
f38a62ff
HPN
2868(define_insn "*andhi_clear"
2869 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q,To")
0b85d816
HPN
2870 (and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
2871 (const_int -256)))]
c3e786e7 2872 "!side_effects_p (operands[0])"
0b85d816
HPN
2873 "cLear.b %0"
2874 [(set_attr "slottable" "yes,yes,no")
2875 (set_attr "cc" "none")])
2876
2877;; Catch-all andhi3 pattern.
2878
45d5d09c 2879(define_insn "*expanded_andhi_non_v32"
23369bef
HPN
2880 [(set (match_operand:HI 0 "register_operand" "=r,r,r, r,r,r,r")
2881 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0, 0,0,0,r")
2882 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))]
0b85d816
HPN
2883
2884;; Sidenote: the tightening from "general_operand" to
2885;; "register_operand" for operand 1 actually increased the register
2886;; pressure (worse code). That will hopefully change with an
2887;; improved reload pass.
2888
45d5d09c 2889 "!TARGET_V32"
0b85d816
HPN
2890 "@
2891 andq %2,%0
2892 and.w %2,%0
2893 and.w %2,%0
2894 and.w %2,%0
2895 anDq %b2,%0
2896 and.w %2,%0
2897 and.w %2,%1,%0"
2898 [(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
2899 (set_attr "cc" "clobber,normal,normal,normal,clobber,normal,normal")])
2900
45d5d09c
HPN
2901(define_insn "*expanded_andhi_v32"
2902 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
2903 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
2904 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g")))]
2905 "TARGET_V32"
2906 "@
2907 andq %2,%0
2908 and.w %2,%0
2909 and.w %2,%0
2910 and.w %2,%0
2911 anDq %b2,%0
2912 and.w %2,%0"
2913 [(set_attr "slottable" "yes,yes,yes,no,yes,no")
2914 (set_attr "cc" "clobber,noov32,noov32,noov32,clobber,noov32")])
2915
0b85d816
HPN
2916;; A strict_low_part pattern.
2917
d7173593
HPN
2918;; Note the use of (match_dup 0) for the first operand of the operation
2919;; here. Reload can't handle an operand pair where one is read-write
2920;; and must match a read, like in:
2921;; (insn 80 79 81 4
2922;; (set (strict_low_part
2923;; (subreg:QI (reg/v:SI 0 r0 [orig:36 data ] [36]) 0))
2924;; (and:QI
2925;; (subreg:QI (reg:SI 15 acr [orig:27 D.7531 ] [27]) 0)
2926;; (const_int -64 [0xf..fc0]))) x.c:126 147 {*andqi_lowpart_v32}
2927;; (nil))
2928;; In theory, it could reload this as a movstrictqi of the register
2929;; operand at the and:QI to the destination register and change the
2930;; and:QI operand to the same as the read-write output operand and the
2931;; result would be recognized, but it doesn't recognize that's a valid
2932;; reload for a strict_low_part-destination; it just sees a "+" at the
2933;; destination constraints. Better than adding complexity to reload is
2934;; to follow the lead of m68k (see comment that begins with "These insns
2935;; must use MATCH_DUP") since prehistoric times and make it just a
2936;; match_dup. FIXME: a sanity-check in gen* to refuse an insn with
2937;; input-constraints matching input-output-constraints, e.g. "+r" <- "0".
2938
45d5d09c 2939(define_insn "*andhi_lowpart_non_v32"
0b85d816 2940 [(set (strict_low_part
d7173593
HPN
2941 (match_operand:HI 0 "register_operand" "+r,r,r"))
2942 (and:HI (match_dup 0)
2943 (match_operand:HI 1 "general_operand" "r,Q>,g")))]
45d5d09c 2944 "!TARGET_V32"
0b85d816 2945 "@
d7173593
HPN
2946 and.w %1,%0
2947 and.w %1,%0
2948 and.w %1,%0"
2949 [(set_attr "slottable" "yes,yes,no")])
45d5d09c
HPN
2950
2951(define_insn "*andhi_lowpart_v32"
2952 [(set (strict_low_part
d7173593
HPN
2953 (match_operand:HI 0 "register_operand" "+r,r,r"))
2954 (and:HI (match_dup 0)
2955 (match_operand:HI 1 "general_operand" "r,Q>,g")))]
45d5d09c
HPN
2956 "TARGET_V32"
2957 "@
d7173593
HPN
2958 and.w %1,%0
2959 and.w %1,%0
2960 and.w %1,%0"
2961 [(set_attr "slottable" "yes,yes,no")
2962 (set_attr "cc" "noov32")])
0b85d816 2963\f
45d5d09c
HPN
2964(define_expand "andqi3"
2965 [(set (match_operand:QI 0 "register_operand")
2966 (and:QI (match_operand:QI 1 "register_operand")
2967 (match_operand:QI 2 "general_operand")))]
2968 ""
2969 "")
2970
2971(define_insn "*andqi3_non_v32"
23369bef
HPN
2972 [(set (match_operand:QI 0 "register_operand" "=r,r,r, r,r,r")
2973 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0, 0,0,r")
2974 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))]
45d5d09c 2975 "!TARGET_V32"
0b85d816
HPN
2976 "@
2977 andq %2,%0
2978 and.b %2,%0
2979 and.b %2,%0
2980 andQ %b2,%0
2981 and.b %2,%0
2982 and.b %2,%1,%0"
2983 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
2984 (set_attr "cc" "clobber,normal,normal,clobber,normal,normal")])
2985
45d5d09c
HPN
2986(define_insn "*andqi3_v32"
2987 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
2988 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0")
2989 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g")))]
2990 "TARGET_V32"
2991 "@
2992 andq %2,%0
2993 and.b %2,%0
2994 and.b %2,%0
2995 andQ %b2,%0
2996 and.b %2,%0"
2997 [(set_attr "slottable" "yes,yes,yes,yes,no")
2998 (set_attr "cc" "clobber,noov32,noov32,clobber,noov32")])
2999
3000(define_insn "*andqi_lowpart_non_v32"
0b85d816 3001 [(set (strict_low_part
d7173593
HPN
3002 (match_operand:QI 0 "register_operand" "+r,r,r"))
3003 (and:QI (match_dup 0)
3004 (match_operand:QI 1 "general_operand" "r,Q>,g")))]
45d5d09c 3005 "!TARGET_V32"
0b85d816 3006 "@
d7173593
HPN
3007 and.b %1,%0
3008 and.b %1,%0
3009 and.b %1,%0"
3010 [(set_attr "slottable" "yes,yes,no")])
45d5d09c
HPN
3011
3012(define_insn "*andqi_lowpart_v32"
3013 [(set (strict_low_part
d7173593
HPN
3014 (match_operand:QI 0 "register_operand" "+r,r,r"))
3015 (and:QI (match_dup 0)
3016 (match_operand:QI 1 "general_operand" "r,Q>,g")))]
45d5d09c
HPN
3017 "TARGET_V32"
3018 "@
d7173593
HPN
3019 and.b %1,%0
3020 and.b %1,%0
3021 and.b %1,%0"
3022 [(set_attr "slottable" "yes,yes,no")
3023 (set_attr "cc" "noov32")])
0b85d816
HPN
3024\f
3025;; Bitwise or.
3026
3027;; Same comment as anddi3 applies here - no need for such a pattern.
3028
3029;; It seems there's no need to jump through hoops to get good code such as
3030;; with andsi3.
3031
45d5d09c
HPN
3032(define_expand "ior<mode>3"
3033 [(set (match_operand:BWD 0 "register_operand")
3034 (ior:BWD (match_operand:BWD 1 "register_operand")
3035 (match_operand:BWD 2 "general_operand")))]
3036 ""
3037 "")
3038
3039(define_insn "*iorsi3_non_v32"
23369bef
HPN
3040 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r,r,r")
3041 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0,0,r")
3042 (match_operand:SI 2 "general_operand" "I, r,Q>,n,g,!To")))]
45d5d09c 3043 "!TARGET_V32"
0b85d816
HPN
3044 "@
3045 orq %2,%0
3046 or.d %2,%0
3047 or.d %2,%0
3048 oR.%s2 %2,%0
3049 or.d %2,%0
3050 or.d %2,%1,%0"
3051 [(set_attr "slottable" "yes,yes,yes,no,no,no")
3052 (set_attr "cc" "normal,normal,normal,clobber,normal,normal")])
3053
45d5d09c
HPN
3054(define_insn "*iorsi3_v32"
3055 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
3056 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
3057 (match_operand:SI 2 "general_operand" "I,r,Q>,n,g")))]
3058 "TARGET_V32"
3059 "@
3060 orq %2,%0
3061 or.d %2,%0
3062 or.d %2,%0
3063 oR.%s2 %2,%0
3064 or.d %2,%0"
3065 [(set_attr "slottable" "yes,yes,yes,no,no")
3066 (set_attr "cc" "noov32,noov32,noov32,clobber,noov32")])
3067
3068(define_insn "*iorhi3_non_v32"
23369bef
HPN
3069 [(set (match_operand:HI 0 "register_operand" "=r,r,r, r,r,r,r")
3070 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0, 0,0,0,r")
3071 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))]
45d5d09c 3072 "!TARGET_V32"
0b85d816
HPN
3073 "@
3074 orq %2,%0
3075 or.w %2,%0
3076 or.w %2,%0
3077 or.w %2,%0
3078 oRq %b2,%0
3079 or.w %2,%0
3080 or.w %2,%1,%0"
3081 [(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
3082 (set_attr "cc" "clobber,normal,normal,normal,clobber,normal,normal")])
3083
45d5d09c
HPN
3084(define_insn "*iorhi3_v32"
3085 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
3086 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
3087 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g")))]
3088 "TARGET_V32"
3089 "@
3090 orq %2,%0
3091 or.w %2,%0
3092 or.w %2,%0
3093 or.w %2,%0
3094 oRq %b2,%0
3095 or.w %2,%0"
3096 [(set_attr "slottable" "yes,yes,yes,no,yes,no")
3097 (set_attr "cc" "clobber,noov32,noov32,noov32,clobber,noov32")])
3098
3099(define_insn "*iorqi3_non_v32"
23369bef
HPN
3100 [(set (match_operand:QI 0 "register_operand" "=r,r,r, r,r,r")
3101 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0, 0,0,r")
3102 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))]
45d5d09c 3103 "!TARGET_V32"
0b85d816
HPN
3104 "@
3105 orq %2,%0
3106 or.b %2,%0
3107 or.b %2,%0
3108 orQ %b2,%0
3109 or.b %2,%0
3110 or.b %2,%1,%0"
3111 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
3112 (set_attr "cc" "clobber,normal,normal,clobber,normal,normal")])
45d5d09c
HPN
3113
3114(define_insn "*iorqi3_v32"
3115 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
3116 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0")
3117 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g")))]
3118 "TARGET_V32"
3119 "@
3120 orq %2,%0
3121 or.b %2,%0
3122 or.b %2,%0
3123 orQ %b2,%0
3124 or.b %2,%0"
3125 [(set_attr "slottable" "yes,yes,yes,yes,no")
3126 (set_attr "cc" "clobber,noov32,noov32,clobber,noov32")])
0b85d816
HPN
3127\f
3128;; Exclusive-or
3129
3130;; See comment about "anddi3" for xordi3 - no need for such a pattern.
22c3c091 3131;; FIXME: Do we really need the shorter variants?
0b85d816
HPN
3132
3133(define_insn "xorsi3"
3134 [(set (match_operand:SI 0 "register_operand" "=r")
3135 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3136 (match_operand:SI 2 "register_operand" "r")))]
3137 ""
3138 "xor %2,%0"
45d5d09c
HPN
3139 [(set_attr "slottable" "yes")
3140 (set_attr "cc" "noov32")])
0b85d816 3141
22c3c091
HPN
3142(define_insn "xor<mode>3"
3143 [(set (match_operand:BW 0 "register_operand" "=r")
3144 (xor:BW (match_operand:BW 1 "register_operand" "%0")
3145 (match_operand:BW 2 "register_operand" "r")))]
0b85d816
HPN
3146 ""
3147 "xor %2,%0"
3148 [(set_attr "slottable" "yes")
3149 (set_attr "cc" "clobber")])
3150\f
3151;; Negation insns.
3152
3153;; Questionable use, here mostly as a (slightly usable) define_expand
3154;; example.
3155
3156(define_expand "negsf2"
3157 [(set (match_dup 2)
3158 (match_dup 3))
3159 (parallel [(set (match_operand:SF 0 "register_operand" "=r")
3160 (neg:SF (match_operand:SF 1
3161 "register_operand" "0")))
3162 (use (match_dup 2))])]
3163 ""
0b85d816
HPN
3164{
3165 operands[2] = gen_reg_rtx (SImode);
3166 operands[3] = GEN_INT (1 << 31);
22c3c091 3167})
0b85d816
HPN
3168
3169(define_insn "*expanded_negsf2"
3170 [(set (match_operand:SF 0 "register_operand" "=r")
3171 (neg:SF (match_operand:SF 1 "register_operand" "0")))
3172 (use (match_operand:SI 2 "register_operand" "r"))]
3173 ""
3174 "xor %2,%0"
3175 [(set_attr "slottable" "yes")])
3176
3177;; No "negdi2" although we could make one up that may be faster than
3178;; the one in libgcc.
3179
22c3c091
HPN
3180(define_insn "neg<mode>2"
3181 [(set (match_operand:BWD 0 "register_operand" "=r")
3182 (neg:BWD (match_operand:BWD 1 "register_operand" "r")))]
0b85d816 3183 ""
22c3c091 3184 "neg<m> %1,%0"
0b85d816
HPN
3185 [(set_attr "slottable" "yes")])
3186\f
3187;; One-complements.
3188
3189;; See comment on anddi3 - no need for a DImode pattern.
22c3c091 3190;; See also xor comment.
0b85d816
HPN
3191
3192(define_insn "one_cmplsi2"
3193 [(set (match_operand:SI 0 "register_operand" "=r")
3194 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3195 ""
3196 "not %0"
45d5d09c
HPN
3197 [(set_attr "slottable" "yes")
3198 (set_attr "cc" "noov32")])
0b85d816 3199
22c3c091
HPN
3200(define_insn "one_cmpl<mode>2"
3201 [(set (match_operand:BW 0 "register_operand" "=r")
3202 (not:BW (match_operand:BW 1 "register_operand" "0")))]
0b85d816
HPN
3203 ""
3204 "not %0"
3205 [(set_attr "slottable" "yes")
3206 (set_attr "cc" "clobber")])
3207\f
22c3c091 3208;; Arithmetic/Logical shift right (and SI left).
0b85d816 3209
22c3c091 3210(define_insn "<shlr>si3"
0b85d816 3211 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 3212 (shift:SI (match_operand:SI 1 "register_operand" "0")
f49e46d8 3213 (match_operand:SI 2 "nonmemory_operand" "Kcr")))]
0b85d816 3214 ""
0b85d816
HPN
3215{
3216 if (REG_S_P (operands[2]))
22c3c091 3217 return "<slr>.d %2,%0";
0b85d816 3218
22c3c091
HPN
3219 return "<slr>q %2,%0";
3220}
45d5d09c
HPN
3221 [(set_attr "slottable" "yes")
3222 (set_attr "cc" "noov32")])
0b85d816 3223
22c3c091
HPN
3224;; Since gcc gets lost, and forgets to zero-extend the source (or mask
3225;; the destination) when it changes shifts of lower modes into SImode,
3226;; it is better to make these expands an anonymous patterns instead of
3227;; the more correct define_insns. This occurs when gcc thinks that is
3228;; is better to widen to SImode and use immediate shift count.
0b85d816 3229
22c3c091 3230;; FIXME: Is this legacy or still true for gcc >= 2.7.2?
0b85d816 3231
22c3c091
HPN
3232;; FIXME: Can't parametrize sign_extend and zero_extend (before
3233;; mentioning "shiftrt"), so we need two patterns.
3234(define_expand "ashr<mode>3"
0b85d816 3235 [(set (match_dup 3)
22c3c091 3236 (sign_extend:SI (match_operand:BW 1 "nonimmediate_operand" "")))
0b85d816 3237 (set (match_dup 4)
22c3c091
HPN
3238 (zero_extend:SI (match_operand:BW 2 "nonimmediate_operand" "")))
3239 (set (match_dup 5) (ashiftrt:SI (match_dup 3) (match_dup 4)))
3240 (set (match_operand:BW 0 "general_operand" "")
3241 (subreg:BW (match_dup 5) 0))]
0b85d816 3242 ""
0b85d816
HPN
3243{
3244 int i;
3245
3246 for (i = 3; i < 6; i++)
3247 operands[i] = gen_reg_rtx (SImode);
22c3c091 3248})
0b85d816 3249
22c3c091 3250(define_expand "lshr<mode>3"
0b85d816 3251 [(set (match_dup 3)
22c3c091 3252 (zero_extend:SI (match_operand:BW 1 "nonimmediate_operand" "")))
0b85d816 3253 (set (match_dup 4)
22c3c091 3254 (zero_extend:SI (match_operand:BW 2 "nonimmediate_operand" "")))
0b85d816 3255 (set (match_dup 5) (lshiftrt:SI (match_dup 3) (match_dup 4)))
22c3c091
HPN
3256 (set (match_operand:BW 0 "general_operand" "")
3257 (subreg:BW (match_dup 5) 0))]
0b85d816 3258 ""
0b85d816
HPN
3259{
3260 int i;
3261
3262 for (i = 3; i < 6; i++)
3263 operands[i] = gen_reg_rtx (SImode);
22c3c091 3264})
0b85d816 3265
22c3c091
HPN
3266(define_insn "*expanded_<shlr><mode>"
3267 [(set (match_operand:BW 0 "register_operand" "=r")
3268 (shiftrt:BW (match_operand:BW 1 "register_operand" "0")
3269 (match_operand:BW 2 "register_operand" "r")))]
0b85d816 3270 ""
22c3c091 3271 "<slr><m> %2,%0"
45d5d09c
HPN
3272 [(set_attr "slottable" "yes")
3273 (set_attr "cc" "noov32")])
0b85d816 3274
22c3c091
HPN
3275(define_insn "*<shlr><mode>_lowpart"
3276 [(set (strict_low_part (match_operand:BW 0 "register_operand" "+r"))
3277 (shiftrt:BW (match_dup 0)
3278 (match_operand:BW 1 "register_operand" "r")))]
0b85d816 3279 ""
22c3c091 3280 "<slr><m> %1,%0"
45d5d09c
HPN
3281 [(set_attr "slottable" "yes")
3282 (set_attr "cc" "noov32")])
0b85d816
HPN
3283\f
3284;; Arithmetic/logical shift left.
3285
0b85d816
HPN
3286;; For narrower modes than SI, we can use lslq although it makes cc
3287;; unusable. The win is that we do not have to reload the shift-count
3288;; into a register.
3289
22c3c091
HPN
3290(define_insn "ashl<mode>3"
3291 [(set (match_operand:BW 0 "register_operand" "=r,r")
3292 (ashift:BW (match_operand:BW 1 "register_operand" "0,0")
f49e46d8 3293 (match_operand:BW 2 "nonmemory_operand" "r,Kc")))]
0b85d816 3294 ""
0b85d816
HPN
3295{
3296 return
991c42ac 3297 (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > <nbitsm1>)
22c3c091 3298 ? "moveq 0,%0"
0b85d816 3299 : (CONSTANT_P (operands[2])
22c3c091
HPN
3300 ? "lslq %2,%0" : "lsl<m> %2,%0");
3301}
0b85d816 3302 [(set_attr "slottable" "yes")
45d5d09c 3303 (set_attr "cc" "noov32,clobber")])
0b85d816
HPN
3304
3305;; A strict_low_part matcher.
3306
22c3c091
HPN
3307(define_insn "*ashl<mode>_lowpart"
3308 [(set (strict_low_part (match_operand:BW 0 "register_operand" "+r"))
3309 (ashift:BW (match_dup 0)
3310 (match_operand:HI 1 "register_operand" "r")))]
0b85d816 3311 ""
22c3c091 3312 "lsl<m> %1,%0"
45d5d09c
HPN
3313 [(set_attr "slottable" "yes")
3314 (set_attr "cc" "noov32")])
0b85d816
HPN
3315\f
3316;; Various strange insns that gcc likes.
3317
3318;; Fortunately, it is simple to construct an abssf (although it may not
3319;; be very much used in practice).
3320
3321(define_insn "abssf2"
3322 [(set (match_operand:SF 0 "register_operand" "=r")
3323 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
3324 ""
3325 "lslq 1,%0\;lsrq 1,%0")
3326
3327(define_insn "abssi2"
3328 [(set (match_operand:SI 0 "register_operand" "=r")
3329 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
3330 ""
3331 "abs %1,%0"
45d5d09c
HPN
3332 [(set_attr "slottable" "yes")
3333 (set_attr "cc" "noov32")])
0b85d816
HPN
3334
3335;; FIXME: GCC should be able to do these expansions itself.
3336
22c3c091 3337(define_expand "abs<mode>2"
0b85d816 3338 [(set (match_dup 2)
22c3c091 3339 (sign_extend:SI (match_operand:BW 1 "general_operand" "")))
0b85d816 3340 (set (match_dup 3) (abs:SI (match_dup 2)))
22c3c091
HPN
3341 (set (match_operand:BW 0 "register_operand" "")
3342 (subreg:BW (match_dup 3) 0))]
0b85d816
HPN
3343 ""
3344 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
e636e508
JN
3345
3346(define_insn "clzsi2"
3347 [(set (match_operand:SI 0 "register_operand" "=r")
3348 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
3349 "TARGET_HAS_LZ"
3350 "lz %1,%0"
45d5d09c
HPN
3351 [(set_attr "slottable" "yes")
3352 (set_attr "cc" "noov32")])
e636e508 3353
df638b27
JN
3354(define_insn "bswapsi2"
3355 [(set (match_operand:SI 0 "register_operand" "=r")
3356 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
3357 "TARGET_HAS_SWAP"
3358 "swapwb %0"
45d5d09c
HPN
3359 [(set_attr "slottable" "yes")
3360 (set_attr "cc" "noov32")])
df638b27 3361
9ef4a0cd
JN
3362;; This instruction swaps all bits in a register.
3363;; That means that the most significant bit is put in the place
3364;; of the least significant bit, and so on.
3365
3366(define_insn "cris_swap_bits"
3367 [(set (match_operand:SI 0 "register_operand" "=r")
3368 (unspec:SI [(match_operand:SI 1 "register_operand" "0")]
3369 CRIS_UNSPEC_SWAP_BITS))]
3370 "TARGET_HAS_SWAP"
3371 "swapwbr %0"
45d5d09c
HPN
3372 [(set_attr "slottable" "yes")
3373 (set_attr "cc" "noov32")])
9ef4a0cd
JN
3374
3375;; Implement ctz using two instructions, one for bit swap and one for clz.
3376;; Defines a scratch register to avoid clobbering input.
3377
3378(define_expand "ctzsi2"
3379 [(set (match_dup 2)
3380 (match_operand:SI 1 "register_operand"))
3381 (set (match_dup 2)
3382 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS))
3383 (set (match_operand:SI 0 "register_operand")
3384 (clz:SI (match_dup 2)))]
3385 "TARGET_HAS_LZ && TARGET_HAS_SWAP"
3386 "operands[2] = gen_reg_rtx (SImode);")
3387
0b85d816
HPN
3388;; Bound-insn. Defined to be the same as an unsigned minimum, which is an
3389;; operation supported by gcc. Used in casesi, but used now and then in
3390;; normal code too.
3391
45d5d09c
HPN
3392(define_expand "uminsi3"
3393 [(set (match_operand:SI 0 "register_operand" "")
3394 (umin:SI (match_operand:SI 1 "register_operand" "")
3395 (match_operand:SI 2 "general_operand" "")))]
3396 ""
3397{
3398 if (MEM_P (operands[2]) && TARGET_V32)
3399 operands[2] = force_reg (SImode, operands[2]);
3400})
3401
3402(define_insn "*uminsi3_non_v32"
23369bef
HPN
3403 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
3404 (umin:SI (match_operand:SI 1 "register_operand" "%0,0, 0,r")
c00fc5cf 3405 (match_operand:SI 2 "general_operand" "r,Q>,g,!To")))]
45d5d09c 3406 "!TARGET_V32"
0b85d816 3407{
991c42ac 3408 if (CONST_INT_P (operands[2]))
0b85d816 3409 {
d76fe40b
HPN
3410 /* Constant operands are zero-extended, so only 32-bit operands
3411 may be negative. */
3412 if (INTVAL (operands[2]) >= 0)
3413 {
3414 if (INTVAL (operands[2]) < 256)
3415 return "bound.b %2,%0";
0b85d816 3416
d76fe40b
HPN
3417 if (INTVAL (operands[2]) < 65536)
3418 return "bound.w %2,%0";
3419 }
0b85d816
HPN
3420 }
3421 else if (which_alternative == 3)
22c3c091 3422 return "bound.d %2,%1,%0";
0b85d816 3423
22c3c091
HPN
3424 return "bound.d %2,%0";
3425}
0b85d816 3426 [(set_attr "slottable" "yes,yes,no,no")])
45d5d09c
HPN
3427
3428(define_insn "*uminsi3_v32"
3429 [(set (match_operand:SI 0 "register_operand" "=r,r")
3430 (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
3431 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
3432 "TARGET_V32"
3433{
3434 if (GET_CODE (operands[2]) == CONST_INT)
3435 {
3436 /* Constant operands are zero-extended, so only 32-bit operands
3437 may be negative. */
3438 if (INTVAL (operands[2]) >= 0)
3439 {
3440 if (INTVAL (operands[2]) < 256)
3441 return "bound.b %2,%0";
3442
3443 if (INTVAL (operands[2]) < 65536)
3444 return "bound.w %2,%0";
3445 }
3446 }
3447
3448 return "bound.d %2,%0";
3449}
3450 [(set_attr "slottable" "yes,no")])
0b85d816
HPN
3451\f
3452;; Jump and branch insns.
3453
3454(define_insn "jump"
3455 [(set (pc)
3456 (label_ref (match_operand 0 "" "")))]
3457 ""
3458 "ba %l0%#"
3459 [(set_attr "slottable" "has_slot")])
3460
3461;; Testcase gcc.c-torture/compile/991213-3.c fails if we allow a constant
3462;; here, since the insn is not recognized as an indirect jump by
3463;; jmp_uses_reg_or_mem used by computed_jump_p. Perhaps it is a kludge to
3464;; change from general_operand to nonimmediate_operand (at least the docs
3465;; should be changed), but then again the pattern is called indirect_jump.
45d5d09c
HPN
3466(define_expand "indirect_jump"
3467 [(set (pc) (match_operand:SI 0 "nonimmediate_operand"))]
0b85d816 3468 ""
45d5d09c
HPN
3469{
3470 if (TARGET_V32 && MEM_P (operands[0]))
3471 operands[0] = force_reg (SImode, operands[0]);
3472})
3473
3474(define_insn "*indirect_jump_non_v32"
3475 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
3476 "!TARGET_V32"
0b85d816
HPN
3477 "jump %0")
3478
45d5d09c
HPN
3479(define_insn "*indirect_jump_v32"
3480 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3481 "TARGET_V32"
3482 "jump %0%#"
3483 [(set_attr "slottable" "has_slot")])
3484
0b85d816 3485;; Return insn. Used whenever the epilogue is very simple; if it is only
04539954
HPN
3486;; a single ret or jump [sp+]. No allocated stack space or saved
3487;; registers are allowed.
0b85d816
HPN
3488;; Note that for this pattern, although named, it is ok to check the
3489;; context of the insn in the test, not only compiler switches.
3490
04539954 3491(define_expand "return"
0b85d816
HPN
3492 [(return)]
3493 "cris_simple_epilogue ()"
04539954 3494 "cris_expand_return (cris_return_address_on_stack ()); DONE;")
0b85d816 3495
04539954
HPN
3496(define_insn "*return_expanded"
3497 [(return)]
3498 ""
3499{
3500 return cris_return_address_on_stack_for_return ()
3501 ? "jump [$sp+]" : "ret%#";
3502}
0b85d816 3503 [(set (attr "slottable")
04539954 3504 (if_then_else
bf0b8cbe 3505 (match_test "cris_return_address_on_stack_for_return ()")
04539954 3506 (const_string "no")
45d5d09c 3507 (const_string "has_return_slot")))])
04539954 3508
d29b4b1b
HPN
3509(define_expand "prologue"
3510 [(const_int 0)]
3511 "TARGET_PROLOGUE_EPILOGUE"
3512 "cris_expand_prologue (); DONE;")
3513
04539954
HPN
3514;; Note that the (return) from the expander itself is always the last
3515;; insn in the epilogue.
3516(define_expand "epilogue"
3517 [(const_int 0)]
a6dfafa0 3518 "TARGET_PROLOGUE_EPILOGUE"
04539954 3519 "cris_expand_epilogue (); DONE;")
0b85d816
HPN
3520\f
3521;; Conditional branches.
3522
f90b7a5a
PB
3523(define_expand "cbranch<mode>4"
3524 [(set (cc0) (compare
3525 (match_operand:BWD 1 "nonimmediate_operand")
3526 (match_operand:BWD 2 "general_operand")))
3527 (set (pc)
3528 (if_then_else (match_operator 0 "ordered_comparison_operator"
3529 [(cc0) (const_int 0)])
3530 (label_ref (match_operand 3 "" ""))
3531 (pc)))]
3532 ""
3533 "")
3534
3535(define_expand "cbranchdi4"
3536 [(set (cc0)
3537 (compare (match_operand:DI 1 "nonimmediate_operand" "")
3538 (match_operand:DI 2 "general_operand" "")))
3539 (set (pc)
3540 (if_then_else (match_operator 0 "ordered_comparison_operator"
3541 [(cc0) (const_int 0)])
3542 (label_ref (match_operand 3 "" ""))
3543 (pc)))]
3544 ""
3545{
3546 if (TARGET_V32 && !REG_P (operands[1]))
3547 operands[1] = force_reg (DImode, operands[1]);
3548 if (TARGET_V32 && MEM_P (operands[2]))
3549 operands[2] = force_reg (DImode, operands[2]);
3550})
3551
3552
0b85d816
HPN
3553;; We suffer from the same overflow-bit-gets-in-the-way problem as
3554;; e.g. m68k, so we have to check if overflow bit is set on all "signed"
3555;; conditions.
3556
221ca267 3557(define_insn "b<ncond:code>"
0b85d816 3558 [(set (pc)
22c3c091
HPN
3559 (if_then_else (ncond (cc0)
3560 (const_int 0))
0b85d816
HPN
3561 (label_ref (match_operand 0 "" ""))
3562 (pc)))]
3563 ""
22c3c091 3564 "b<CC> %l0%#"
0b85d816
HPN
3565 [(set_attr "slottable" "has_slot")])
3566
221ca267 3567(define_insn "b<ocond:code>"
0b85d816 3568 [(set (pc)
22c3c091
HPN
3569 (if_then_else (ocond (cc0)
3570 (const_int 0))
0b85d816
HPN
3571 (label_ref (match_operand 0 "" ""))
3572 (pc)))]
3573 ""
0b85d816
HPN
3574{
3575 return
3576 (cc_prev_status.flags & CC_NO_OVERFLOW)
221ca267 3577 ? 0 : "b<CC> %l0%#";
22c3c091 3578}
0b85d816
HPN
3579 [(set_attr "slottable" "has_slot")])
3580
221ca267 3581(define_insn "b<rcond:code>"
0b85d816 3582 [(set (pc)
22c3c091
HPN
3583 (if_then_else (rcond (cc0)
3584 (const_int 0))
0b85d816
HPN
3585 (label_ref (match_operand 0 "" ""))
3586 (pc)))]
3587 ""
0b85d816
HPN
3588{
3589 return
3590 (cc_prev_status.flags & CC_NO_OVERFLOW)
22c3c091
HPN
3591 ? "b<oCC> %l0%#" : "b<CC> %l0%#";
3592}
0b85d816
HPN
3593 [(set_attr "slottable" "has_slot")])
3594\f
3595;; Reversed anonymous patterns to the ones above, as mandated.
3596
221ca267 3597(define_insn "*b<ncond:code>_reversed"
0b85d816 3598 [(set (pc)
22c3c091
HPN
3599 (if_then_else (ncond (cc0)
3600 (const_int 0))
0b85d816
HPN
3601 (pc)
3602 (label_ref (match_operand 0 "" ""))))]
3603 ""
22c3c091 3604 "b<rCC> %l0%#"
0b85d816
HPN
3605 [(set_attr "slottable" "has_slot")])
3606
221ca267 3607(define_insn "*b<ocond:code>_reversed"
0b85d816 3608 [(set (pc)
22c3c091
HPN
3609 (if_then_else (ocond (cc0)
3610 (const_int 0))
0b85d816
HPN
3611 (pc)
3612 (label_ref (match_operand 0 "" ""))))]
3613 ""
0b85d816
HPN
3614{
3615 return
3616 (cc_prev_status.flags & CC_NO_OVERFLOW)
221ca267 3617 ? 0 : "b<rCC> %l0%#";
22c3c091 3618}
0b85d816
HPN
3619 [(set_attr "slottable" "has_slot")])
3620
221ca267 3621(define_insn "*b<rcond:code>_reversed"
0b85d816 3622 [(set (pc)
22c3c091
HPN
3623 (if_then_else (rcond (cc0)
3624 (const_int 0))
0b85d816
HPN
3625 (pc)
3626 (label_ref (match_operand 0 "" ""))))]
3627 ""
0b85d816
HPN
3628{
3629 return
3630 (cc_prev_status.flags & CC_NO_OVERFLOW)
221ca267 3631 ? "b<roCC> %l0%#" : "b<rCC> %l0%#";
22c3c091 3632}
0b85d816
HPN
3633 [(set_attr "slottable" "has_slot")])
3634\f
3635;; Set on condition: sCC.
3636
f90b7a5a
PB
3637(define_expand "cstoredi4"
3638 [(set (cc0) (compare
3639 (match_operand:DI 2 "nonimmediate_operand")
3640 (match_operand:DI 3 "general_operand")))
3641 (set (match_operand:SI 0 "register_operand")
3642 (match_operator:SI 1 "ordered_comparison_operator"
3643 [(cc0) (const_int 0)]))]
3644 ""
3645{
3646 if (TARGET_V32 && !REG_P (operands[2]))
3647 operands[2] = force_reg (DImode, operands[2]);
3648 if (TARGET_V32 && MEM_P (operands[3]))
3649 operands[3] = force_reg (DImode, operands[3]);
3650})
3651
3652(define_expand "cstore<mode>4"
3653 [(set (cc0) (compare
3654 (match_operand:BWD 2 "nonimmediate_operand")
3655 (match_operand:BWD 3 "general_operand")))
3656 (set (match_operand:SI 0 "register_operand")
3657 (match_operator:SI 1 "ordered_comparison_operator"
3658 [(cc0) (const_int 0)]))]
3659 ""
3660 "")
3661
0b85d816
HPN
3662;; Like bCC, we have to check the overflow bit for
3663;; signed conditions.
3664
221ca267 3665(define_insn "s<ncond:code>"
0b85d816 3666 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 3667 (ncond:SI (cc0) (const_int 0)))]
0b85d816 3668 ""
22c3c091 3669 "s<CC> %0"
0b85d816
HPN
3670 [(set_attr "slottable" "yes")
3671 (set_attr "cc" "none")])
3672
221ca267 3673(define_insn "s<rcond:code>"
0b85d816 3674 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 3675 (rcond:SI (cc0) (const_int 0)))]
0b85d816 3676 ""
0b85d816
HPN
3677{
3678 return
3679 (cc_prev_status.flags & CC_NO_OVERFLOW)
22c3c091
HPN
3680 ? "s<oCC> %0" : "s<CC> %0";
3681}
0cec6af1
HPN
3682 [(set_attr "slottable" "yes")
3683 (set_attr "cc" "none")])
0b85d816 3684
221ca267 3685(define_insn "s<ocond:code>"
0b85d816 3686 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 3687 (ocond:SI (cc0) (const_int 0)))]
0b85d816 3688 ""
0b85d816
HPN
3689{
3690 return
3691 (cc_prev_status.flags & CC_NO_OVERFLOW)
22c3c091
HPN
3692 ? 0 : "s<CC> %0";
3693}
0b85d816
HPN
3694 [(set_attr "slottable" "yes")
3695 (set_attr "cc" "none")])
3696\f
3697;; Call insns.
3698
3699;; We need to make these patterns "expand", since the real operand is
3700;; hidden in a (mem:QI ) inside operand[0] (call_value: operand[1]),
3701;; and cannot be checked if it were a "normal" pattern.
3702;; Note that "call" and "call_value" are *always* called with a
3703;; mem-operand for operand 0 and 1 respective. What happens for combined
3704;; instructions is a different issue.
3705
3706(define_expand "call"
3707 [(parallel [(call (match_operand:QI 0 "cris_mem_call_operand" "")
3708 (match_operand 1 "general_operand" ""))
f16bb520 3709 (clobber (reg:SI CRIS_SRP_REGNUM))])]
0b85d816 3710 ""
0b85d816 3711{
991c42ac 3712 gcc_assert (MEM_P (operands[0]));
0b85d816 3713 if (flag_pic)
c00fc5cf 3714 cris_expand_pic_call_address (&operands[0]);
b6c34129 3715})
0b85d816
HPN
3716
3717;; Accept *anything* as operand 1. Accept operands for operand 0 in
23369bef 3718;; order of preference.
0b85d816 3719
45d5d09c
HPN
3720(define_insn "*expanded_call_non_v32"
3721 [(call (mem:QI (match_operand:SI 0 "general_operand" "r,Q>,g"))
0b85d816 3722 (match_operand 1 "" ""))
f16bb520 3723 (clobber (reg:SI CRIS_SRP_REGNUM))]
45d5d09c 3724 "!TARGET_V32"
0b85d816
HPN
3725 "jsr %0")
3726
45d5d09c
HPN
3727(define_insn "*expanded_call_v32"
3728 [(call
3729 (mem:QI
3730 (match_operand:SI 0 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
3731 (match_operand 1 "" ""))
3732 (clobber (reg:SI CRIS_SRP_REGNUM))]
3733 "TARGET_V32"
3734 "@
3735 jsr %0%#
3736 jsr %0%#
3737 bsr %0%#
3738 bsr %0%#"
3739 [(set_attr "slottable" "has_call_slot")])
3740
c00fc5cf
HPN
3741;; Parallel when calculating and reusing address of indirect pointer
3742;; with simple offset. (Makes most sense with PIC.) It looks a bit
3743;; wrong not to have the clobber last, but that's the way combine
3744;; generates it (except it doesn' look into the *inner* mem, so this
3745;; just matches a peephole2). FIXME: investigate that.
3746(define_insn "*expanded_call_side"
3747 [(call (mem:QI
3748 (mem:SI
3749 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r, r,r")
3750 (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r,>Rn"))))
3751 (match_operand 2 "" ""))
3752 (clobber (reg:SI CRIS_SRP_REGNUM))
3753 (set (match_operand:SI 3 "register_operand" "=*0,r,r")
3754 (plus:SI (match_dup 0)
3755 (match_dup 1)))]
45d5d09c 3756 "!TARGET_AVOID_GOTPLT && !TARGET_V32"
c00fc5cf
HPN
3757 "jsr [%3=%0%S1]")
3758
0b85d816
HPN
3759(define_expand "call_value"
3760 [(parallel [(set (match_operand 0 "" "")
3761 (call (match_operand:QI 1 "cris_mem_call_operand" "")
3762 (match_operand 2 "" "")))
f16bb520 3763 (clobber (reg:SI CRIS_SRP_REGNUM))])]
0b85d816 3764 ""
0b85d816 3765{
991c42ac 3766 gcc_assert (MEM_P (operands[1]));
0b85d816 3767 if (flag_pic)
c00fc5cf 3768 cris_expand_pic_call_address (&operands[1]);
b6c34129 3769})
0b85d816
HPN
3770
3771;; Accept *anything* as operand 2. The validity other than "general" of
3772;; operand 0 will be checked elsewhere. Accept operands for operand 1 in
3773;; order of preference (Q includes r, but r is shorter, faster).
3774;; We also accept a PLT symbol. We output it as [rPIC+sym:GOTPLT] rather
3775;; than requiring getting rPIC + sym:PLT into a register.
3776
45d5d09c 3777(define_insn "*expanded_call_value_non_v32"
c00fc5cf 3778 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
45d5d09c 3779 (call (mem:QI (match_operand:SI 1 "general_operand" "r,Q>,g"))
0b85d816 3780 (match_operand 2 "" "")))
f16bb520 3781 (clobber (reg:SI CRIS_SRP_REGNUM))]
45d5d09c 3782 "!TARGET_V32"
0b85d816
HPN
3783 "Jsr %1"
3784 [(set_attr "cc" "clobber")])
3785
c00fc5cf
HPN
3786;; See similar call special-case.
3787(define_insn "*expanded_call_value_side"
0b85d816 3788 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
c00fc5cf
HPN
3789 (call
3790 (mem:QI
3791 (mem:SI
3792 (plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r, r,r")
3793 (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn"))))
3794 (match_operand 3 "" "")))
3795 (clobber (reg:SI CRIS_SRP_REGNUM))
3796 (set (match_operand:SI 4 "register_operand" "=*1,r,r")
3797 (plus:SI (match_dup 1)
3798 (match_dup 2)))]
45d5d09c 3799 "!TARGET_AVOID_GOTPLT && !TARGET_V32"
c00fc5cf 3800 "Jsr [%4=%1%S2]"
0b85d816
HPN
3801 [(set_attr "cc" "clobber")])
3802
45d5d09c
HPN
3803(define_insn "*expanded_call_value_v32"
3804 [(set
3805 (match_operand 0 "nonimmediate_operand" "=g,g,g,g")
3806 (call
3807 (mem:QI
3808 (match_operand:SI 1 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
3809 (match_operand 2 "" "")))
3810 (clobber (reg:SI 16))]
3811 "TARGET_V32"
3812 "@
3813 Jsr %1%#
3814 Jsr %1%#
3815 Bsr %1%#
3816 Bsr %1%#"
3817 [(set_attr "cc" "clobber")
3818 (set_attr "slottable" "has_call_slot")])
3819
0b85d816
HPN
3820;; Used in debugging. No use for the direct pattern; unfilled
3821;; delayed-branches are taken care of by other means.
3822
3823(define_insn "nop"
3824 [(const_int 0)]
3825 ""
3826 "nop"
3827 [(set_attr "cc" "none")])
3828\f
04539954
HPN
3829;; We need to stop accesses to the stack after the memory is
3830;; deallocated. Unfortunately, reorg doesn't look at naked clobbers,
3831;; e.g. (insn ... (clobber (mem:BLK (stack_pointer_rtx)))) and we don't
3832;; want to use a naked (unspec_volatile) as that would stop any
3833;; scheduling in the epilogue. Hence we model it as a "real" insn that
3834;; sets the memory in an unspecified manner. FIXME: Unfortunately it
3835;; still has the effect of an unspec_volatile.
3836(define_insn "cris_frame_deallocated_barrier"
3837 [(set (mem:BLK (reg:SI CRIS_SP_REGNUM))
3838 (unspec:BLK [(const_int 0)] CRIS_UNSPEC_FRAME_DEALLOC))]
3839 ""
3840 ""
3841 [(set_attr "length" "0")])
3842
0b85d816
HPN
3843;; We expand on casesi so we can use "bound" and "add offset fetched from
3844;; a table to pc" (adds.w [pc+%0.w],pc).
3845
3846;; Note: if you change the "parallel" (or add anything after it) in
3847;; this expansion, you must change the macro ASM_OUTPUT_CASE_END
3848;; accordingly, to add the default case at the end of the jump-table.
3849
45d5d09c 3850(define_expand "cris_casesi_non_v32"
0b85d816
HPN
3851 [(set (match_dup 5) (match_operand:SI 0 "general_operand" ""))
3852 (set (match_dup 6)
3853 (minus:SI (match_dup 5)
3854 (match_operand:SI 1 "const_int_operand" "n")))
3855 (set (match_dup 7)
3856 (umin:SI (match_dup 6)
3857 (match_operand:SI 2 "const_int_operand" "n")))
3858 (parallel
3859 [(set (pc)
3860 (if_then_else
3861 (ltu (match_dup 7) (match_dup 2))
3862 (plus:SI (sign_extend:SI
3863 (mem:HI
3864 (plus:SI (mult:SI (match_dup 7) (const_int 2))
3865 (pc))))
3866 (pc))
3867 (label_ref (match_operand 4 "" ""))))
3868 (use (label_ref (match_operand 3 "" "")))])]
3869 ""
0b85d816
HPN
3870{
3871 operands[2] = plus_constant (operands[2], 1);
3872 operands[5] = gen_reg_rtx (SImode);
3873 operands[6] = gen_reg_rtx (SImode);
3874 operands[7] = gen_reg_rtx (SImode);
22c3c091 3875})
45d5d09c
HPN
3876
3877;; FIXME: Check effect of not JUMP_TABLES_IN_TEXT_SECTION.
3878(define_expand "cris_casesi_v32"
3879 [(set (match_dup 5) (match_operand:SI 0 "general_operand"))
3880 (set (match_dup 6)
3881 (minus:SI (match_dup 5)
3882 (match_operand:SI 1 "const_int_operand")))
3883 (set (match_dup 7)
3884 (umin:SI (match_dup 6)
3885 (match_operand:SI 2 "const_int_operand")))
3886 (set (match_dup 8) (match_dup 11))
3887 (set (match_dup 9)
3888 (plus:SI (mult:SI (match_dup 7) (const_int 2))
3889 (match_dup 8)))
3890 (set (match_dup 10)
3891 (plus:SI (sign_extend:SI (mem:HI (match_dup 9)))
3892 (match_dup 9)))
3893 (parallel
3894 [(set (pc)
3895 (if_then_else
3896 (ltu (unspec [(const_int 0)] CRIS_UNSPEC_CASESI) (match_dup 2))
3897 (match_dup 10)
3898 (label_ref (match_operand 4 "" ""))))
3899 (use (label_ref (match_dup 3)))])]
3900 "TARGET_V32"
3901{
3902 int i;
3903 rtx xlabel = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3904 for (i = 5; i <= 10; i++)
3905 operands[i] = gen_reg_rtx (SImode);
3906 operands[2] = plus_constant (operands[2], 1);
3907
3908 /* Don't forget to decorate labels too, for PIC. */
3909 operands[11] = flag_pic
3910 ? gen_rtx_CONST (Pmode,
3911 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xlabel),
3912 CRIS_UNSPEC_PCREL))
3913 : xlabel;
3914})
3915
3916(define_expand "casesi"
3917 [(match_operand:SI 0 "general_operand")
3918 (match_operand:SI 1 "const_int_operand")
3919 (match_operand:SI 2 "const_int_operand")
3920 (match_operand 3 "" "")
3921 (match_operand 4 "" "")]
3922 ""
3923{
3924 if (TARGET_V32)
3925 emit_insn (gen_cris_casesi_v32 (operands[0], operands[1], operands[2],
3926 operands[3], operands[4]));
3927 else
3928 emit_insn (gen_cris_casesi_non_v32 (operands[0], operands[1], operands[2],
3929 operands[3], operands[4]));
3930 DONE;
3931})
0b85d816
HPN
3932\f
3933;; Split-patterns. Some of them have modes unspecified. This
3934;; should always be ok; if for no other reason sparc.md has it as
3935;; well.
3936;;
3937;; When register_operand is specified for an operand, we can get a
3938;; subreg as well (Axis-990331), so don't just assume that REG_P is true
3939;; for a register_operand and that REGNO can be used as is. It is best to
3940;; guard with REG_P, unless it is worth it to adjust for the subreg case.
3941
3942;; op [rx + 0],ry,rz
3943;; The index to rx is optimized into zero, and gone.
3944
3945;; First, recognize bound [rx],ry,rz; where [rx] is zero-extended,
3946;; and add/sub [rx],ry,rz, with zero or sign-extend on [rx].
3947;; Split this into:
3948;; move ry,rz
3949;; op [rx],rz
3950;; Lose if rz=ry or rx=rz.
45d5d09c
HPN
3951;; Call this op-extend-split.
3952;; Do not match for V32; the addo and addi shouldn't be split
3953;; up.
0b85d816
HPN
3954
3955(define_split
3956 [(set (match_operand 0 "register_operand" "")
3957 (match_operator
3958 4 "cris_operand_extend_operator"
3959 [(match_operand 1 "register_operand" "")
3960 (match_operator
3961 3 "cris_extend_operator"
3962 [(match_operand 2 "memory_operand" "")])]))]
45d5d09c
HPN
3963 "!TARGET_V32
3964 && REG_P (operands[0])
0b85d816
HPN
3965 && REG_P (operands[1])
3966 && REGNO (operands[1]) != REGNO (operands[0])
3967 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3968 && REG_P (XEXP (operands[2], 0))
3969 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
3970 [(set (match_dup 0)
3971 (match_dup 1))
3972 (set (match_dup 0)
3973 (match_op_dup
3974 4 [(match_dup 0)
3975 (match_op_dup 3 [(match_dup 2)])]))]
3976 "")
3977
3978;; As op-extend-split, but recognize and split op [rz],ry,rz into
3979;; ext [rz],rz
3980;; op ry,rz
3981;; Do this for plus or bound only, being commutative operations, since we
3982;; have swapped the operands.
3983;; Call this op-extend-split-rx=rz
3984
3985(define_split
3986 [(set (match_operand 0 "register_operand" "")
3987 (match_operator
3988 4 "cris_plus_or_bound_operator"
3989 [(match_operand 1 "register_operand" "")
3990 (match_operator
3991 3 "cris_extend_operator"
3992 [(match_operand 2 "memory_operand" "")])]))]
45d5d09c
HPN
3993 "!TARGET_V32
3994 && REG_P (operands[0])
0b85d816
HPN
3995 && REG_P (operands[1])
3996 && REGNO (operands[1]) != REGNO (operands[0])
3997 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3998 && REG_P (XEXP (operands[2], 0))
3999 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4000 [(set (match_dup 0)
4001 (match_op_dup 3 [(match_dup 2)]))
4002 (set (match_dup 0)
4003 (match_op_dup
4004 4 [(match_dup 0)
4005 (match_dup 1)]))]
4006 "")
4007
4008;; As the op-extend-split, but swapped operands, and only for
4009;; plus or bound, being the commutative extend-operators. FIXME: Why is
4010;; this needed? Is it?
4011;; Call this op-extend-split-swapped
4012
4013(define_split
4014 [(set (match_operand 0 "register_operand" "")
4015 (match_operator
4016 4 "cris_plus_or_bound_operator"
4017 [(match_operator
4018 3 "cris_extend_operator"
4019 [(match_operand 2 "memory_operand" "")])
4020 (match_operand 1 "register_operand" "")]))]
45d5d09c
HPN
4021 "!TARGET_V32
4022 && REG_P (operands[0])
0b85d816
HPN
4023 && REG_P (operands[1])
4024 && REGNO (operands[1]) != REGNO (operands[0])
4025 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4026 && REG_P (XEXP (operands[2], 0))
4027 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4028 [(set (match_dup 0)
4029 (match_dup 1))
4030 (set (match_dup 0)
4031 (match_op_dup
4032 4 [(match_dup 0)
4033 (match_op_dup 3 [(match_dup 2)])]))]
4034 "")
4035
4036;; As op-extend-split-rx=rz, but swapped operands, only for plus or
4037;; bound. Call this op-extend-split-swapped-rx=rz.
4038
4039(define_split
4040 [(set (match_operand 0 "register_operand" "")
4041 (match_operator
4042 4 "cris_plus_or_bound_operator"
4043 [(match_operator
4044 3 "cris_extend_operator"
4045 [(match_operand 2 "memory_operand" "")])
4046 (match_operand 1 "register_operand" "")]))]
45d5d09c
HPN
4047 "!TARGET_V32
4048 && REG_P (operands[0])
0b85d816
HPN
4049 && REG_P (operands[1])
4050 && REGNO (operands[1]) != REGNO (operands[0])
4051 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4052 && REG_P (XEXP (operands[2], 0))
4053 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4054 [(set (match_dup 0)
4055 (match_op_dup 3 [(match_dup 2)]))
4056 (set (match_dup 0)
4057 (match_op_dup
4058 4 [(match_dup 0)
4059 (match_dup 1)]))]
4060 "")
4061
4062;; As op-extend-split, but the mem operand is not extended.
4063;;
4064;; op [rx],ry,rz changed into
4065;; move ry,rz
4066;; op [rx],rz
4067;; lose if ry=rz or rx=rz
4068;; Call this op-extend.
4069
4070(define_split
4071 [(set (match_operand 0 "register_operand" "")
4072 (match_operator
4073 3 "cris_orthogonal_operator"
4074 [(match_operand 1 "register_operand" "")
4075 (match_operand 2 "memory_operand" "")]))]
45d5d09c
HPN
4076 "!TARGET_V32
4077 && REG_P (operands[0])
0b85d816
HPN
4078 && REG_P (operands[1])
4079 && REGNO (operands[1]) != REGNO (operands[0])
4080 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4081 && REG_P (XEXP (operands[2], 0))
4082 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4083 [(set (match_dup 0)
4084 (match_dup 1))
4085 (set (match_dup 0)
4086 (match_op_dup
4087 3 [(match_dup 0)
4088 (match_dup 2)]))]
4089 "")
4090
4091;; As op-extend-split-rx=rz, non-extended.
4092;; Call this op-split-rx=rz
4093
4094(define_split
4095 [(set (match_operand 0 "register_operand" "")
4096 (match_operator
4097 3 "cris_commutative_orth_op"
4098 [(match_operand 2 "memory_operand" "")
4099 (match_operand 1 "register_operand" "")]))]
45d5d09c
HPN
4100 "!TARGET_V32
4101 && REG_P (operands[0])
0b85d816
HPN
4102 && REG_P (operands[1])
4103 && REGNO (operands[1]) != REGNO (operands[0])
4104 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4105 && REG_P (XEXP (operands[2], 0))
4106 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4107 [(set (match_dup 0)
4108 (match_dup 1))
4109 (set (match_dup 0)
4110 (match_op_dup
4111 3 [(match_dup 0)
4112 (match_dup 2)]))]
4113 "")
4114
4115;; As op-extend-split-swapped, nonextended.
4116;; Call this op-split-swapped.
4117
4118(define_split
4119 [(set (match_operand 0 "register_operand" "")
4120 (match_operator
4121 3 "cris_commutative_orth_op"
4122 [(match_operand 1 "register_operand" "")
4123 (match_operand 2 "memory_operand" "")]))]
45d5d09c
HPN
4124 "!TARGET_V32
4125 && REG_P (operands[0]) && REG_P (operands[1])
0b85d816
HPN
4126 && REGNO (operands[1]) != REGNO (operands[0])
4127 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4128 && REG_P (XEXP (operands[2], 0))
4129 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4130 [(set (match_dup 0)
4131 (match_dup 2))
4132 (set (match_dup 0)
4133 (match_op_dup
4134 3 [(match_dup 0)
4135 (match_dup 1)]))]
4136 "")
4137
4138;; As op-extend-split-swapped-rx=rz, non-extended.
4139;; Call this op-split-swapped-rx=rz.
4140
4141(define_split
4142 [(set (match_operand 0 "register_operand" "")
4143 (match_operator
4144 3 "cris_orthogonal_operator"
4145 [(match_operand 2 "memory_operand" "")
4146 (match_operand 1 "register_operand" "")]))]
45d5d09c
HPN
4147 "!TARGET_V32
4148 && REG_P (operands[0]) && REG_P (operands[1])
0b85d816
HPN
4149 && REGNO (operands[1]) != REGNO (operands[0])
4150 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4151 && REG_P (XEXP (operands[2], 0))
4152 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4153 [(set (match_dup 0)
4154 (match_dup 2))
4155 (set (match_dup 0)
4156 (match_op_dup
4157 3 [(match_dup 0)
4158 (match_dup 1)]))]
4159 "")
4160\f
4161;; Splits for all cases in side-effect insns where (possibly after reload
4162;; and register allocation) rx and ry in [rx=ry+i] are equal.
4163
4164;; move.S1 [rx=rx+rz.S2],ry
4165
4166(define_split
4167 [(parallel
4168 [(set (match_operand 0 "register_operand" "")
dbb138ce
HPN
4169 (match_operator
4170 6 "cris_mem_op"
4171 [(plus:SI
4172 (mult:SI (match_operand:SI 1 "register_operand" "")
4173 (match_operand:SI 2 "const_int_operand" ""))
4174 (match_operand:SI 3 "register_operand" ""))]))
0b85d816 4175 (set (match_operand:SI 4 "register_operand" "")
8ad46d34
HPN
4176 (plus:SI (mult:SI (match_dup 1)
4177 (match_dup 2))
0b85d816
HPN
4178 (match_dup 3)))])]
4179 "REG_P (operands[3]) && REG_P (operands[4])
4180 && REGNO (operands[3]) == REGNO (operands[4])"
4181 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
8ad46d34 4182 (match_dup 3)))
0b85d816 4183 (set (match_dup 0) (match_dup 5))]
dbb138ce 4184 "operands[5] = replace_equiv_address (operands[6], operands[3]);")
0b85d816
HPN
4185
4186;; move.S1 [rx=rx+i],ry
4187
4188(define_split
4189 [(parallel
4190 [(set (match_operand 0 "register_operand" "")
dbb138ce
HPN
4191 (match_operator
4192 5 "cris_mem_op"
4193 [(plus:SI (match_operand:SI 1 "cris_bdap_operand" "")
4194 (match_operand:SI 2 "cris_bdap_operand" ""))]))
0b85d816
HPN
4195 (set (match_operand:SI 3 "register_operand" "")
4196 (plus:SI (match_dup 1)
4197 (match_dup 2)))])]
4198 "(rtx_equal_p (operands[3], operands[1])
4199 || rtx_equal_p (operands[3], operands[2]))"
4200 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))
4201 (set (match_dup 0) (match_dup 4))]
7faa3eb8
HPN
4202{
4203 operands[4] = replace_equiv_address (operands[5], operands[3]);
4204 cris_order_for_addsi3 (operands, 1);
4205})
0b85d816
HPN
4206
4207;; move.S1 ry,[rx=rx+rz.S2]
4208
4209(define_split
4210 [(parallel
dbb138ce
HPN
4211 [(set (match_operator
4212 6 "cris_mem_op"
4213 [(plus:SI
4214 (mult:SI (match_operand:SI 0 "register_operand" "")
4215 (match_operand:SI 1 "const_int_operand" ""))
4216 (match_operand:SI 2 "register_operand" ""))])
4217 (match_operand 3 "register_operand" ""))
0b85d816
HPN
4218 (set (match_operand:SI 4 "register_operand" "")
4219 (plus:SI (mult:SI (match_dup 0)
4220 (match_dup 1))
4221 (match_dup 2)))])]
4222 "REG_P (operands[2]) && REG_P (operands[4])
4223 && REGNO (operands[4]) == REGNO (operands[2])"
4224 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
4225 (match_dup 2)))
4226 (set (match_dup 5) (match_dup 3))]
dbb138ce 4227 "operands[5] = replace_equiv_address (operands[6], operands[4]);")
0b85d816
HPN
4228
4229;; move.S1 ry,[rx=rx+i]
4230
4231(define_split
4232 [(parallel
dbb138ce
HPN
4233 [(set (match_operator
4234 6 "cris_mem_op"
4235 [(plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
4236 (match_operand:SI 1 "cris_bdap_operand" ""))])
4237 (match_operand 2 "register_operand" ""))
0b85d816
HPN
4238 (set (match_operand:SI 3 "register_operand" "")
4239 (plus:SI (match_dup 0)
4240 (match_dup 1)))])]
4241 "(rtx_equal_p (operands[3], operands[0])
4242 || rtx_equal_p (operands[3], operands[1]))"
4243 [(set (match_dup 3) (plus:SI (match_dup 0) (match_dup 1)))
4244 (set (match_dup 5) (match_dup 2))]
7faa3eb8
HPN
4245{
4246 operands[5] = replace_equiv_address (operands[6], operands[3]);
4247 cris_order_for_addsi3 (operands, 0);
4248})
0b85d816 4249
22c3c091 4250;; clear.[bwd] [rx=rx+rz.S2]
0b85d816
HPN
4251
4252(define_split
4253 [(parallel
22c3c091 4254 [(set (mem:BWD (plus:SI
0b85d816
HPN
4255 (mult:SI (match_operand:SI 0 "register_operand" "")
4256 (match_operand:SI 1 "const_int_operand" ""))
4257 (match_operand:SI 2 "register_operand" "")))
4258 (const_int 0))
4259 (set (match_operand:SI 3 "register_operand" "")
4260 (plus:SI (mult:SI (match_dup 0)
4261 (match_dup 1))
4262 (match_dup 2)))])]
4263 "REG_P (operands[2]) && REG_P (operands[3])
4264 && REGNO (operands[3]) == REGNO (operands[2])"
4265 [(set (match_dup 3) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
4266 (match_dup 2)))
22c3c091 4267 (set (mem:BWD (match_dup 3)) (const_int 0))]
0b85d816
HPN
4268 "")
4269
22c3c091 4270;; clear.[bwd] [rx=rx+i]
0b85d816
HPN
4271
4272(define_split
4273 [(parallel
22c3c091 4274 [(set (mem:BWD
0b85d816
HPN
4275 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
4276 (match_operand:SI 1 "cris_bdap_operand" "")))
4277 (const_int 0))
4278 (set (match_operand:SI 2 "register_operand" "")
4279 (plus:SI (match_dup 0)
4280 (match_dup 1)))])]
4281 "(rtx_equal_p (operands[0], operands[2])
4282 || rtx_equal_p (operands[2], operands[1]))"
4283 [(set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))
22c3c091 4284 (set (mem:BWD (match_dup 2)) (const_int 0))]
7faa3eb8 4285 "cris_order_for_addsi3 (operands, 0);")
0b85d816
HPN
4286
4287;; mov(s|u).S1 [rx=rx+rz.S2],ry
4288
4289(define_split
4290 [(parallel
4291 [(set (match_operand 0 "register_operand" "")
4292 (match_operator
4293 5 "cris_extend_operator"
4294 [(mem (plus:SI
4295 (mult:SI (match_operand:SI 1 "register_operand" "")
4296 (match_operand:SI 2 "const_int_operand" ""))
4297 (match_operand:SI 3 "register_operand" "")))]))
4298 (set (match_operand:SI 4 "register_operand" "")
4299 (plus:SI (mult:SI (match_dup 1)
4300 (match_dup 2))
4301 (match_dup 3)))])]
4302 "REG_P (operands[3])
4303 && REG_P (operands[4])
4304 && REGNO (operands[3]) == REGNO (operands[4])"
4305 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
4306 (match_dup 3)))
4307 (set (match_dup 0) (match_op_dup 5 [(match_dup 6)]))]
dbb138ce 4308 "operands[6] = replace_equiv_address (XEXP (operands[5], 0), operands[4]);")
0b85d816
HPN
4309
4310;; mov(s|u).S1 [rx=rx+i],ry
4311
4312(define_split
4313 [(parallel
4314 [(set (match_operand 0 "register_operand" "")
4315 (match_operator
4316 4 "cris_extend_operator"
4317 [(mem (plus:SI
4318 (match_operand:SI 1 "cris_bdap_operand" "")
4319 (match_operand:SI 2 "cris_bdap_operand" "")))]))
4320 (set (match_operand:SI 3 "register_operand" "")
4321 (plus:SI (match_dup 1)
4322 (match_dup 2)))])]
4323 "(rtx_equal_p (operands[1], operands[3])
4324 || rtx_equal_p (operands[2], operands[3]))"
4325 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))
4326 (set (match_dup 0) (match_op_dup 4 [(match_dup 5)]))]
7faa3eb8
HPN
4327{
4328 operands[5] = replace_equiv_address (XEXP (operands[4], 0), operands[3]);
4329 cris_order_for_addsi3 (operands, 1);
4330})
0b85d816
HPN
4331
4332;; op.S1 [rx=rx+i],ry
4333
4334(define_split
4335 [(parallel
4336 [(set (match_operand 0 "register_operand" "")
4337 (match_operator
4338 5 "cris_orthogonal_operator"
4339 [(match_operand 1 "register_operand" "")
4340 (mem (plus:SI
4341 (match_operand:SI 2 "cris_bdap_operand" "")
4342 (match_operand:SI 3 "cris_bdap_operand" "")))]))
4343 (set (match_operand:SI 4 "register_operand" "")
4344 (plus:SI (match_dup 2)
4345 (match_dup 3)))])]
4346 "(rtx_equal_p (operands[4], operands[2])
4347 || rtx_equal_p (operands[4], operands[3]))"
4348 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4349 (set (match_dup 0) (match_op_dup 5 [(match_dup 1) (match_dup 6)]))]
7faa3eb8
HPN
4350{
4351 operands[6] = replace_equiv_address (XEXP (operands[5], 1), operands[4]);
4352 cris_order_for_addsi3 (operands, 2);
4353})
0b85d816
HPN
4354
4355;; op.S1 [rx=rx+rz.S2],ry
4356
4357(define_split
4358 [(parallel
4359 [(set (match_operand 0 "register_operand" "")
4360 (match_operator
4361 6 "cris_orthogonal_operator"
4362 [(match_operand 1 "register_operand" "")
4363 (mem (plus:SI
4364 (mult:SI (match_operand:SI 2 "register_operand" "")
4365 (match_operand:SI 3 "const_int_operand" ""))
4366 (match_operand:SI 4 "register_operand" "")))]))
4367 (set (match_operand:SI 5 "register_operand" "")
4368 (plus:SI (mult:SI (match_dup 2)
4369 (match_dup 3))
4370 (match_dup 4)))])]
4371 "REG_P (operands[4])
4372 && REG_P (operands[5])
4373 && REGNO (operands[5]) == REGNO (operands[4])"
4374 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4375 (match_dup 4)))
4376 (set (match_dup 0) (match_op_dup 6 [(match_dup 1) (match_dup 7)]))]
dbb138ce 4377 "operands[7] = replace_equiv_address (XEXP (operands[6], 1), operands[5]);")
0b85d816
HPN
4378
4379;; op.S1 [rx=rx+rz.S2],ry (swapped)
4380
4381(define_split
4382 [(parallel
4383 [(set (match_operand 0 "register_operand" "")
4384 (match_operator
4385 6 "cris_commutative_orth_op"
4386 [(mem (plus:SI
4387 (mult:SI (match_operand:SI 2 "register_operand" "")
4388 (match_operand:SI 3 "const_int_operand" ""))
4389 (match_operand:SI 4 "register_operand" "")))
4390 (match_operand 1 "register_operand" "")]))
4391 (set (match_operand:SI 5 "register_operand" "")
4392 (plus:SI (mult:SI (match_dup 2)
4393 (match_dup 3))
4394 (match_dup 4)))])]
4395 "REG_P (operands[4])
4396 && REG_P (operands[5])
4397 && REGNO (operands[5]) == REGNO (operands[4])"
4398 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4399 (match_dup 4)))
4400 (set (match_dup 0) (match_op_dup 6 [(match_dup 7) (match_dup 1)]))]
dbb138ce 4401 "operands[7] = replace_equiv_address (XEXP (operands[6], 0), operands[5]);")
0b85d816
HPN
4402
4403;; op.S1 [rx=rx+i],ry (swapped)
4404
4405(define_split
4406 [(parallel
4407 [(set (match_operand 0 "register_operand" "")
4408 (match_operator
4409 5 "cris_commutative_orth_op"
4410 [(mem
4411 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "")
4412 (match_operand:SI 3 "cris_bdap_operand" "")))
4413 (match_operand 1 "register_operand" "")]))
4414 (set (match_operand:SI 4 "register_operand" "")
4415 (plus:SI (match_dup 2)
4416 (match_dup 3)))])]
4417 "(rtx_equal_p (operands[4], operands[2])
4418 || rtx_equal_p (operands[4], operands[3]))"
4419 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4420 (set (match_dup 0) (match_op_dup 5 [(match_dup 6) (match_dup 1)]))]
7faa3eb8
HPN
4421{
4422 operands[6] = replace_equiv_address (XEXP (operands[5], 0), operands[4]);
4423 cris_order_for_addsi3 (operands, 2);
4424})
0b85d816
HPN
4425
4426;; op(s|u).S1 [rx=rx+rz.S2],ry
4427
4428(define_split
4429 [(parallel
4430 [(set (match_operand 0 "register_operand" "")
4431 (match_operator
4432 6 "cris_operand_extend_operator"
4433 [(match_operand 1 "register_operand" "")
4434 (match_operator
4435 7 "cris_extend_operator"
4436 [(mem (plus:SI
4437 (mult:SI (match_operand:SI 2 "register_operand" "")
4438 (match_operand:SI 3 "const_int_operand" ""))
4439 (match_operand:SI 4 "register_operand" "")))])]))
4440 (set (match_operand:SI 5 "register_operand" "")
4441 (plus:SI (mult:SI (match_dup 2)
4442 (match_dup 3))
4443 (match_dup 4)))])]
4444 "REG_P (operands[4])
4445 && REG_P (operands[5])
4446 && REGNO (operands[5]) == REGNO (operands[4])"
4447 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4448 (match_dup 4)))
4449 (set (match_dup 0) (match_op_dup 6 [(match_dup 1) (match_dup 8)]))]
1c563bed 4450 "operands[8] = gen_rtx_fmt_e (GET_CODE (operands[7]), GET_MODE (operands[7]),
0f4c242b
KH
4451 replace_equiv_address (XEXP (operands[7], 0),
4452 operands[5]));")
0b85d816
HPN
4453
4454;; op(s|u).S1 [rx=rx+i],ry
4455
4456(define_split
4457 [(parallel
4458 [(set (match_operand 0 "register_operand" "")
4459 (match_operator
4460 5 "cris_operand_extend_operator"
4461 [(match_operand 1 "register_operand" "")
4462 (match_operator
4463 6 "cris_extend_operator"
4464 [(mem
4465 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "")
4466 (match_operand:SI 3 "cris_bdap_operand" "")
4467 ))])]))
4468 (set (match_operand:SI 4 "register_operand" "")
4469 (plus:SI (match_dup 2)
4470 (match_dup 3)))])]
4471 "(rtx_equal_p (operands[4], operands[2])
4472 || rtx_equal_p (operands[4], operands[3]))"
4473 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4474 (set (match_dup 0) (match_op_dup 5 [(match_dup 1) (match_dup 7)]))]
7faa3eb8
HPN
4475{
4476 operands[7] = gen_rtx_fmt_e (GET_CODE (operands[6]), GET_MODE (operands[6]),
4477 replace_equiv_address (XEXP (operands[6], 0),
4478 operands[4]));
4479 cris_order_for_addsi3 (operands, 2);
4480})
0b85d816
HPN
4481
4482;; op(s|u).S1 [rx=rx+rz.S2],ry (swapped, plus or bound)
4483
4484(define_split
4485 [(parallel
4486 [(set (match_operand 0 "register_operand" "")
4487 (match_operator
4488 7 "cris_plus_or_bound_operator"
4489 [(match_operator
4490 6 "cris_extend_operator"
4491 [(mem (plus:SI
4492 (mult:SI (match_operand:SI 2 "register_operand" "")
4493 (match_operand:SI 3 "const_int_operand" ""))
4494 (match_operand:SI 4 "register_operand" "")))])
4495 (match_operand 1 "register_operand" "")]))
4496 (set (match_operand:SI 5 "register_operand" "")
4497 (plus:SI (mult:SI (match_dup 2)
4498 (match_dup 3))
4499 (match_dup 4)))])]
4500 "REG_P (operands[4]) && REG_P (operands[5])
4501 && REGNO (operands[5]) == REGNO (operands[4])"
4502 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4503 (match_dup 4)))
4504 (set (match_dup 0) (match_op_dup 6 [(match_dup 8) (match_dup 1)]))]
1c563bed 4505 "operands[8] = gen_rtx_fmt_e (GET_CODE (operands[6]), GET_MODE (operands[6]),
0f4c242b
KH
4506 replace_equiv_address (XEXP (operands[6], 0),
4507 operands[5]));")
0b85d816
HPN
4508
4509;; op(s|u).S1 [rx=rx+i],ry (swapped, plus or bound)
4510
4511(define_split
4512 [(parallel
4513 [(set (match_operand 0 "register_operand" "")
4514 (match_operator
4515 6 "cris_plus_or_bound_operator"
4516 [(match_operator
4517 5 "cris_extend_operator"
4518 [(mem (plus:SI
4519 (match_operand:SI 2 "cris_bdap_operand" "")
4520 (match_operand:SI 3 "cris_bdap_operand" "")))])
4521 (match_operand 1 "register_operand" "")]))
4522 (set (match_operand:SI 4 "register_operand" "")
4523 (plus:SI (match_dup 2)
4524 (match_dup 3)))])]
4525 "(rtx_equal_p (operands[4], operands[2])
4526 || rtx_equal_p (operands[4], operands[3]))"
4527 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4528 (set (match_dup 0) (match_op_dup 6 [(match_dup 7) (match_dup 1)]))]
7faa3eb8
HPN
4529{
4530 operands[7] = gen_rtx_fmt_e (GET_CODE (operands[5]), GET_MODE (operands[5]),
4531 replace_equiv_address (XEXP (operands[5], 0),
4532 operands[4]));
4533 cris_order_for_addsi3 (operands, 2);
4534})
0b85d816
HPN
4535\f
4536;; Splits for addressing prefixes that have no side-effects, so we can
4537;; fill a delay slot. Never split if we lose something, though.
4538
4539;; If we have a
4540;; move [indirect_ref],rx
4541;; where indirect ref = {const, [r+], [r]}, it costs as much as
4542;; move indirect_ref,rx
4543;; move [rx],rx
4544;; Take care not to allow indirect_ref = register.
4545
4546;; We're not allowed to generate copies of registers with different mode
4547;; until after reload; copying pseudos upsets reload. CVS as of
4548;; 2001-08-24, unwind-dw2-fde.c, _Unwind_Find_FDE ICE in
4549;; cselib_invalidate_regno.
4550
f60c7155 4551(define_split ; indir_to_reg_split
0b85d816
HPN
4552 [(set (match_operand 0 "register_operand" "")
4553 (match_operand 1 "indirect_operand" ""))]
4554 "reload_completed
4555 && REG_P (operands[0])
4556 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
991c42ac 4557 && (MEM_P (XEXP (operands[1], 0)) || CONSTANT_P (XEXP (operands[1], 0)))
f60c7155 4558 && REGNO (operands[0]) < CRIS_LAST_GENERAL_REGISTER"
0b85d816
HPN
4559 [(set (match_dup 2) (match_dup 4))
4560 (set (match_dup 0) (match_dup 3))]
4561 "operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
dbb138ce 4562 operands[3] = replace_equiv_address (operands[1], operands[2]);
0b85d816
HPN
4563 operands[4] = XEXP (operands[1], 0);")
4564
4565;; As the above, but MOVS and MOVU.
4566
4567(define_split
4568 [(set (match_operand 0 "register_operand" "")
4569 (match_operator
4570 4 "cris_extend_operator"
4571 [(match_operand 1 "indirect_operand" "")]))]
4572 "reload_completed
4573 && REG_P (operands[0])
4574 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
991c42ac 4575 && (MEM_P (XEXP (operands[1], 0))
0b85d816
HPN
4576 || CONSTANT_P (XEXP (operands[1], 0)))"
4577 [(set (match_dup 2) (match_dup 5))
4578 (set (match_dup 0) (match_op_dup 4 [(match_dup 3)]))]
4579 "operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
dbb138ce 4580 operands[3] = replace_equiv_address (XEXP (operands[4], 0), operands[2]);
0b85d816
HPN
4581 operands[5] = XEXP (operands[1], 0);")
4582\f
4583;; Various peephole optimizations.
4584;;
4585;; Watch out: when you exchange one set of instructions for another, the
4586;; condition codes setting must be the same, or you have to CC_INIT or
4587;; whatever is appropriate, in the pattern before you emit the
4588;; assembly text. This is best done here, not in cris_notice_update_cc,
4589;; to keep changes local to their cause.
4590;;
4591;; Do not add patterns that you do not know will be matched.
109b748d 4592;; Please also add a self-contained testcase.
0b85d816
HPN
4593
4594;; We have trouble with and:s and shifts. Maybe something is broken in
43a88a8c 4595;; gcc? Or it could just be that bit-field insn expansion is a bit
0b85d816 4596;; suboptimal when not having extzv insns.
8ad46d34 4597;; Testcase for the following four peepholes: gcc.dg/cris-peep2-xsrand.c
0b85d816 4598
8ad46d34
HPN
4599(define_peephole2 ; asrandb (peephole casesi+31)
4600 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 4601 (ashiftrt:SI (match_dup 0)
8ad46d34 4602 (match_operand:SI 1 "const_int_operand" "")))
0b85d816
HPN
4603 (set (match_dup 0)
4604 (and:SI (match_dup 0)
8ad46d34 4605 (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
4606 "INTVAL (operands[2]) > 31
4607 && INTVAL (operands[2]) < 255
8ad46d34
HPN
4608 && INTVAL (operands[1]) > 23
4609 /* Check that the and-operation enables us to use logical-shift. */
4610 && (INTVAL (operands[2])
4611 & ((HOST_WIDE_INT) -1 << (32 - INTVAL (operands[1])))) == 0"
4612 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 4613 (set (match_dup 3) (and:QI (match_dup 3) (match_dup 4)))]
8ad46d34 4614 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
4615{
4616 operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));
4617 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), QImode));
4618})
8ad46d34
HPN
4619
4620(define_peephole2 ; asrandw (peephole casesi+32)
4621 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 4622 (ashiftrt:SI (match_dup 0)
8ad46d34 4623 (match_operand:SI 1 "const_int_operand" "")))
0b85d816 4624 (set (match_dup 0)
8ad46d34 4625 (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
4626 "INTVAL (operands[2]) > 31
4627 && INTVAL (operands[2]) < 65535
4628 && INTVAL (operands[2]) != 255
8ad46d34
HPN
4629 && INTVAL (operands[1]) > 15
4630 /* Check that the and-operation enables us to use logical-shift. */
4631 && (INTVAL (operands[2])
4632 & ((HOST_WIDE_INT) -1 << (32 - INTVAL (operands[1])))) == 0"
4633 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 4634 (set (match_dup 3) (and:HI (match_dup 3) (match_dup 4)))]
8ad46d34 4635 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
4636{
4637 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4638 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), HImode));
4639})
8ad46d34
HPN
4640
4641(define_peephole2 ; lsrandb (peephole casesi+33)
4642 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 4643 (lshiftrt:SI (match_dup 0)
8ad46d34 4644 (match_operand:SI 1 "const_int_operand" "")))
0b85d816 4645 (set (match_dup 0)
8ad46d34 4646 (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
4647 "INTVAL (operands[2]) > 31
4648 && INTVAL (operands[2]) < 255
4649 && INTVAL (operands[1]) > 23"
8ad46d34 4650 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 4651 (set (match_dup 3) (and:QI (match_dup 3) (match_dup 4)))]
8ad46d34 4652 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
4653{
4654 operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));
4655 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), QImode));
4656})
0b85d816 4657
8ad46d34
HPN
4658(define_peephole2 ; lsrandw (peephole casesi+34)
4659 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 4660 (lshiftrt:SI (match_dup 0)
8ad46d34 4661 (match_operand:SI 1 "const_int_operand" "")))
0b85d816 4662 (set (match_dup 0)
8ad46d34 4663 (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
4664 "INTVAL (operands[2]) > 31 && INTVAL (operands[2]) < 65535
4665 && INTVAL (operands[2]) != 255
4666 && INTVAL (operands[1]) > 15"
8ad46d34 4667 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 4668 (set (match_dup 3) (and:HI (match_dup 3) (match_dup 4)))]
8ad46d34 4669 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
4670{
4671 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4672 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), HImode));
4673})
0b85d816
HPN
4674\f
4675
4676;; Change
4677;; add.d n,rx
4678;; move [rx],ry
4679;; into
4680;; move [rx=rx+n],ry
4681;; when -128 <= n <= 127.
4682;; This will reduce the size of the assembler code for n = [-128..127],
8ad46d34
HPN
4683;; and speed up accordingly. Don't match if the previous insn is
4684;; (set rx rz) because that combination is matched by another peephole.
4685;; No stable test-case.
4686
4687(define_peephole2 ; moversideqi (peephole casesi+35)
4688 [(set (match_operand:SI 0 "register_operand" "")
4689 (plus:SI (match_operand:SI 1 "register_operand" "")
4690 (match_operand:SI 2 "const_int_operand" "")))
4691 (set (match_operand 3 "register_operand" "")
4692 (match_operator 4 "cris_mem_op" [(match_dup 0)]))]
4693 "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
4694 && REGNO (operands[3]) != REGNO (operands[0])
a08160c3 4695 && (cris_base_p (operands[1], true) || cris_base_p (operands[2], true))
06cadf63
AS
4696 && !satisfies_constraint_J (operands[2])
4697 && !satisfies_constraint_N (operands[2])
45d5d09c
HPN
4698 && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)
4699 && TARGET_SIDE_EFFECT_PREFIXES"
8ad46d34
HPN
4700 [(parallel
4701 [(set (match_dup 3) (match_dup 5))
4702 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
4703 ;; Checking the previous insn is a bit too awkward for the condition.
4704{
4705 rtx prev = prev_nonnote_insn (curr_insn);
4706 if (prev != NULL_RTX)
4707 {
4708 rtx set = single_set (prev);
4709 if (set != NULL_RTX
4710 && REG_S_P (SET_DEST (set))
4711 && REGNO (SET_DEST (set)) == REGNO (operands[0])
4712 && REG_S_P (SET_SRC (set)))
4713 FAIL;
4714 }
4715 operands[5]
4716 = replace_equiv_address (operands[4],
4717 gen_rtx_PLUS (SImode,
4718 operands[1], operands[2]));
4719})
0b85d816
HPN
4720
4721;; Vice versa: move ry,[rx=rx+n]
4722
8ad46d34
HPN
4723(define_peephole2 ; movemsideqi (peephole casesi+36)
4724 [(set (match_operand:SI 0 "register_operand" "")
4725 (plus:SI (match_operand:SI 1 "register_operand" "")
4726 (match_operand:SI 2 "const_int_operand" "")))
4727 (set (match_operator 3 "cris_mem_op" [(match_dup 0)])
4728 (match_operand 4 "register_operand" ""))]
4729 "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
4730 && REGNO (operands[4]) != REGNO (operands[0])
a08160c3 4731 && (cris_base_p (operands[1], true) || cris_base_p (operands[2], true))
06cadf63
AS
4732 && !satisfies_constraint_J (operands[2])
4733 && !satisfies_constraint_N (operands[2])
45d5d09c
HPN
4734 && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)
4735 && TARGET_SIDE_EFFECT_PREFIXES"
8ad46d34
HPN
4736 [(parallel
4737 [(set (match_dup 5) (match_dup 4))
4738 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
4739 "operands[5]
4740 = replace_equiv_address (operands[3],
4741 gen_rtx_PLUS (SImode,
4742 operands[1], operands[2]));")
0b85d816
HPN
4743\f
4744;; As above, change:
4745;; add.d n,rx
4746;; op.d [rx],ry
4747;; into:
4748;; op.d [rx=rx+n],ry
4749;; Saves when n = [-128..127].
4750;;
4751;; Splitting and joining combinations for side-effect modes are slightly
4752;; out of hand. They probably will not save the time they take typing in,
4753;; not to mention the bugs that creep in. FIXME: Get rid of as many of
4754;; the splits and peepholes as possible.
8ad46d34
HPN
4755;; No stable test-case.
4756
4757(define_peephole2 ; mover2side (peephole casesi+37)
4758 [(set (match_operand:SI 0 "register_operand" "")
4759 (plus:SI (match_operand:SI 1 "register_operand" "")
4760 (match_operand:SI 2 "const_int_operand" "")))
4761 (set (match_operand 3 "register_operand" "")
4762 (match_operator 4 "cris_orthogonal_operator"
4763 [(match_dup 3)
4764 (match_operator
4765 5 "cris_mem_op" [(match_dup 0)])]))]
477c433d
HPN
4766 ;; FIXME: What about DFmode?
4767 ;; Change to GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD?
0b85d816 4768 "GET_MODE (operands[3]) != DImode
8ad46d34 4769 && REGNO (operands[0]) != REGNO (operands[3])
06cadf63
AS
4770 && !satisfies_constraint_J (operands[2])
4771 && !satisfies_constraint_N (operands[2])
8ad46d34 4772 && INTVAL (operands[2]) >= -128
45d5d09c
HPN
4773 && INTVAL (operands[2]) <= 127
4774 && TARGET_SIDE_EFFECT_PREFIXES"
8ad46d34
HPN
4775 [(parallel
4776 [(set (match_dup 3) (match_op_dup 4 [(match_dup 3) (match_dup 6)]))
4777 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
4778 "operands[6]
4779 = replace_equiv_address (operands[5],
4780 gen_rtx_PLUS (SImode,
4781 operands[1], operands[2]));")
0b85d816
HPN
4782
4783;; Sometimes, for some reason the pattern
4784;; move x,rx
4785;; add y,rx
4786;; move [rx],rz
4787;; will occur. Solve this, and likewise for to-memory.
8ad46d34 4788;; No stable test-case.
0b85d816 4789
8ad46d34
HPN
4790(define_peephole2 ; moverside (peephole casesi+38)
4791 [(set (match_operand:SI 0 "register_operand" "")
4792 (match_operand:SI 1 "cris_bdap_biap_operand" ""))
0b85d816 4793 (set (match_dup 0)
8ad46d34
HPN
4794 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "")
4795 (match_operand:SI 3 "cris_bdap_biap_operand" "")))
4796 (set (match_operand 4 "register_operand" "")
4797 (match_operator 5 "cris_mem_op" [(match_dup 0)]))]
0b85d816
HPN
4798 "(rtx_equal_p (operands[2], operands[0])
4799 || rtx_equal_p (operands[3], operands[0]))
4800 && cris_side_effect_mode_ok (PLUS, operands, 0,
8ad46d34
HPN
4801 (REG_S_P (operands[1])
4802 ? 1
4803 : (rtx_equal_p (operands[2], operands[0])
4804 ? 3 : 2)),
4805 (! REG_S_P (operands[1])
4806 ? 1
4807 : (rtx_equal_p (operands[2], operands[0])
4808 ? 3 : 2)),
4809 -1, 4)"
4810 [(parallel
4811 [(set (match_dup 4) (match_dup 6))
4812 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 8)))])]
4813{
e758023d 4814 rtx otherop
8ad46d34
HPN
4815 = rtx_equal_p (operands[2], operands[0]) ? operands[3] : operands[2];
4816
8820e4be
HPN
4817 /* Make sure we have canonical RTX so we match the insn pattern -
4818 not a constant in the first operand. We also require the order
4819 (plus reg mem) to match the final pattern. */
4820 if (CONSTANT_P (otherop) || MEM_P (otherop))
8ad46d34
HPN
4821 {
4822 operands[7] = operands[1];
e758023d 4823 operands[8] = otherop;
8ad46d34
HPN
4824 }
4825 else
4826 {
e758023d 4827 operands[7] = otherop;
8ad46d34
HPN
4828 operands[8] = operands[1];
4829 }
4830 operands[6]
4831 = replace_equiv_address (operands[5],
4832 gen_rtx_PLUS (SImode,
4833 operands[7], operands[8]));
4834})
0b85d816
HPN
4835
4836;; As above but to memory.
8ad46d34
HPN
4837;; FIXME: Split movemside and moverside into variants and prune
4838;; the ones that don't trig.
4839;; No stable test-case.
0b85d816 4840
8ad46d34
HPN
4841(define_peephole2 ; movemside (peephole casesi+39)
4842 [(set (match_operand:SI 0 "register_operand" "")
4843 (match_operand:SI 1 "cris_bdap_biap_operand" ""))
0b85d816 4844 (set (match_dup 0)
8ad46d34
HPN
4845 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "")
4846 (match_operand:SI 3 "cris_bdap_biap_operand" "")))
4847 (set (match_operator 4 "cris_mem_op" [(match_dup 0)])
4848 (match_operand 5 "register_operand" ""))]
0b85d816
HPN
4849 "(rtx_equal_p (operands[2], operands[0])
4850 || rtx_equal_p (operands[3], operands[0]))
4851 && cris_side_effect_mode_ok (PLUS, operands, 0,
8ad46d34
HPN
4852 (REG_S_P (operands[1])
4853 ? 1
4854 : (rtx_equal_p (operands[2], operands[0])
4855 ? 3 : 2)),
4856 (! REG_S_P (operands[1])
4857 ? 1
4858 : (rtx_equal_p (operands[2], operands[0])
4859 ? 3 : 2)),
4860 -1, 5)"
4861 [(parallel
4862 [(set (match_dup 6) (match_dup 5))
4863 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 8)))])]
4864{
e758023d 4865 rtx otherop
8ad46d34 4866 = rtx_equal_p (operands[2], operands[0]) ? operands[3] : operands[2];
0b85d816 4867
8820e4be
HPN
4868 /* Make sure we have canonical RTX so we match the insn pattern -
4869 not a constant in the first operand. We also require the order
4870 (plus reg mem) to match the final pattern. */
4871 if (CONSTANT_P (otherop) || MEM_P (otherop))
8ad46d34
HPN
4872 {
4873 operands[7] = operands[1];
e758023d 4874 operands[8] = otherop;
8ad46d34
HPN
4875 }
4876 else
4877 {
e758023d 4878 operands[7] = otherop;
8ad46d34
HPN
4879 operands[8] = operands[1];
4880 }
4881 operands[6]
4882 = replace_equiv_address (operands[4],
4883 gen_rtx_PLUS (SImode,
4884 operands[7], operands[8]));
4885})
0b85d816
HPN
4886
4887;; Another spotted bad code:
4888;; move rx,ry
4889;; move [ry],ry
8ad46d34 4890;; No stable test-case.
0b85d816 4891
8ad46d34
HPN
4892(define_peephole2 ; movei (peephole casesi+42)
4893 [(set (match_operand:SI 0 "register_operand" "")
4894 (match_operand:SI 1 "register_operand" ""))
4895 (set (match_operand 2 "register_operand" "")
4896 (match_operator 3 "cris_mem_op" [(match_dup 0)]))]
0b85d816 4897 "REGNO (operands[0]) == REGNO (operands[2])
f60c7155
HPN
4898 && (REGNO_REG_CLASS (REGNO (operands[0]))
4899 == REGNO_REG_CLASS (REGNO (operands[1])))
0b85d816 4900 && GET_MODE_SIZE (GET_MODE (operands[2])) <= UNITS_PER_WORD"
8ad46d34
HPN
4901 [(set (match_dup 2) (match_dup 4))]
4902 "operands[4] = replace_equiv_address (operands[3], operands[1]);")
0b85d816 4903
0b85d816
HPN
4904;; move.d [r10+16],r9
4905;; and.d r12,r9
4906;; change to
4907;; and.d [r10+16],r12,r9
4908;; With generalization of the operation, the size and the addressing mode.
4909;; This seems to be the result of a quirk in register allocation
4910;; missing the three-operand cases when having different predicates.
4911;; Maybe that it matters that it is a commutative operation.
4912;; This pattern helps that situation, but there's still the increased
4913;; register pressure.
4914;; Note that adding the noncommutative variant did not show any matches
4915;; in ipps and cc1, so it's not here.
8ad46d34 4916;; No stable test-case.
0b85d816 4917
8ad46d34
HPN
4918(define_peephole2 ; op3 (peephole casesi+44)
4919 [(set (match_operand 0 "register_operand" "")
4920 (match_operator
4921 6 "cris_mem_op"
4922 [(plus:SI
4923 (match_operand:SI 1 "cris_bdap_biap_operand" "")
4924 (match_operand:SI 2 "cris_bdap_biap_operand" ""))]))
0b85d816 4925 (set (match_dup 0)
8ad46d34
HPN
4926 (match_operator
4927 5 "cris_commutative_orth_op"
4928 [(match_operand 3 "register_operand" "")
4929 (match_operand 4 "register_operand" "")]))]
0b85d816
HPN
4930 "(rtx_equal_p (operands[3], operands[0])
4931 || rtx_equal_p (operands[4], operands[0]))
4932 && ! rtx_equal_p (operands[3], operands[4])
4933 && (REG_S_P (operands[1]) || REG_S_P (operands[2]))
4934 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD"
8ad46d34
HPN
4935 [(set (match_dup 0) (match_op_dup 5 [(match_dup 7) (match_dup 6)]))]
4936 "operands[7]
4937 = rtx_equal_p (operands[3], operands[0]) ? operands[4] : operands[3];")
0b85d816 4938
0b85d816
HPN
4939;; I cannot tell GCC (2.1, 2.7.2) how to correctly reload an instruction
4940;; that looks like
4941;; and.b some_byte,const,reg_32
4942;; where reg_32 is the destination of the "three-address" code optimally.
4943;; It should be:
4944;; movu.b some_byte,reg_32
4945;; and.b const,reg_32
365cacbf 4946;; but it turns into:
0b85d816
HPN
4947;; move.b some_byte,reg_32
4948;; and.d const,reg_32
4949;; Fix it here.
8ad46d34 4950;; Testcases: gcc.dg/cris-peep2-andu1.c gcc.dg/cris-peep2-andu2.c
0b85d816 4951
8ad46d34
HPN
4952(define_peephole2 ; andu (casesi+45)
4953 [(set (match_operand:SI 0 "register_operand" "")
4954 (match_operand:SI 1 "nonimmediate_operand" ""))
4955 (set (match_operand:SI 2 "register_operand" "")
0b85d816 4956 (and:SI (match_dup 0)
8ad46d34 4957 (match_operand:SI 3 "const_int_operand" "")))]
0b85d816
HPN
4958 ;; Since the size of the memory access could be made different here,
4959 ;; don't do this for a mem-volatile access.
0b85d816
HPN
4960 "REGNO (operands[2]) == REGNO (operands[0])
4961 && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
06cadf63 4962 && !satisfies_constraint_I (operands[3])
365cacbf
HPN
4963 && !side_effects_p (operands[1])
4964 && (!REG_P (operands[1])
4965 || REGNO (operands[1]) <= CRIS_LAST_GENERAL_REGISTER)"
8ad46d34
HPN
4966 ;; FIXME: CC0 valid except for M (i.e. CC_NOT_NEGATIVE).
4967 [(set (match_dup 0) (match_dup 4))
4968 (set (match_dup 5) (match_dup 6))]
0b85d816 4969{
8ad46d34
HPN
4970 enum machine_mode zmode = INTVAL (operands[3]) <= 255 ? QImode : HImode;
4971 enum machine_mode amode
06cadf63 4972 = satisfies_constraint_O (operands[3]) ? SImode : zmode;
8ad46d34
HPN
4973 rtx op1
4974 = (REG_S_P (operands[1])
4975 ? gen_rtx_REG (zmode, REGNO (operands[1]))
4976 : adjust_address (operands[1], zmode, 0));
4977 operands[4]
4978 = gen_rtx_ZERO_EXTEND (SImode, op1);
4979 operands[5] = gen_rtx_REG (amode, REGNO (operands[0]));
4980 operands[6]
4981 = gen_rtx_AND (amode, gen_rtx_REG (amode, REGNO (operands[0])),
4982 GEN_INT (trunc_int_for_mode (INTVAL (operands[3]),
4983 amode == SImode
4984 ? QImode : amode)));
4985})
c00fc5cf
HPN
4986
4987;; Try and avoid GOTPLT reads escaping a call: transform them into
4988;; PLT. Curiously (but thankfully), peepholes for instructions
4989;; *without side-effects* that just feed a call (or call_value) are
4990;; not matched neither in a build or test-suite, so those patterns are
4991;; omitted.
4992
4993;; A "normal" move where we don't check the consumer.
4994
4995(define_peephole2 ; gotplt-to-plt
4996 [(set
4997 (match_operand:SI 0 "register_operand" "")
4998 (match_operator:SI
4999 1 "cris_mem_op"
5000 [(plus:SI
5001 (reg:SI CRIS_GOT_REGNUM)
5002 (const:SI
5003 (unspec:SI [(match_operand:SI 2 "cris_general_operand_or_symbol" "")]
5004 CRIS_UNSPEC_PLTGOTREAD)))]))]
5005 "flag_pic
45d5d09c 5006 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
c00fc5cf 5007 && REGNO_REG_CLASS (REGNO (operands[0])) == REGNO_REG_CLASS (0)"
45d5d09c 5008 [(set (match_dup 0) (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLT_GOTREL)))
c00fc5cf
HPN
5009 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI CRIS_GOT_REGNUM)))]
5010 "")
5011
5012;; And one set with a side-effect getting the PLTGOT offset.
5013;; First call and call_value variants.
5014
5015(define_peephole2 ; gotplt-to-plt-side-call
5016 [(parallel
5017 [(set
5018 (match_operand:SI 0 "register_operand" "")
5019 (match_operator:SI
5020 1 "cris_mem_op"
5021 [(plus:SI
5022 (reg:SI CRIS_GOT_REGNUM)
5023 (const:SI
5024 (unspec:SI [(match_operand:SI
5025 2 "cris_general_operand_or_symbol" "")]
5026 CRIS_UNSPEC_PLTGOTREAD)))]))
5027 (set (match_operand:SI 3 "register_operand" "")
5028 (plus:SI (reg:SI CRIS_GOT_REGNUM)
5029 (const:SI
5030 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])
5031 (parallel [(call (mem:QI (match_dup 0))
5032 (match_operand 4 "" ""))
5033 (clobber (reg:SI CRIS_SRP_REGNUM))])]
5034 "flag_pic
45d5d09c 5035 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
c00fc5cf
HPN
5036 && peep2_reg_dead_p (2, operands[0])"
5037 [(parallel [(call (mem:QI (match_dup 1))
5038 (match_dup 4))
5039 (clobber (reg:SI CRIS_SRP_REGNUM))
5040 (set (match_dup 3)
5041 (plus:SI (reg:SI CRIS_GOT_REGNUM)
5042 (const:SI
5043 (unspec:SI [(match_dup 2)]
5044 CRIS_UNSPEC_PLTGOTREAD))))])]
5045 "")
5046
5047(define_peephole2 ; gotplt-to-plt-side-call-value
5048 [(parallel
5049 [(set
5050 (match_operand:SI 0 "register_operand" "")
5051 (match_operator:SI
5052 1 "cris_mem_op"
5053 [(plus:SI
5054 (reg:SI CRIS_GOT_REGNUM)
5055 (const:SI
5056 (unspec:SI [(match_operand:SI
5057 2 "cris_general_operand_or_symbol" "")]
5058 CRIS_UNSPEC_PLTGOTREAD)))]))
5059 (set (match_operand:SI 3 "register_operand" "")
5060 (plus:SI (reg:SI CRIS_GOT_REGNUM)
5061 (const:SI
5062 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])
5063 (parallel [(set (match_operand 5 "" "")
5064 (call (mem:QI (match_dup 0))
5065 (match_operand 4 "" "")))
5066 (clobber (reg:SI CRIS_SRP_REGNUM))])]
5067 "flag_pic
45d5d09c 5068 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
c00fc5cf
HPN
5069 && peep2_reg_dead_p (2, operands[0])"
5070 [(parallel [(set (match_dup 5)
5071 (call (mem:QI (match_dup 1))
5072 (match_dup 4)))
5073 (clobber (reg:SI CRIS_SRP_REGNUM))
5074 (set (match_dup 3)
5075 (plus:SI (reg:SI CRIS_GOT_REGNUM)
5076 (const:SI
5077 (unspec:SI [(match_dup 2)]
5078 CRIS_UNSPEC_PLTGOTREAD))))])]
5079 "")
5080
5081(define_peephole2 ; gotplt-to-plt-side
5082 [(parallel
5083 [(set
5084 (match_operand:SI 0 "register_operand" "")
5085 (match_operator:SI
5086 1 "cris_mem_op"
5087 [(plus:SI
5088 (reg:SI CRIS_GOT_REGNUM)
5089 (const:SI
5090 (unspec:SI [(match_operand:SI
5091 2 "cris_general_operand_or_symbol" "")]
5092 CRIS_UNSPEC_PLTGOTREAD)))]))
5093 (set (match_operand:SI 3 "register_operand" "")
5094 (plus:SI (reg:SI CRIS_GOT_REGNUM)
5095 (const:SI
5096 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])]
5097 "flag_pic
45d5d09c 5098 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1), true)
c00fc5cf
HPN
5099 && REGNO_REG_CLASS (REGNO (operands[0])) == REGNO_REG_CLASS (0)"
5100 [(set (match_dup 3)
5101 (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD)))
5102 (set (match_dup 3) (plus:SI (match_dup 3) (reg:SI CRIS_GOT_REGNUM)))
45d5d09c
HPN
5103 (set (match_dup 0)
5104 (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLT_GOTREL)))
c00fc5cf
HPN
5105 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI CRIS_GOT_REGNUM)))]
5106 "")
0b85d816
HPN
5107\f
5108;; Local variables:
5109;; mode:emacs-lisp
5110;; comment-start: ";; "
5111;; eval: (set-syntax-table (copy-sequence (syntax-table)))
5112;; eval: (modify-syntax-entry ?[ "(]")
5113;; eval: (modify-syntax-entry ?] ")[")
5114;; eval: (modify-syntax-entry ?{ "(}")
5115;; eval: (modify-syntax-entry ?} "){")
5116;; eval: (setq indent-tabs-mode t)
5117;; End: