]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/cris/cris.md
builtin_clz_v0.c: New testcase.
[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);")
2666\f
2667;; Bound-insn. Defined to be the same as an unsigned minimum, which is an
2668;; operation supported by gcc. Used in casesi, but used now and then in
2669;; normal code too.
2670
2671(define_insn "uminsi3"
23369bef
HPN
2672 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
2673 (umin:SI (match_operand:SI 1 "register_operand" "%0,0, 0,r")
c00fc5cf 2674 (match_operand:SI 2 "general_operand" "r,Q>,g,!To")))]
0b85d816 2675 ""
0b85d816 2676{
991c42ac 2677 if (CONST_INT_P (operands[2]))
0b85d816 2678 {
d76fe40b
HPN
2679 /* Constant operands are zero-extended, so only 32-bit operands
2680 may be negative. */
2681 if (INTVAL (operands[2]) >= 0)
2682 {
2683 if (INTVAL (operands[2]) < 256)
2684 return "bound.b %2,%0";
0b85d816 2685
d76fe40b
HPN
2686 if (INTVAL (operands[2]) < 65536)
2687 return "bound.w %2,%0";
2688 }
0b85d816
HPN
2689 }
2690 else if (which_alternative == 3)
22c3c091 2691 return "bound.d %2,%1,%0";
0b85d816 2692
22c3c091
HPN
2693 return "bound.d %2,%0";
2694}
0b85d816
HPN
2695 [(set_attr "slottable" "yes,yes,no,no")])
2696\f
2697;; Jump and branch insns.
2698
2699(define_insn "jump"
2700 [(set (pc)
2701 (label_ref (match_operand 0 "" "")))]
2702 ""
2703 "ba %l0%#"
2704 [(set_attr "slottable" "has_slot")])
2705
2706;; Testcase gcc.c-torture/compile/991213-3.c fails if we allow a constant
2707;; here, since the insn is not recognized as an indirect jump by
2708;; jmp_uses_reg_or_mem used by computed_jump_p. Perhaps it is a kludge to
2709;; change from general_operand to nonimmediate_operand (at least the docs
2710;; should be changed), but then again the pattern is called indirect_jump.
2711(define_insn "indirect_jump"
2712 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
2713 ""
2714 "jump %0")
2715
2716;; Return insn. Used whenever the epilogue is very simple; if it is only
04539954
HPN
2717;; a single ret or jump [sp+]. No allocated stack space or saved
2718;; registers are allowed.
0b85d816
HPN
2719;; Note that for this pattern, although named, it is ok to check the
2720;; context of the insn in the test, not only compiler switches.
2721
04539954 2722(define_expand "return"
0b85d816
HPN
2723 [(return)]
2724 "cris_simple_epilogue ()"
04539954 2725 "cris_expand_return (cris_return_address_on_stack ()); DONE;")
0b85d816 2726
04539954
HPN
2727(define_insn "*return_expanded"
2728 [(return)]
2729 ""
2730{
2731 return cris_return_address_on_stack_for_return ()
2732 ? "jump [$sp+]" : "ret%#";
2733}
0b85d816 2734 [(set (attr "slottable")
04539954
HPN
2735 (if_then_else
2736 (ne (symbol_ref
2737 "(cris_return_address_on_stack_for_return ())")
2738 (const_int 0))
2739 (const_string "no")
2740 (const_string "has_slot")))])
2741
d29b4b1b
HPN
2742(define_expand "prologue"
2743 [(const_int 0)]
2744 "TARGET_PROLOGUE_EPILOGUE"
2745 "cris_expand_prologue (); DONE;")
2746
04539954
HPN
2747;; Note that the (return) from the expander itself is always the last
2748;; insn in the epilogue.
2749(define_expand "epilogue"
2750 [(const_int 0)]
a6dfafa0 2751 "TARGET_PROLOGUE_EPILOGUE"
04539954 2752 "cris_expand_epilogue (); DONE;")
0b85d816
HPN
2753\f
2754;; Conditional branches.
2755
2756;; We suffer from the same overflow-bit-gets-in-the-way problem as
2757;; e.g. m68k, so we have to check if overflow bit is set on all "signed"
2758;; conditions.
2759
221ca267 2760(define_insn "b<ncond:code>"
0b85d816 2761 [(set (pc)
22c3c091
HPN
2762 (if_then_else (ncond (cc0)
2763 (const_int 0))
0b85d816
HPN
2764 (label_ref (match_operand 0 "" ""))
2765 (pc)))]
2766 ""
22c3c091 2767 "b<CC> %l0%#"
0b85d816
HPN
2768 [(set_attr "slottable" "has_slot")])
2769
221ca267 2770(define_insn "b<ocond:code>"
0b85d816 2771 [(set (pc)
22c3c091
HPN
2772 (if_then_else (ocond (cc0)
2773 (const_int 0))
0b85d816
HPN
2774 (label_ref (match_operand 0 "" ""))
2775 (pc)))]
2776 ""
0b85d816
HPN
2777{
2778 return
2779 (cc_prev_status.flags & CC_NO_OVERFLOW)
221ca267 2780 ? 0 : "b<CC> %l0%#";
22c3c091 2781}
0b85d816
HPN
2782 [(set_attr "slottable" "has_slot")])
2783
221ca267 2784(define_insn "b<rcond:code>"
0b85d816 2785 [(set (pc)
22c3c091
HPN
2786 (if_then_else (rcond (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)
22c3c091
HPN
2794 ? "b<oCC> %l0%#" : "b<CC> %l0%#";
2795}
0b85d816
HPN
2796 [(set_attr "slottable" "has_slot")])
2797\f
2798;; Reversed anonymous patterns to the ones above, as mandated.
2799
221ca267 2800(define_insn "*b<ncond:code>_reversed"
0b85d816 2801 [(set (pc)
22c3c091
HPN
2802 (if_then_else (ncond (cc0)
2803 (const_int 0))
0b85d816
HPN
2804 (pc)
2805 (label_ref (match_operand 0 "" ""))))]
2806 ""
22c3c091 2807 "b<rCC> %l0%#"
0b85d816
HPN
2808 [(set_attr "slottable" "has_slot")])
2809
221ca267 2810(define_insn "*b<ocond:code>_reversed"
0b85d816 2811 [(set (pc)
22c3c091
HPN
2812 (if_then_else (ocond (cc0)
2813 (const_int 0))
0b85d816
HPN
2814 (pc)
2815 (label_ref (match_operand 0 "" ""))))]
2816 ""
0b85d816
HPN
2817{
2818 return
2819 (cc_prev_status.flags & CC_NO_OVERFLOW)
221ca267 2820 ? 0 : "b<rCC> %l0%#";
22c3c091 2821}
0b85d816
HPN
2822 [(set_attr "slottable" "has_slot")])
2823
221ca267 2824(define_insn "*b<rcond:code>_reversed"
0b85d816 2825 [(set (pc)
22c3c091
HPN
2826 (if_then_else (rcond (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 ? "b<roCC> %l0%#" : "b<rCC> %l0%#";
22c3c091 2835}
0b85d816
HPN
2836 [(set_attr "slottable" "has_slot")])
2837\f
2838;; Set on condition: sCC.
2839
2840;; Like bCC, we have to check the overflow bit for
2841;; signed conditions.
2842
221ca267 2843(define_insn "s<ncond:code>"
0b85d816 2844 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 2845 (ncond:SI (cc0) (const_int 0)))]
0b85d816 2846 ""
22c3c091 2847 "s<CC> %0"
0b85d816
HPN
2848 [(set_attr "slottable" "yes")
2849 (set_attr "cc" "none")])
2850
221ca267 2851(define_insn "s<rcond:code>"
0b85d816 2852 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 2853 (rcond:SI (cc0) (const_int 0)))]
0b85d816 2854 ""
0b85d816
HPN
2855{
2856 return
2857 (cc_prev_status.flags & CC_NO_OVERFLOW)
22c3c091
HPN
2858 ? "s<oCC> %0" : "s<CC> %0";
2859}
0cec6af1
HPN
2860 [(set_attr "slottable" "yes")
2861 (set_attr "cc" "none")])
0b85d816 2862
221ca267 2863(define_insn "s<ocond:code>"
0b85d816 2864 [(set (match_operand:SI 0 "register_operand" "=r")
22c3c091 2865 (ocond:SI (cc0) (const_int 0)))]
0b85d816 2866 ""
0b85d816
HPN
2867{
2868 return
2869 (cc_prev_status.flags & CC_NO_OVERFLOW)
22c3c091
HPN
2870 ? 0 : "s<CC> %0";
2871}
0b85d816
HPN
2872 [(set_attr "slottable" "yes")
2873 (set_attr "cc" "none")])
2874\f
2875;; Call insns.
2876
2877;; We need to make these patterns "expand", since the real operand is
2878;; hidden in a (mem:QI ) inside operand[0] (call_value: operand[1]),
2879;; and cannot be checked if it were a "normal" pattern.
2880;; Note that "call" and "call_value" are *always* called with a
2881;; mem-operand for operand 0 and 1 respective. What happens for combined
2882;; instructions is a different issue.
2883
2884(define_expand "call"
2885 [(parallel [(call (match_operand:QI 0 "cris_mem_call_operand" "")
2886 (match_operand 1 "general_operand" ""))
f16bb520 2887 (clobber (reg:SI CRIS_SRP_REGNUM))])]
0b85d816 2888 ""
0b85d816 2889{
991c42ac 2890 gcc_assert (MEM_P (operands[0]));
0b85d816 2891 if (flag_pic)
c00fc5cf 2892 cris_expand_pic_call_address (&operands[0]);
b6c34129 2893})
0b85d816
HPN
2894
2895;; Accept *anything* as operand 1. Accept operands for operand 0 in
23369bef 2896;; order of preference.
0b85d816
HPN
2897
2898(define_insn "*expanded_call"
0b85d816
HPN
2899 [(call (mem:QI (match_operand:SI
2900 0 "cris_general_operand_or_plt_symbol" "r,Q>,g"))
2901 (match_operand 1 "" ""))
f16bb520 2902 (clobber (reg:SI CRIS_SRP_REGNUM))]
c00fc5cf 2903 ""
0b85d816
HPN
2904 "jsr %0")
2905
c00fc5cf
HPN
2906;; Parallel when calculating and reusing address of indirect pointer
2907;; with simple offset. (Makes most sense with PIC.) It looks a bit
2908;; wrong not to have the clobber last, but that's the way combine
2909;; generates it (except it doesn' look into the *inner* mem, so this
2910;; just matches a peephole2). FIXME: investigate that.
2911(define_insn "*expanded_call_side"
2912 [(call (mem:QI
2913 (mem:SI
2914 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r, r,r")
2915 (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r,>Rn"))))
2916 (match_operand 2 "" ""))
2917 (clobber (reg:SI CRIS_SRP_REGNUM))
2918 (set (match_operand:SI 3 "register_operand" "=*0,r,r")
2919 (plus:SI (match_dup 0)
2920 (match_dup 1)))]
2921 "! TARGET_AVOID_GOTPLT"
2922 "jsr [%3=%0%S1]")
2923
0b85d816
HPN
2924(define_expand "call_value"
2925 [(parallel [(set (match_operand 0 "" "")
2926 (call (match_operand:QI 1 "cris_mem_call_operand" "")
2927 (match_operand 2 "" "")))
f16bb520 2928 (clobber (reg:SI CRIS_SRP_REGNUM))])]
0b85d816 2929 ""
0b85d816 2930{
991c42ac 2931 gcc_assert (MEM_P (operands[1]));
0b85d816 2932 if (flag_pic)
c00fc5cf 2933 cris_expand_pic_call_address (&operands[1]);
b6c34129 2934})
0b85d816
HPN
2935
2936;; Accept *anything* as operand 2. The validity other than "general" of
2937;; operand 0 will be checked elsewhere. Accept operands for operand 1 in
2938;; order of preference (Q includes r, but r is shorter, faster).
2939;; We also accept a PLT symbol. We output it as [rPIC+sym:GOTPLT] rather
2940;; than requiring getting rPIC + sym:PLT into a register.
2941
2942(define_insn "*expanded_call_value"
c00fc5cf 2943 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
0b85d816 2944 (call (mem:QI (match_operand:SI
c00fc5cf 2945 1 "cris_general_operand_or_plt_symbol" "r,Q>,g"))
0b85d816 2946 (match_operand 2 "" "")))
f16bb520 2947 (clobber (reg:SI CRIS_SRP_REGNUM))]
c00fc5cf 2948 ""
0b85d816
HPN
2949 "Jsr %1"
2950 [(set_attr "cc" "clobber")])
2951
c00fc5cf
HPN
2952;; See similar call special-case.
2953(define_insn "*expanded_call_value_side"
0b85d816 2954 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
c00fc5cf
HPN
2955 (call
2956 (mem:QI
2957 (mem:SI
2958 (plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r, r,r")
2959 (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn"))))
2960 (match_operand 3 "" "")))
2961 (clobber (reg:SI CRIS_SRP_REGNUM))
2962 (set (match_operand:SI 4 "register_operand" "=*1,r,r")
2963 (plus:SI (match_dup 1)
2964 (match_dup 2)))]
2965 "! TARGET_AVOID_GOTPLT"
2966 "Jsr [%4=%1%S2]"
0b85d816
HPN
2967 [(set_attr "cc" "clobber")])
2968
2969;; Used in debugging. No use for the direct pattern; unfilled
2970;; delayed-branches are taken care of by other means.
2971
2972(define_insn "nop"
2973 [(const_int 0)]
2974 ""
2975 "nop"
2976 [(set_attr "cc" "none")])
2977\f
04539954
HPN
2978;; We need to stop accesses to the stack after the memory is
2979;; deallocated. Unfortunately, reorg doesn't look at naked clobbers,
2980;; e.g. (insn ... (clobber (mem:BLK (stack_pointer_rtx)))) and we don't
2981;; want to use a naked (unspec_volatile) as that would stop any
2982;; scheduling in the epilogue. Hence we model it as a "real" insn that
2983;; sets the memory in an unspecified manner. FIXME: Unfortunately it
2984;; still has the effect of an unspec_volatile.
2985(define_insn "cris_frame_deallocated_barrier"
2986 [(set (mem:BLK (reg:SI CRIS_SP_REGNUM))
2987 (unspec:BLK [(const_int 0)] CRIS_UNSPEC_FRAME_DEALLOC))]
2988 ""
2989 ""
2990 [(set_attr "length" "0")])
2991
0b85d816
HPN
2992;; We expand on casesi so we can use "bound" and "add offset fetched from
2993;; a table to pc" (adds.w [pc+%0.w],pc).
2994
2995;; Note: if you change the "parallel" (or add anything after it) in
2996;; this expansion, you must change the macro ASM_OUTPUT_CASE_END
2997;; accordingly, to add the default case at the end of the jump-table.
2998
2999(define_expand "casesi"
3000 [(set (match_dup 5) (match_operand:SI 0 "general_operand" ""))
3001 (set (match_dup 6)
3002 (minus:SI (match_dup 5)
3003 (match_operand:SI 1 "const_int_operand" "n")))
3004 (set (match_dup 7)
3005 (umin:SI (match_dup 6)
3006 (match_operand:SI 2 "const_int_operand" "n")))
3007 (parallel
3008 [(set (pc)
3009 (if_then_else
3010 (ltu (match_dup 7) (match_dup 2))
3011 (plus:SI (sign_extend:SI
3012 (mem:HI
3013 (plus:SI (mult:SI (match_dup 7) (const_int 2))
3014 (pc))))
3015 (pc))
3016 (label_ref (match_operand 4 "" ""))))
3017 (use (label_ref (match_operand 3 "" "")))])]
3018 ""
0b85d816
HPN
3019{
3020 operands[2] = plus_constant (operands[2], 1);
3021 operands[5] = gen_reg_rtx (SImode);
3022 operands[6] = gen_reg_rtx (SImode);
3023 operands[7] = gen_reg_rtx (SImode);
22c3c091 3024})
0b85d816
HPN
3025\f
3026;; Split-patterns. Some of them have modes unspecified. This
3027;; should always be ok; if for no other reason sparc.md has it as
3028;; well.
3029;;
3030;; When register_operand is specified for an operand, we can get a
3031;; subreg as well (Axis-990331), so don't just assume that REG_P is true
3032;; for a register_operand and that REGNO can be used as is. It is best to
3033;; guard with REG_P, unless it is worth it to adjust for the subreg case.
3034
3035;; op [rx + 0],ry,rz
3036;; The index to rx is optimized into zero, and gone.
3037
3038;; First, recognize bound [rx],ry,rz; where [rx] is zero-extended,
3039;; and add/sub [rx],ry,rz, with zero or sign-extend on [rx].
3040;; Split this into:
3041;; move ry,rz
3042;; op [rx],rz
3043;; Lose if rz=ry or rx=rz.
3044;; Call this op-extend-split
3045
3046(define_split
3047 [(set (match_operand 0 "register_operand" "")
3048 (match_operator
3049 4 "cris_operand_extend_operator"
3050 [(match_operand 1 "register_operand" "")
3051 (match_operator
3052 3 "cris_extend_operator"
3053 [(match_operand 2 "memory_operand" "")])]))]
3054 "REG_P (operands[0])
3055 && REG_P (operands[1])
3056 && REGNO (operands[1]) != REGNO (operands[0])
3057 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3058 && REG_P (XEXP (operands[2], 0))
3059 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
3060 [(set (match_dup 0)
3061 (match_dup 1))
3062 (set (match_dup 0)
3063 (match_op_dup
3064 4 [(match_dup 0)
3065 (match_op_dup 3 [(match_dup 2)])]))]
3066 "")
3067
3068;; As op-extend-split, but recognize and split op [rz],ry,rz into
3069;; ext [rz],rz
3070;; op ry,rz
3071;; Do this for plus or bound only, being commutative operations, since we
3072;; have swapped the operands.
3073;; Call this op-extend-split-rx=rz
3074
3075(define_split
3076 [(set (match_operand 0 "register_operand" "")
3077 (match_operator
3078 4 "cris_plus_or_bound_operator"
3079 [(match_operand 1 "register_operand" "")
3080 (match_operator
3081 3 "cris_extend_operator"
3082 [(match_operand 2 "memory_operand" "")])]))]
3083 "REG_P (operands[0])
3084 && REG_P (operands[1])
3085 && REGNO (operands[1]) != REGNO (operands[0])
3086 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3087 && REG_P (XEXP (operands[2], 0))
3088 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
3089 [(set (match_dup 0)
3090 (match_op_dup 3 [(match_dup 2)]))
3091 (set (match_dup 0)
3092 (match_op_dup
3093 4 [(match_dup 0)
3094 (match_dup 1)]))]
3095 "")
3096
3097;; As the op-extend-split, but swapped operands, and only for
3098;; plus or bound, being the commutative extend-operators. FIXME: Why is
3099;; this needed? Is it?
3100;; Call this op-extend-split-swapped
3101
3102(define_split
3103 [(set (match_operand 0 "register_operand" "")
3104 (match_operator
3105 4 "cris_plus_or_bound_operator"
3106 [(match_operator
3107 3 "cris_extend_operator"
3108 [(match_operand 2 "memory_operand" "")])
3109 (match_operand 1 "register_operand" "")]))]
3110 "REG_P (operands[0])
3111 && REG_P (operands[1])
3112 && REGNO (operands[1]) != REGNO (operands[0])
3113 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3114 && REG_P (XEXP (operands[2], 0))
3115 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
3116 [(set (match_dup 0)
3117 (match_dup 1))
3118 (set (match_dup 0)
3119 (match_op_dup
3120 4 [(match_dup 0)
3121 (match_op_dup 3 [(match_dup 2)])]))]
3122 "")
3123
3124;; As op-extend-split-rx=rz, but swapped operands, only for plus or
3125;; bound. Call this op-extend-split-swapped-rx=rz.
3126
3127(define_split
3128 [(set (match_operand 0 "register_operand" "")
3129 (match_operator
3130 4 "cris_plus_or_bound_operator"
3131 [(match_operator
3132 3 "cris_extend_operator"
3133 [(match_operand 2 "memory_operand" "")])
3134 (match_operand 1 "register_operand" "")]))]
3135 "REG_P (operands[0])
3136 && REG_P (operands[1])
3137 && REGNO (operands[1]) != REGNO (operands[0])
3138 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3139 && REG_P (XEXP (operands[2], 0))
3140 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
3141 [(set (match_dup 0)
3142 (match_op_dup 3 [(match_dup 2)]))
3143 (set (match_dup 0)
3144 (match_op_dup
3145 4 [(match_dup 0)
3146 (match_dup 1)]))]
3147 "")
3148
3149;; As op-extend-split, but the mem operand is not extended.
3150;;
3151;; op [rx],ry,rz changed into
3152;; move ry,rz
3153;; op [rx],rz
3154;; lose if ry=rz or rx=rz
3155;; Call this op-extend.
3156
3157(define_split
3158 [(set (match_operand 0 "register_operand" "")
3159 (match_operator
3160 3 "cris_orthogonal_operator"
3161 [(match_operand 1 "register_operand" "")
3162 (match_operand 2 "memory_operand" "")]))]
3163 "REG_P (operands[0])
3164 && REG_P (operands[1])
3165 && REGNO (operands[1]) != REGNO (operands[0])
3166 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3167 && REG_P (XEXP (operands[2], 0))
3168 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
3169 [(set (match_dup 0)
3170 (match_dup 1))
3171 (set (match_dup 0)
3172 (match_op_dup
3173 3 [(match_dup 0)
3174 (match_dup 2)]))]
3175 "")
3176
3177;; As op-extend-split-rx=rz, non-extended.
3178;; Call this op-split-rx=rz
3179
3180(define_split
3181 [(set (match_operand 0 "register_operand" "")
3182 (match_operator
3183 3 "cris_commutative_orth_op"
3184 [(match_operand 2 "memory_operand" "")
3185 (match_operand 1 "register_operand" "")]))]
3186 "REG_P (operands[0])
3187 && REG_P (operands[1])
3188 && REGNO (operands[1]) != REGNO (operands[0])
3189 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3190 && REG_P (XEXP (operands[2], 0))
3191 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
3192 [(set (match_dup 0)
3193 (match_dup 1))
3194 (set (match_dup 0)
3195 (match_op_dup
3196 3 [(match_dup 0)
3197 (match_dup 2)]))]
3198 "")
3199
3200;; As op-extend-split-swapped, nonextended.
3201;; Call this op-split-swapped.
3202
3203(define_split
3204 [(set (match_operand 0 "register_operand" "")
3205 (match_operator
3206 3 "cris_commutative_orth_op"
3207 [(match_operand 1 "register_operand" "")
3208 (match_operand 2 "memory_operand" "")]))]
3209 "REG_P (operands[0]) && REG_P (operands[1])
3210 && REGNO (operands[1]) != REGNO (operands[0])
3211 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3212 && REG_P (XEXP (operands[2], 0))
3213 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
3214 [(set (match_dup 0)
3215 (match_dup 2))
3216 (set (match_dup 0)
3217 (match_op_dup
3218 3 [(match_dup 0)
3219 (match_dup 1)]))]
3220 "")
3221
3222;; As op-extend-split-swapped-rx=rz, non-extended.
3223;; Call this op-split-swapped-rx=rz.
3224
3225(define_split
3226 [(set (match_operand 0 "register_operand" "")
3227 (match_operator
3228 3 "cris_orthogonal_operator"
3229 [(match_operand 2 "memory_operand" "")
3230 (match_operand 1 "register_operand" "")]))]
3231 "REG_P (operands[0]) && REG_P (operands[1])
3232 && REGNO (operands[1]) != REGNO (operands[0])
3233 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
3234 && REG_P (XEXP (operands[2], 0))
3235 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
3236 [(set (match_dup 0)
3237 (match_dup 2))
3238 (set (match_dup 0)
3239 (match_op_dup
3240 3 [(match_dup 0)
3241 (match_dup 1)]))]
3242 "")
3243\f
3244;; Splits for all cases in side-effect insns where (possibly after reload
3245;; and register allocation) rx and ry in [rx=ry+i] are equal.
3246
3247;; move.S1 [rx=rx+rz.S2],ry
3248
3249(define_split
3250 [(parallel
3251 [(set (match_operand 0 "register_operand" "")
dbb138ce
HPN
3252 (match_operator
3253 6 "cris_mem_op"
3254 [(plus:SI
3255 (mult:SI (match_operand:SI 1 "register_operand" "")
3256 (match_operand:SI 2 "const_int_operand" ""))
3257 (match_operand:SI 3 "register_operand" ""))]))
0b85d816 3258 (set (match_operand:SI 4 "register_operand" "")
8ad46d34
HPN
3259 (plus:SI (mult:SI (match_dup 1)
3260 (match_dup 2))
0b85d816
HPN
3261 (match_dup 3)))])]
3262 "REG_P (operands[3]) && REG_P (operands[4])
3263 && REGNO (operands[3]) == REGNO (operands[4])"
3264 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
8ad46d34 3265 (match_dup 3)))
0b85d816 3266 (set (match_dup 0) (match_dup 5))]
dbb138ce 3267 "operands[5] = replace_equiv_address (operands[6], operands[3]);")
0b85d816
HPN
3268
3269;; move.S1 [rx=rx+i],ry
3270
3271(define_split
3272 [(parallel
3273 [(set (match_operand 0 "register_operand" "")
dbb138ce
HPN
3274 (match_operator
3275 5 "cris_mem_op"
3276 [(plus:SI (match_operand:SI 1 "cris_bdap_operand" "")
3277 (match_operand:SI 2 "cris_bdap_operand" ""))]))
0b85d816
HPN
3278 (set (match_operand:SI 3 "register_operand" "")
3279 (plus:SI (match_dup 1)
3280 (match_dup 2)))])]
3281 "(rtx_equal_p (operands[3], operands[1])
3282 || rtx_equal_p (operands[3], operands[2]))"
3283 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))
3284 (set (match_dup 0) (match_dup 4))]
7faa3eb8
HPN
3285{
3286 operands[4] = replace_equiv_address (operands[5], operands[3]);
3287 cris_order_for_addsi3 (operands, 1);
3288})
0b85d816
HPN
3289
3290;; move.S1 ry,[rx=rx+rz.S2]
3291
3292(define_split
3293 [(parallel
dbb138ce
HPN
3294 [(set (match_operator
3295 6 "cris_mem_op"
3296 [(plus:SI
3297 (mult:SI (match_operand:SI 0 "register_operand" "")
3298 (match_operand:SI 1 "const_int_operand" ""))
3299 (match_operand:SI 2 "register_operand" ""))])
3300 (match_operand 3 "register_operand" ""))
0b85d816
HPN
3301 (set (match_operand:SI 4 "register_operand" "")
3302 (plus:SI (mult:SI (match_dup 0)
3303 (match_dup 1))
3304 (match_dup 2)))])]
3305 "REG_P (operands[2]) && REG_P (operands[4])
3306 && REGNO (operands[4]) == REGNO (operands[2])"
3307 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
3308 (match_dup 2)))
3309 (set (match_dup 5) (match_dup 3))]
dbb138ce 3310 "operands[5] = replace_equiv_address (operands[6], operands[4]);")
0b85d816
HPN
3311
3312;; move.S1 ry,[rx=rx+i]
3313
3314(define_split
3315 [(parallel
dbb138ce
HPN
3316 [(set (match_operator
3317 6 "cris_mem_op"
3318 [(plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
3319 (match_operand:SI 1 "cris_bdap_operand" ""))])
3320 (match_operand 2 "register_operand" ""))
0b85d816
HPN
3321 (set (match_operand:SI 3 "register_operand" "")
3322 (plus:SI (match_dup 0)
3323 (match_dup 1)))])]
3324 "(rtx_equal_p (operands[3], operands[0])
3325 || rtx_equal_p (operands[3], operands[1]))"
3326 [(set (match_dup 3) (plus:SI (match_dup 0) (match_dup 1)))
3327 (set (match_dup 5) (match_dup 2))]
7faa3eb8
HPN
3328{
3329 operands[5] = replace_equiv_address (operands[6], operands[3]);
3330 cris_order_for_addsi3 (operands, 0);
3331})
0b85d816 3332
22c3c091 3333;; clear.[bwd] [rx=rx+rz.S2]
0b85d816
HPN
3334
3335(define_split
3336 [(parallel
22c3c091 3337 [(set (mem:BWD (plus:SI
0b85d816
HPN
3338 (mult:SI (match_operand:SI 0 "register_operand" "")
3339 (match_operand:SI 1 "const_int_operand" ""))
3340 (match_operand:SI 2 "register_operand" "")))
3341 (const_int 0))
3342 (set (match_operand:SI 3 "register_operand" "")
3343 (plus:SI (mult:SI (match_dup 0)
3344 (match_dup 1))
3345 (match_dup 2)))])]
3346 "REG_P (operands[2]) && REG_P (operands[3])
3347 && REGNO (operands[3]) == REGNO (operands[2])"
3348 [(set (match_dup 3) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
3349 (match_dup 2)))
22c3c091 3350 (set (mem:BWD (match_dup 3)) (const_int 0))]
0b85d816
HPN
3351 "")
3352
22c3c091 3353;; clear.[bwd] [rx=rx+i]
0b85d816
HPN
3354
3355(define_split
3356 [(parallel
22c3c091 3357 [(set (mem:BWD
0b85d816
HPN
3358 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
3359 (match_operand:SI 1 "cris_bdap_operand" "")))
3360 (const_int 0))
3361 (set (match_operand:SI 2 "register_operand" "")
3362 (plus:SI (match_dup 0)
3363 (match_dup 1)))])]
3364 "(rtx_equal_p (operands[0], operands[2])
3365 || rtx_equal_p (operands[2], operands[1]))"
3366 [(set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))
22c3c091 3367 (set (mem:BWD (match_dup 2)) (const_int 0))]
7faa3eb8 3368 "cris_order_for_addsi3 (operands, 0);")
0b85d816
HPN
3369
3370;; mov(s|u).S1 [rx=rx+rz.S2],ry
3371
3372(define_split
3373 [(parallel
3374 [(set (match_operand 0 "register_operand" "")
3375 (match_operator
3376 5 "cris_extend_operator"
3377 [(mem (plus:SI
3378 (mult:SI (match_operand:SI 1 "register_operand" "")
3379 (match_operand:SI 2 "const_int_operand" ""))
3380 (match_operand:SI 3 "register_operand" "")))]))
3381 (set (match_operand:SI 4 "register_operand" "")
3382 (plus:SI (mult:SI (match_dup 1)
3383 (match_dup 2))
3384 (match_dup 3)))])]
3385 "REG_P (operands[3])
3386 && REG_P (operands[4])
3387 && REGNO (operands[3]) == REGNO (operands[4])"
3388 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
3389 (match_dup 3)))
3390 (set (match_dup 0) (match_op_dup 5 [(match_dup 6)]))]
dbb138ce 3391 "operands[6] = replace_equiv_address (XEXP (operands[5], 0), operands[4]);")
0b85d816
HPN
3392
3393;; mov(s|u).S1 [rx=rx+i],ry
3394
3395(define_split
3396 [(parallel
3397 [(set (match_operand 0 "register_operand" "")
3398 (match_operator
3399 4 "cris_extend_operator"
3400 [(mem (plus:SI
3401 (match_operand:SI 1 "cris_bdap_operand" "")
3402 (match_operand:SI 2 "cris_bdap_operand" "")))]))
3403 (set (match_operand:SI 3 "register_operand" "")
3404 (plus:SI (match_dup 1)
3405 (match_dup 2)))])]
3406 "(rtx_equal_p (operands[1], operands[3])
3407 || rtx_equal_p (operands[2], operands[3]))"
3408 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))
3409 (set (match_dup 0) (match_op_dup 4 [(match_dup 5)]))]
7faa3eb8
HPN
3410{
3411 operands[5] = replace_equiv_address (XEXP (operands[4], 0), operands[3]);
3412 cris_order_for_addsi3 (operands, 1);
3413})
0b85d816
HPN
3414
3415;; op.S1 [rx=rx+i],ry
3416
3417(define_split
3418 [(parallel
3419 [(set (match_operand 0 "register_operand" "")
3420 (match_operator
3421 5 "cris_orthogonal_operator"
3422 [(match_operand 1 "register_operand" "")
3423 (mem (plus:SI
3424 (match_operand:SI 2 "cris_bdap_operand" "")
3425 (match_operand:SI 3 "cris_bdap_operand" "")))]))
3426 (set (match_operand:SI 4 "register_operand" "")
3427 (plus:SI (match_dup 2)
3428 (match_dup 3)))])]
3429 "(rtx_equal_p (operands[4], operands[2])
3430 || rtx_equal_p (operands[4], operands[3]))"
3431 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
3432 (set (match_dup 0) (match_op_dup 5 [(match_dup 1) (match_dup 6)]))]
7faa3eb8
HPN
3433{
3434 operands[6] = replace_equiv_address (XEXP (operands[5], 1), operands[4]);
3435 cris_order_for_addsi3 (operands, 2);
3436})
0b85d816
HPN
3437
3438;; op.S1 [rx=rx+rz.S2],ry
3439
3440(define_split
3441 [(parallel
3442 [(set (match_operand 0 "register_operand" "")
3443 (match_operator
3444 6 "cris_orthogonal_operator"
3445 [(match_operand 1 "register_operand" "")
3446 (mem (plus:SI
3447 (mult:SI (match_operand:SI 2 "register_operand" "")
3448 (match_operand:SI 3 "const_int_operand" ""))
3449 (match_operand:SI 4 "register_operand" "")))]))
3450 (set (match_operand:SI 5 "register_operand" "")
3451 (plus:SI (mult:SI (match_dup 2)
3452 (match_dup 3))
3453 (match_dup 4)))])]
3454 "REG_P (operands[4])
3455 && REG_P (operands[5])
3456 && REGNO (operands[5]) == REGNO (operands[4])"
3457 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
3458 (match_dup 4)))
3459 (set (match_dup 0) (match_op_dup 6 [(match_dup 1) (match_dup 7)]))]
dbb138ce 3460 "operands[7] = replace_equiv_address (XEXP (operands[6], 1), operands[5]);")
0b85d816
HPN
3461
3462;; op.S1 [rx=rx+rz.S2],ry (swapped)
3463
3464(define_split
3465 [(parallel
3466 [(set (match_operand 0 "register_operand" "")
3467 (match_operator
3468 6 "cris_commutative_orth_op"
3469 [(mem (plus:SI
3470 (mult:SI (match_operand:SI 2 "register_operand" "")
3471 (match_operand:SI 3 "const_int_operand" ""))
3472 (match_operand:SI 4 "register_operand" "")))
3473 (match_operand 1 "register_operand" "")]))
3474 (set (match_operand:SI 5 "register_operand" "")
3475 (plus:SI (mult:SI (match_dup 2)
3476 (match_dup 3))
3477 (match_dup 4)))])]
3478 "REG_P (operands[4])
3479 && REG_P (operands[5])
3480 && REGNO (operands[5]) == REGNO (operands[4])"
3481 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
3482 (match_dup 4)))
3483 (set (match_dup 0) (match_op_dup 6 [(match_dup 7) (match_dup 1)]))]
dbb138ce 3484 "operands[7] = replace_equiv_address (XEXP (operands[6], 0), operands[5]);")
0b85d816
HPN
3485
3486;; op.S1 [rx=rx+i],ry (swapped)
3487
3488(define_split
3489 [(parallel
3490 [(set (match_operand 0 "register_operand" "")
3491 (match_operator
3492 5 "cris_commutative_orth_op"
3493 [(mem
3494 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "")
3495 (match_operand:SI 3 "cris_bdap_operand" "")))
3496 (match_operand 1 "register_operand" "")]))
3497 (set (match_operand:SI 4 "register_operand" "")
3498 (plus:SI (match_dup 2)
3499 (match_dup 3)))])]
3500 "(rtx_equal_p (operands[4], operands[2])
3501 || rtx_equal_p (operands[4], operands[3]))"
3502 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
3503 (set (match_dup 0) (match_op_dup 5 [(match_dup 6) (match_dup 1)]))]
7faa3eb8
HPN
3504{
3505 operands[6] = replace_equiv_address (XEXP (operands[5], 0), operands[4]);
3506 cris_order_for_addsi3 (operands, 2);
3507})
0b85d816
HPN
3508
3509;; op(s|u).S1 [rx=rx+rz.S2],ry
3510
3511(define_split
3512 [(parallel
3513 [(set (match_operand 0 "register_operand" "")
3514 (match_operator
3515 6 "cris_operand_extend_operator"
3516 [(match_operand 1 "register_operand" "")
3517 (match_operator
3518 7 "cris_extend_operator"
3519 [(mem (plus:SI
3520 (mult:SI (match_operand:SI 2 "register_operand" "")
3521 (match_operand:SI 3 "const_int_operand" ""))
3522 (match_operand:SI 4 "register_operand" "")))])]))
3523 (set (match_operand:SI 5 "register_operand" "")
3524 (plus:SI (mult:SI (match_dup 2)
3525 (match_dup 3))
3526 (match_dup 4)))])]
3527 "REG_P (operands[4])
3528 && REG_P (operands[5])
3529 && REGNO (operands[5]) == REGNO (operands[4])"
3530 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
3531 (match_dup 4)))
3532 (set (match_dup 0) (match_op_dup 6 [(match_dup 1) (match_dup 8)]))]
1c563bed 3533 "operands[8] = gen_rtx_fmt_e (GET_CODE (operands[7]), GET_MODE (operands[7]),
0f4c242b
KH
3534 replace_equiv_address (XEXP (operands[7], 0),
3535 operands[5]));")
0b85d816
HPN
3536
3537;; op(s|u).S1 [rx=rx+i],ry
3538
3539(define_split
3540 [(parallel
3541 [(set (match_operand 0 "register_operand" "")
3542 (match_operator
3543 5 "cris_operand_extend_operator"
3544 [(match_operand 1 "register_operand" "")
3545 (match_operator
3546 6 "cris_extend_operator"
3547 [(mem
3548 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "")
3549 (match_operand:SI 3 "cris_bdap_operand" "")
3550 ))])]))
3551 (set (match_operand:SI 4 "register_operand" "")
3552 (plus:SI (match_dup 2)
3553 (match_dup 3)))])]
3554 "(rtx_equal_p (operands[4], operands[2])
3555 || rtx_equal_p (operands[4], operands[3]))"
3556 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
3557 (set (match_dup 0) (match_op_dup 5 [(match_dup 1) (match_dup 7)]))]
7faa3eb8
HPN
3558{
3559 operands[7] = gen_rtx_fmt_e (GET_CODE (operands[6]), GET_MODE (operands[6]),
3560 replace_equiv_address (XEXP (operands[6], 0),
3561 operands[4]));
3562 cris_order_for_addsi3 (operands, 2);
3563})
0b85d816
HPN
3564
3565;; op(s|u).S1 [rx=rx+rz.S2],ry (swapped, plus or bound)
3566
3567(define_split
3568 [(parallel
3569 [(set (match_operand 0 "register_operand" "")
3570 (match_operator
3571 7 "cris_plus_or_bound_operator"
3572 [(match_operator
3573 6 "cris_extend_operator"
3574 [(mem (plus:SI
3575 (mult:SI (match_operand:SI 2 "register_operand" "")
3576 (match_operand:SI 3 "const_int_operand" ""))
3577 (match_operand:SI 4 "register_operand" "")))])
3578 (match_operand 1 "register_operand" "")]))
3579 (set (match_operand:SI 5 "register_operand" "")
3580 (plus:SI (mult:SI (match_dup 2)
3581 (match_dup 3))
3582 (match_dup 4)))])]
3583 "REG_P (operands[4]) && REG_P (operands[5])
3584 && REGNO (operands[5]) == REGNO (operands[4])"
3585 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
3586 (match_dup 4)))
3587 (set (match_dup 0) (match_op_dup 6 [(match_dup 8) (match_dup 1)]))]
1c563bed 3588 "operands[8] = gen_rtx_fmt_e (GET_CODE (operands[6]), GET_MODE (operands[6]),
0f4c242b
KH
3589 replace_equiv_address (XEXP (operands[6], 0),
3590 operands[5]));")
0b85d816
HPN
3591
3592;; op(s|u).S1 [rx=rx+i],ry (swapped, plus or bound)
3593
3594(define_split
3595 [(parallel
3596 [(set (match_operand 0 "register_operand" "")
3597 (match_operator
3598 6 "cris_plus_or_bound_operator"
3599 [(match_operator
3600 5 "cris_extend_operator"
3601 [(mem (plus:SI
3602 (match_operand:SI 2 "cris_bdap_operand" "")
3603 (match_operand:SI 3 "cris_bdap_operand" "")))])
3604 (match_operand 1 "register_operand" "")]))
3605 (set (match_operand:SI 4 "register_operand" "")
3606 (plus:SI (match_dup 2)
3607 (match_dup 3)))])]
3608 "(rtx_equal_p (operands[4], operands[2])
3609 || rtx_equal_p (operands[4], operands[3]))"
3610 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
3611 (set (match_dup 0) (match_op_dup 6 [(match_dup 7) (match_dup 1)]))]
7faa3eb8
HPN
3612{
3613 operands[7] = gen_rtx_fmt_e (GET_CODE (operands[5]), GET_MODE (operands[5]),
3614 replace_equiv_address (XEXP (operands[5], 0),
3615 operands[4]));
3616 cris_order_for_addsi3 (operands, 2);
3617})
0b85d816
HPN
3618\f
3619;; Splits for addressing prefixes that have no side-effects, so we can
3620;; fill a delay slot. Never split if we lose something, though.
3621
3622;; If we have a
3623;; move [indirect_ref],rx
3624;; where indirect ref = {const, [r+], [r]}, it costs as much as
3625;; move indirect_ref,rx
3626;; move [rx],rx
3627;; Take care not to allow indirect_ref = register.
3628
3629;; We're not allowed to generate copies of registers with different mode
3630;; until after reload; copying pseudos upsets reload. CVS as of
3631;; 2001-08-24, unwind-dw2-fde.c, _Unwind_Find_FDE ICE in
3632;; cselib_invalidate_regno.
3633
f60c7155 3634(define_split ; indir_to_reg_split
0b85d816
HPN
3635 [(set (match_operand 0 "register_operand" "")
3636 (match_operand 1 "indirect_operand" ""))]
3637 "reload_completed
3638 && REG_P (operands[0])
3639 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
991c42ac 3640 && (MEM_P (XEXP (operands[1], 0)) || CONSTANT_P (XEXP (operands[1], 0)))
f60c7155 3641 && REGNO (operands[0]) < CRIS_LAST_GENERAL_REGISTER"
0b85d816
HPN
3642 [(set (match_dup 2) (match_dup 4))
3643 (set (match_dup 0) (match_dup 3))]
3644 "operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
dbb138ce 3645 operands[3] = replace_equiv_address (operands[1], operands[2]);
0b85d816
HPN
3646 operands[4] = XEXP (operands[1], 0);")
3647
3648;; As the above, but MOVS and MOVU.
3649
3650(define_split
3651 [(set (match_operand 0 "register_operand" "")
3652 (match_operator
3653 4 "cris_extend_operator"
3654 [(match_operand 1 "indirect_operand" "")]))]
3655 "reload_completed
3656 && REG_P (operands[0])
3657 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
991c42ac 3658 && (MEM_P (XEXP (operands[1], 0))
0b85d816
HPN
3659 || CONSTANT_P (XEXP (operands[1], 0)))"
3660 [(set (match_dup 2) (match_dup 5))
3661 (set (match_dup 0) (match_op_dup 4 [(match_dup 3)]))]
3662 "operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
dbb138ce 3663 operands[3] = replace_equiv_address (XEXP (operands[4], 0), operands[2]);
0b85d816
HPN
3664 operands[5] = XEXP (operands[1], 0);")
3665\f
3666;; Various peephole optimizations.
3667;;
3668;; Watch out: when you exchange one set of instructions for another, the
3669;; condition codes setting must be the same, or you have to CC_INIT or
3670;; whatever is appropriate, in the pattern before you emit the
3671;; assembly text. This is best done here, not in cris_notice_update_cc,
3672;; to keep changes local to their cause.
3673;;
3674;; Do not add patterns that you do not know will be matched.
109b748d 3675;; Please also add a self-contained testcase.
0b85d816
HPN
3676
3677;; We have trouble with and:s and shifts. Maybe something is broken in
43a88a8c 3678;; gcc? Or it could just be that bit-field insn expansion is a bit
0b85d816 3679;; suboptimal when not having extzv insns.
8ad46d34 3680;; Testcase for the following four peepholes: gcc.dg/cris-peep2-xsrand.c
0b85d816 3681
8ad46d34
HPN
3682(define_peephole2 ; asrandb (peephole casesi+31)
3683 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 3684 (ashiftrt:SI (match_dup 0)
8ad46d34 3685 (match_operand:SI 1 "const_int_operand" "")))
0b85d816
HPN
3686 (set (match_dup 0)
3687 (and:SI (match_dup 0)
8ad46d34 3688 (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
3689 "INTVAL (operands[2]) > 31
3690 && INTVAL (operands[2]) < 255
8ad46d34
HPN
3691 && INTVAL (operands[1]) > 23
3692 /* Check that the and-operation enables us to use logical-shift. */
3693 && (INTVAL (operands[2])
3694 & ((HOST_WIDE_INT) -1 << (32 - INTVAL (operands[1])))) == 0"
3695 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 3696 (set (match_dup 3) (and:QI (match_dup 3) (match_dup 4)))]
8ad46d34 3697 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
3698{
3699 operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));
3700 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), QImode));
3701})
8ad46d34
HPN
3702
3703(define_peephole2 ; asrandw (peephole casesi+32)
3704 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 3705 (ashiftrt:SI (match_dup 0)
8ad46d34 3706 (match_operand:SI 1 "const_int_operand" "")))
0b85d816 3707 (set (match_dup 0)
8ad46d34 3708 (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
3709 "INTVAL (operands[2]) > 31
3710 && INTVAL (operands[2]) < 65535
3711 && INTVAL (operands[2]) != 255
8ad46d34
HPN
3712 && INTVAL (operands[1]) > 15
3713 /* Check that the and-operation enables us to use logical-shift. */
3714 && (INTVAL (operands[2])
3715 & ((HOST_WIDE_INT) -1 << (32 - INTVAL (operands[1])))) == 0"
3716 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 3717 (set (match_dup 3) (and:HI (match_dup 3) (match_dup 4)))]
8ad46d34 3718 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
3719{
3720 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3721 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), HImode));
3722})
8ad46d34
HPN
3723
3724(define_peephole2 ; lsrandb (peephole casesi+33)
3725 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 3726 (lshiftrt:SI (match_dup 0)
8ad46d34 3727 (match_operand:SI 1 "const_int_operand" "")))
0b85d816 3728 (set (match_dup 0)
8ad46d34 3729 (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
3730 "INTVAL (operands[2]) > 31
3731 && INTVAL (operands[2]) < 255
3732 && INTVAL (operands[1]) > 23"
8ad46d34 3733 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 3734 (set (match_dup 3) (and:QI (match_dup 3) (match_dup 4)))]
8ad46d34 3735 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
3736{
3737 operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));
3738 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), QImode));
3739})
0b85d816 3740
8ad46d34
HPN
3741(define_peephole2 ; lsrandw (peephole casesi+34)
3742 [(set (match_operand:SI 0 "register_operand" "")
0b85d816 3743 (lshiftrt:SI (match_dup 0)
8ad46d34 3744 (match_operand:SI 1 "const_int_operand" "")))
0b85d816 3745 (set (match_dup 0)
8ad46d34 3746 (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
0b85d816
HPN
3747 "INTVAL (operands[2]) > 31 && INTVAL (operands[2]) < 65535
3748 && INTVAL (operands[2]) != 255
3749 && INTVAL (operands[1]) > 15"
8ad46d34 3750 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
bf6ac87c 3751 (set (match_dup 3) (and:HI (match_dup 3) (match_dup 4)))]
8ad46d34 3752 ;; FIXME: CC0 is valid except for the M bit.
bf6ac87c
HPN
3753{
3754 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3755 operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[2]), HImode));
3756})
0b85d816
HPN
3757\f
3758
3759;; Change
3760;; add.d n,rx
3761;; move [rx],ry
3762;; into
3763;; move [rx=rx+n],ry
3764;; when -128 <= n <= 127.
3765;; This will reduce the size of the assembler code for n = [-128..127],
8ad46d34
HPN
3766;; and speed up accordingly. Don't match if the previous insn is
3767;; (set rx rz) because that combination is matched by another peephole.
3768;; No stable test-case.
3769
3770(define_peephole2 ; moversideqi (peephole casesi+35)
3771 [(set (match_operand:SI 0 "register_operand" "")
3772 (plus:SI (match_operand:SI 1 "register_operand" "")
3773 (match_operand:SI 2 "const_int_operand" "")))
3774 (set (match_operand 3 "register_operand" "")
3775 (match_operator 4 "cris_mem_op" [(match_dup 0)]))]
3776 "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
3777 && REGNO (operands[3]) != REGNO (operands[0])
3778 && (BASE_P (operands[1]) || BASE_P (operands[2]))
3779 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
3780 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
3781 && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
3782 [(parallel
3783 [(set (match_dup 3) (match_dup 5))
3784 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
3785 ;; Checking the previous insn is a bit too awkward for the condition.
3786{
3787 rtx prev = prev_nonnote_insn (curr_insn);
3788 if (prev != NULL_RTX)
3789 {
3790 rtx set = single_set (prev);
3791 if (set != NULL_RTX
3792 && REG_S_P (SET_DEST (set))
3793 && REGNO (SET_DEST (set)) == REGNO (operands[0])
3794 && REG_S_P (SET_SRC (set)))
3795 FAIL;
3796 }
3797 operands[5]
3798 = replace_equiv_address (operands[4],
3799 gen_rtx_PLUS (SImode,
3800 operands[1], operands[2]));
3801})
0b85d816
HPN
3802
3803;; Vice versa: move ry,[rx=rx+n]
3804
8ad46d34
HPN
3805(define_peephole2 ; movemsideqi (peephole casesi+36)
3806 [(set (match_operand:SI 0 "register_operand" "")
3807 (plus:SI (match_operand:SI 1 "register_operand" "")
3808 (match_operand:SI 2 "const_int_operand" "")))
3809 (set (match_operator 3 "cris_mem_op" [(match_dup 0)])
3810 (match_operand 4 "register_operand" ""))]
3811 "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
3812 && REGNO (operands[4]) != REGNO (operands[0])
3813 && (BASE_P (operands[1]) || BASE_P (operands[2]))
3814 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
3815 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
3816 && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
3817 [(parallel
3818 [(set (match_dup 5) (match_dup 4))
3819 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
3820 "operands[5]
3821 = replace_equiv_address (operands[3],
3822 gen_rtx_PLUS (SImode,
3823 operands[1], operands[2]));")
0b85d816
HPN
3824\f
3825;; As above, change:
3826;; add.d n,rx
3827;; op.d [rx],ry
3828;; into:
3829;; op.d [rx=rx+n],ry
3830;; Saves when n = [-128..127].
3831;;
3832;; Splitting and joining combinations for side-effect modes are slightly
3833;; out of hand. They probably will not save the time they take typing in,
3834;; not to mention the bugs that creep in. FIXME: Get rid of as many of
3835;; the splits and peepholes as possible.
8ad46d34
HPN
3836;; No stable test-case.
3837
3838(define_peephole2 ; mover2side (peephole casesi+37)
3839 [(set (match_operand:SI 0 "register_operand" "")
3840 (plus:SI (match_operand:SI 1 "register_operand" "")
3841 (match_operand:SI 2 "const_int_operand" "")))
3842 (set (match_operand 3 "register_operand" "")
3843 (match_operator 4 "cris_orthogonal_operator"
3844 [(match_dup 3)
3845 (match_operator
3846 5 "cris_mem_op" [(match_dup 0)])]))]
477c433d
HPN
3847 ;; FIXME: What about DFmode?
3848 ;; Change to GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD?
0b85d816 3849 "GET_MODE (operands[3]) != DImode
8ad46d34
HPN
3850 && REGNO (operands[0]) != REGNO (operands[3])
3851 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
3852 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
3853 && INTVAL (operands[2]) >= -128
3854 && INTVAL (operands[2]) <= 127"
3855 [(parallel
3856 [(set (match_dup 3) (match_op_dup 4 [(match_dup 3) (match_dup 6)]))
3857 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
3858 "operands[6]
3859 = replace_equiv_address (operands[5],
3860 gen_rtx_PLUS (SImode,
3861 operands[1], operands[2]));")
0b85d816
HPN
3862
3863;; Sometimes, for some reason the pattern
3864;; move x,rx
3865;; add y,rx
3866;; move [rx],rz
3867;; will occur. Solve this, and likewise for to-memory.
8ad46d34 3868;; No stable test-case.
0b85d816 3869
8ad46d34
HPN
3870(define_peephole2 ; moverside (peephole casesi+38)
3871 [(set (match_operand:SI 0 "register_operand" "")
3872 (match_operand:SI 1 "cris_bdap_biap_operand" ""))
0b85d816 3873 (set (match_dup 0)
8ad46d34
HPN
3874 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "")
3875 (match_operand:SI 3 "cris_bdap_biap_operand" "")))
3876 (set (match_operand 4 "register_operand" "")
3877 (match_operator 5 "cris_mem_op" [(match_dup 0)]))]
0b85d816
HPN
3878 "(rtx_equal_p (operands[2], operands[0])
3879 || rtx_equal_p (operands[3], operands[0]))
3880 && cris_side_effect_mode_ok (PLUS, operands, 0,
8ad46d34
HPN
3881 (REG_S_P (operands[1])
3882 ? 1
3883 : (rtx_equal_p (operands[2], operands[0])
3884 ? 3 : 2)),
3885 (! REG_S_P (operands[1])
3886 ? 1
3887 : (rtx_equal_p (operands[2], operands[0])
3888 ? 3 : 2)),
3889 -1, 4)"
3890 [(parallel
3891 [(set (match_dup 4) (match_dup 6))
3892 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 8)))])]
3893{
e758023d 3894 rtx otherop
8ad46d34
HPN
3895 = rtx_equal_p (operands[2], operands[0]) ? operands[3] : operands[2];
3896
8820e4be
HPN
3897 /* Make sure we have canonical RTX so we match the insn pattern -
3898 not a constant in the first operand. We also require the order
3899 (plus reg mem) to match the final pattern. */
3900 if (CONSTANT_P (otherop) || MEM_P (otherop))
8ad46d34
HPN
3901 {
3902 operands[7] = operands[1];
e758023d 3903 operands[8] = otherop;
8ad46d34
HPN
3904 }
3905 else
3906 {
e758023d 3907 operands[7] = otherop;
8ad46d34
HPN
3908 operands[8] = operands[1];
3909 }
3910 operands[6]
3911 = replace_equiv_address (operands[5],
3912 gen_rtx_PLUS (SImode,
3913 operands[7], operands[8]));
3914})
0b85d816
HPN
3915
3916;; As above but to memory.
8ad46d34
HPN
3917;; FIXME: Split movemside and moverside into variants and prune
3918;; the ones that don't trig.
3919;; No stable test-case.
0b85d816 3920
8ad46d34
HPN
3921(define_peephole2 ; movemside (peephole casesi+39)
3922 [(set (match_operand:SI 0 "register_operand" "")
3923 (match_operand:SI 1 "cris_bdap_biap_operand" ""))
0b85d816 3924 (set (match_dup 0)
8ad46d34
HPN
3925 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "")
3926 (match_operand:SI 3 "cris_bdap_biap_operand" "")))
3927 (set (match_operator 4 "cris_mem_op" [(match_dup 0)])
3928 (match_operand 5 "register_operand" ""))]
0b85d816
HPN
3929 "(rtx_equal_p (operands[2], operands[0])
3930 || rtx_equal_p (operands[3], operands[0]))
3931 && cris_side_effect_mode_ok (PLUS, operands, 0,
8ad46d34
HPN
3932 (REG_S_P (operands[1])
3933 ? 1
3934 : (rtx_equal_p (operands[2], operands[0])
3935 ? 3 : 2)),
3936 (! REG_S_P (operands[1])
3937 ? 1
3938 : (rtx_equal_p (operands[2], operands[0])
3939 ? 3 : 2)),
3940 -1, 5)"
3941 [(parallel
3942 [(set (match_dup 6) (match_dup 5))
3943 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 8)))])]
3944{
e758023d 3945 rtx otherop
8ad46d34 3946 = rtx_equal_p (operands[2], operands[0]) ? operands[3] : operands[2];
0b85d816 3947
8820e4be
HPN
3948 /* Make sure we have canonical RTX so we match the insn pattern -
3949 not a constant in the first operand. We also require the order
3950 (plus reg mem) to match the final pattern. */
3951 if (CONSTANT_P (otherop) || MEM_P (otherop))
8ad46d34
HPN
3952 {
3953 operands[7] = operands[1];
e758023d 3954 operands[8] = otherop;
8ad46d34
HPN
3955 }
3956 else
3957 {
e758023d 3958 operands[7] = otherop;
8ad46d34
HPN
3959 operands[8] = operands[1];
3960 }
3961 operands[6]
3962 = replace_equiv_address (operands[4],
3963 gen_rtx_PLUS (SImode,
3964 operands[7], operands[8]));
3965})
0b85d816
HPN
3966
3967;; Another spotted bad code:
3968;; move rx,ry
3969;; move [ry],ry
8ad46d34 3970;; No stable test-case.
0b85d816 3971
8ad46d34
HPN
3972(define_peephole2 ; movei (peephole casesi+42)
3973 [(set (match_operand:SI 0 "register_operand" "")
3974 (match_operand:SI 1 "register_operand" ""))
3975 (set (match_operand 2 "register_operand" "")
3976 (match_operator 3 "cris_mem_op" [(match_dup 0)]))]
0b85d816 3977 "REGNO (operands[0]) == REGNO (operands[2])
f60c7155
HPN
3978 && (REGNO_REG_CLASS (REGNO (operands[0]))
3979 == REGNO_REG_CLASS (REGNO (operands[1])))
0b85d816 3980 && GET_MODE_SIZE (GET_MODE (operands[2])) <= UNITS_PER_WORD"
8ad46d34
HPN
3981 [(set (match_dup 2) (match_dup 4))]
3982 "operands[4] = replace_equiv_address (operands[3], operands[1]);")
0b85d816 3983
0b85d816
HPN
3984;; move.d [r10+16],r9
3985;; and.d r12,r9
3986;; change to
3987;; and.d [r10+16],r12,r9
3988;; With generalization of the operation, the size and the addressing mode.
3989;; This seems to be the result of a quirk in register allocation
3990;; missing the three-operand cases when having different predicates.
3991;; Maybe that it matters that it is a commutative operation.
3992;; This pattern helps that situation, but there's still the increased
3993;; register pressure.
3994;; Note that adding the noncommutative variant did not show any matches
3995;; in ipps and cc1, so it's not here.
8ad46d34 3996;; No stable test-case.
0b85d816 3997
8ad46d34
HPN
3998(define_peephole2 ; op3 (peephole casesi+44)
3999 [(set (match_operand 0 "register_operand" "")
4000 (match_operator
4001 6 "cris_mem_op"
4002 [(plus:SI
4003 (match_operand:SI 1 "cris_bdap_biap_operand" "")
4004 (match_operand:SI 2 "cris_bdap_biap_operand" ""))]))
0b85d816 4005 (set (match_dup 0)
8ad46d34
HPN
4006 (match_operator
4007 5 "cris_commutative_orth_op"
4008 [(match_operand 3 "register_operand" "")
4009 (match_operand 4 "register_operand" "")]))]
0b85d816
HPN
4010 "(rtx_equal_p (operands[3], operands[0])
4011 || rtx_equal_p (operands[4], operands[0]))
4012 && ! rtx_equal_p (operands[3], operands[4])
4013 && (REG_S_P (operands[1]) || REG_S_P (operands[2]))
4014 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD"
8ad46d34
HPN
4015 [(set (match_dup 0) (match_op_dup 5 [(match_dup 7) (match_dup 6)]))]
4016 "operands[7]
4017 = rtx_equal_p (operands[3], operands[0]) ? operands[4] : operands[3];")
0b85d816 4018
0b85d816
HPN
4019;; I cannot tell GCC (2.1, 2.7.2) how to correctly reload an instruction
4020;; that looks like
4021;; and.b some_byte,const,reg_32
4022;; where reg_32 is the destination of the "three-address" code optimally.
4023;; It should be:
4024;; movu.b some_byte,reg_32
4025;; and.b const,reg_32
4026;; but is turns into:
4027;; move.b some_byte,reg_32
4028;; and.d const,reg_32
4029;; Fix it here.
8ad46d34 4030;; Testcases: gcc.dg/cris-peep2-andu1.c gcc.dg/cris-peep2-andu2.c
0b85d816 4031
8ad46d34
HPN
4032(define_peephole2 ; andu (casesi+45)
4033 [(set (match_operand:SI 0 "register_operand" "")
4034 (match_operand:SI 1 "nonimmediate_operand" ""))
4035 (set (match_operand:SI 2 "register_operand" "")
0b85d816 4036 (and:SI (match_dup 0)
8ad46d34 4037 (match_operand:SI 3 "const_int_operand" "")))]
0b85d816
HPN
4038 ;; Since the size of the memory access could be made different here,
4039 ;; don't do this for a mem-volatile access.
0b85d816
HPN
4040 "REGNO (operands[2]) == REGNO (operands[0])
4041 && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
c3e786e7
HPN
4042 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
4043 && !side_effects_p (operands[1])"
8ad46d34
HPN
4044 ;; FIXME: CC0 valid except for M (i.e. CC_NOT_NEGATIVE).
4045 [(set (match_dup 0) (match_dup 4))
4046 (set (match_dup 5) (match_dup 6))]
0b85d816 4047{
8ad46d34
HPN
4048 enum machine_mode zmode = INTVAL (operands[3]) <= 255 ? QImode : HImode;
4049 enum machine_mode amode
4050 = CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O') ? SImode : zmode;
4051 rtx op1
4052 = (REG_S_P (operands[1])
4053 ? gen_rtx_REG (zmode, REGNO (operands[1]))
4054 : adjust_address (operands[1], zmode, 0));
4055 operands[4]
4056 = gen_rtx_ZERO_EXTEND (SImode, op1);
4057 operands[5] = gen_rtx_REG (amode, REGNO (operands[0]));
4058 operands[6]
4059 = gen_rtx_AND (amode, gen_rtx_REG (amode, REGNO (operands[0])),
4060 GEN_INT (trunc_int_for_mode (INTVAL (operands[3]),
4061 amode == SImode
4062 ? QImode : amode)));
4063})
c00fc5cf
HPN
4064
4065;; Try and avoid GOTPLT reads escaping a call: transform them into
4066;; PLT. Curiously (but thankfully), peepholes for instructions
4067;; *without side-effects* that just feed a call (or call_value) are
4068;; not matched neither in a build or test-suite, so those patterns are
4069;; omitted.
4070
4071;; A "normal" move where we don't check the consumer.
4072
4073(define_peephole2 ; gotplt-to-plt
4074 [(set
4075 (match_operand:SI 0 "register_operand" "")
4076 (match_operator:SI
4077 1 "cris_mem_op"
4078 [(plus:SI
4079 (reg:SI CRIS_GOT_REGNUM)
4080 (const:SI
4081 (unspec:SI [(match_operand:SI 2 "cris_general_operand_or_symbol" "")]
4082 CRIS_UNSPEC_PLTGOTREAD)))]))]
4083 "flag_pic
4084 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1))
4085 && REGNO_REG_CLASS (REGNO (operands[0])) == REGNO_REG_CLASS (0)"
4086 [(set (match_dup 0) (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLT)))
4087 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI CRIS_GOT_REGNUM)))]
4088 "")
4089
4090;; And one set with a side-effect getting the PLTGOT offset.
4091;; First call and call_value variants.
4092
4093(define_peephole2 ; gotplt-to-plt-side-call
4094 [(parallel
4095 [(set
4096 (match_operand:SI 0 "register_operand" "")
4097 (match_operator:SI
4098 1 "cris_mem_op"
4099 [(plus:SI
4100 (reg:SI CRIS_GOT_REGNUM)
4101 (const:SI
4102 (unspec:SI [(match_operand:SI
4103 2 "cris_general_operand_or_symbol" "")]
4104 CRIS_UNSPEC_PLTGOTREAD)))]))
4105 (set (match_operand:SI 3 "register_operand" "")
4106 (plus:SI (reg:SI CRIS_GOT_REGNUM)
4107 (const:SI
4108 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])
4109 (parallel [(call (mem:QI (match_dup 0))
4110 (match_operand 4 "" ""))
4111 (clobber (reg:SI CRIS_SRP_REGNUM))])]
4112 "flag_pic
4113 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1))
4114 && peep2_reg_dead_p (2, operands[0])"
4115 [(parallel [(call (mem:QI (match_dup 1))
4116 (match_dup 4))
4117 (clobber (reg:SI CRIS_SRP_REGNUM))
4118 (set (match_dup 3)
4119 (plus:SI (reg:SI CRIS_GOT_REGNUM)
4120 (const:SI
4121 (unspec:SI [(match_dup 2)]
4122 CRIS_UNSPEC_PLTGOTREAD))))])]
4123 "")
4124
4125(define_peephole2 ; gotplt-to-plt-side-call-value
4126 [(parallel
4127 [(set
4128 (match_operand:SI 0 "register_operand" "")
4129 (match_operator:SI
4130 1 "cris_mem_op"
4131 [(plus:SI
4132 (reg:SI CRIS_GOT_REGNUM)
4133 (const:SI
4134 (unspec:SI [(match_operand:SI
4135 2 "cris_general_operand_or_symbol" "")]
4136 CRIS_UNSPEC_PLTGOTREAD)))]))
4137 (set (match_operand:SI 3 "register_operand" "")
4138 (plus:SI (reg:SI CRIS_GOT_REGNUM)
4139 (const:SI
4140 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])
4141 (parallel [(set (match_operand 5 "" "")
4142 (call (mem:QI (match_dup 0))
4143 (match_operand 4 "" "")))
4144 (clobber (reg:SI CRIS_SRP_REGNUM))])]
4145 "flag_pic
4146 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1))
4147 && peep2_reg_dead_p (2, operands[0])"
4148 [(parallel [(set (match_dup 5)
4149 (call (mem:QI (match_dup 1))
4150 (match_dup 4)))
4151 (clobber (reg:SI CRIS_SRP_REGNUM))
4152 (set (match_dup 3)
4153 (plus:SI (reg:SI CRIS_GOT_REGNUM)
4154 (const:SI
4155 (unspec:SI [(match_dup 2)]
4156 CRIS_UNSPEC_PLTGOTREAD))))])]
4157 "")
4158
4159(define_peephole2 ; gotplt-to-plt-side
4160 [(parallel
4161 [(set
4162 (match_operand:SI 0 "register_operand" "")
4163 (match_operator:SI
4164 1 "cris_mem_op"
4165 [(plus:SI
4166 (reg:SI CRIS_GOT_REGNUM)
4167 (const:SI
4168 (unspec:SI [(match_operand:SI
4169 2 "cris_general_operand_or_symbol" "")]
4170 CRIS_UNSPEC_PLTGOTREAD)))]))
4171 (set (match_operand:SI 3 "register_operand" "")
4172 (plus:SI (reg:SI CRIS_GOT_REGNUM)
4173 (const:SI
4174 (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD))))])]
4175 "flag_pic
4176 && cris_valid_pic_const (XEXP (XEXP (operands[1], 0), 1))
4177 && REGNO_REG_CLASS (REGNO (operands[0])) == REGNO_REG_CLASS (0)"
4178 [(set (match_dup 3)
4179 (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLTGOTREAD)))
4180 (set (match_dup 3) (plus:SI (match_dup 3) (reg:SI CRIS_GOT_REGNUM)))
4181 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 2)] CRIS_UNSPEC_PLT)))
4182 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI CRIS_GOT_REGNUM)))]
4183 "")
0b85d816
HPN
4184\f
4185;; Local variables:
4186;; mode:emacs-lisp
4187;; comment-start: ";; "
4188;; eval: (set-syntax-table (copy-sequence (syntax-table)))
4189;; eval: (modify-syntax-entry ?[ "(]")
4190;; eval: (modify-syntax-entry ?] ")[")
4191;; eval: (modify-syntax-entry ?{ "(}")
4192;; eval: (modify-syntax-entry ?} "){")
4193;; eval: (setq indent-tabs-mode t)
4194;; End: