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