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