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