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