]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/cris/cris.md
* gcc.c-torture/execute/20020529-1.c: New test.
[thirdparty/gcc.git] / gcc / config / cris / cris.md
CommitLineData
0b85d816
HPN
1;; GCC machine description for CRIS cpu cores.
2;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
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
37;; fixed in egcs post 1.1.1, so FIXME: try again.
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
324;; extends subregs for lower-size modes. FIXME: Add test-case.
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
388 CVS, version -r 1.5), and it believe that the high part (the last one
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")
499 (match_operand:SI 2 "cris_bdap_operand" "r>Ri,r,>Ri"))))
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")
522 (match_operand:SI 2 "cris_bdap_operand" "r>Ri,r,>Ri"))))
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")
545 (match_operand:SI 2 "cris_bdap_operand" "r>Ri,r,>Ri"))))
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
564;; For all side-effect patterns, it seems to be the case that the
565;; predicate isn't consulted after combine. For sake of stability, we
566;; recognize and split the cases where dangerous register combinations are
567;; spotted: where a register is set in the side-effect, and used in the
568;; main insn. We don't handle the case where the set in the main insn
569;; overlaps the set in the side-effect; that would be too big a bug to
570;; paper over. We handle just the case where the set in the side-effect
571;; overlaps the input operand of the main insn (i.e. just moves to memory).
572
573;;
574;; move.s rx,[ry=rx+rw.S]
575;; FIXME: These could have anonymous mode for operand 3.
576
577;; QImode
578
579(define_insn "*mov_sideqi_biap_mem"
580 [(set (mem:QI (plus:SI
581 (mult:SI (match_operand:SI 0 "register_operand" "r,r,r")
582 (match_operand:SI 1 "const_int_operand" "n,n,n"))
583 (match_operand:SI 2 "register_operand" "r,r,r")))
584 (match_operand:QI 3 "register_operand" "r,r,r"))
585 (set (match_operand:SI 4 "register_operand" "=*2,!*3,r")
586 (plus:SI (mult:SI (match_dup 0)
587 (match_dup 1))
588 (match_dup 2)))]
589 "cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
590 "@
591 #
592 #
593 move.%s3 %3,[%4=%2+%0%T1]")
594
595;; HImode
596
597(define_insn "*mov_sidehi_biap_mem"
598 [(set (mem:HI (plus:SI
599 (mult:SI (match_operand:SI 0 "register_operand" "r,r,r")
600 (match_operand:SI 1 "const_int_operand" "n,n,n"))
601 (match_operand:SI 2 "register_operand" "r,r,r")))
602 (match_operand:HI 3 "register_operand" "r,r,r"))
603 (set (match_operand:SI 4 "register_operand" "=*2,!*3,r")
604 (plus:SI (mult:SI (match_dup 0)
605 (match_dup 1))
606 (match_dup 2)))]
607 "cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
608 "@
609 #
610 #
611 move.%s3 %3,[%4=%2+%0%T1]")
612
613;; SImode
614
615(define_insn "*mov_sidesi_biap_mem"
616 [(set (mem:SI (plus:SI
617 (mult:SI (match_operand:SI 0 "register_operand" "r,r,r")
618 (match_operand:SI 1 "const_int_operand" "n,n,n"))
619 (match_operand:SI 2 "register_operand" "r,r,r")))
620 (match_operand:SI 3 "register_operand" "r,r,r"))
621 (set (match_operand:SI 4 "register_operand" "=*2,!*3,r")
622 (plus:SI (mult:SI (match_dup 0)
623 (match_dup 1))
624 (match_dup 2)))]
625 "cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
626 "@
627 #
628 #
629 move.%s3 %3,[%4=%2+%0%T1]")
630
631;; Split for the case above where the predicate isn't honored; only the
632;; constraint, and we end up with the set in the side-effect gets the same
633;; register as the input register. Arguably a GCC bug, but we'll spot it
634;; rarely enough that we need to catch it ourselves to be safe.
635
636(define_split
637 [(parallel
638 [(set (mem (plus:SI
639 (mult:SI (match_operand:SI 0 "register_operand" "")
640 (match_operand:SI 1 "const_int_operand" ""))
641 (match_operand:SI 2 "register_operand" "")))
642 (match_operand 3 "register_operand" ""))
643 (set (match_operand:SI 4 "register_operand" "")
644 (plus:SI (mult:SI (match_dup 0)
645 (match_dup 1))
646 (match_dup 2)))])]
647 "reload_completed && reg_overlap_mentioned_p (operands[4], operands[3])"
648 [(set (match_dup 5) (match_dup 3))
649 (set (match_dup 4) (match_dup 2))
650 (set (match_dup 4)
651 (plus:SI (mult:SI (match_dup 0)
652 (match_dup 1))
653 (match_dup 4)))]
654 "operands[5]
655 = gen_rtx_MEM (GET_MODE (operands[3]),
656 gen_rtx_PLUS (SImode,
657 gen_rtx_MULT (SImode,
658 operands[0], operands[1]),
659 operands[2]));")
660\f
661;; move.s rx,[ry=rz+i]
662;; FIXME: These could have anonymous mode for operand 2.
663
664;; QImode
665
666(define_insn "*mov_sideqi_mem"
667 [(set (mem:QI
668 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
669 (match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
670 (match_operand:QI 2 "register_operand" "r,r,r,r"))
671 (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r")
672 (plus:SI (match_dup 0)
673 (match_dup 1)))]
674 "cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
675 "*
676{
677 if (which_alternative == 0
678 && (GET_CODE (operands[1]) != CONST_INT
679 || INTVAL (operands[1]) > 127
680 || INTVAL (operands[1]) < -128
681 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
682 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
683 return \"#\";
684 if (which_alternative == 1)
685 return \"#\";
686 return \"move.%s2 %2,[%3=%0%S1]\";
687}")
688
689;; HImode
690
691(define_insn "*mov_sidehi_mem"
692 [(set (mem:HI
693 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
694 (match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
695 (match_operand:HI 2 "register_operand" "r,r,r,r"))
696 (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r")
697 (plus:SI (match_dup 0)
698 (match_dup 1)))]
699 "cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
700 "*
701{
702 if (which_alternative == 0
703 && (GET_CODE (operands[1]) != CONST_INT
704 || INTVAL (operands[1]) > 127
705 || INTVAL (operands[1]) < -128
706 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
707 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
708 return \"#\";
709 if (which_alternative == 1)
710 return \"#\";
711 return \"move.%s2 %2,[%3=%0%S1]\";
712}")
713
714;; SImode
715
716(define_insn "*mov_sidesi_mem"
717 [(set (mem:SI
718 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
719 (match_operand:SI 1 "cris_bdap_operand" "r>Ri,r>Ri,r,>Ri")))
720 (match_operand:SI 2 "register_operand" "r,r,r,r"))
721 (set (match_operand:SI 3 "register_operand" "=*0,!*2,r,r")
722 (plus:SI (match_dup 0)
723 (match_dup 1)))]
724 "cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
725 "*
726{
727 if (which_alternative == 0
728 && (GET_CODE (operands[1]) != CONST_INT
729 || INTVAL (operands[1]) > 127
730 || INTVAL (operands[1]) < -128
731 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
732 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
733 return \"#\";
734 if (which_alternative == 1)
735 return \"#\";
736 return \"move.%s2 %2,[%3=%0%S1]\";
737}")
738
739;; Like the biap case, a split where the set in the side-effect gets the
740;; same register as the input register to the main insn due to gcc not
741;; always checking the predicate.
742
743(define_split
744 [(parallel
745 [(set (mem (plus:SI
746 (match_operand:SI 0 "cris_bdap_operand" "")
747 (match_operand:SI 1 "cris_bdap_operand" "")))
748 (match_operand:SI 2 "register_operand" ""))
749 (set (match_operand:SI 3 "register_operand" "")
750 (plus:SI (match_dup 0) (match_dup 1)))])]
751 "reload_completed && reg_overlap_mentioned_p (operands[3], operands[2])"
752 [(set (match_dup 4) (match_dup 2))
753 (set (match_dup 3) (match_dup 0))
754 (set (match_dup 3) (plus:SI (match_dup 3) (match_dup 1)))]
755 "operands[4]
756 = gen_rtx_MEM (GET_MODE (operands[2]),
757 gen_rtx_PLUS (SImode, operands[0], operands[1]));")
758\f
759;; Clear memory side-effect patterns. It is hard to get to the mode if
760;; the MEM was anonymous, so there will be one for each mode.
761
762;; clear.d [ry=rx+rw.s2]
763
764(define_insn "*clear_sidesi_biap"
765 [(set (mem:SI (plus:SI
766 (mult:SI (match_operand:SI 0 "register_operand" "r,r")
767 (match_operand:SI 1 "const_int_operand" "n,n"))
768 (match_operand:SI 2 "register_operand" "r,r")))
769 (const_int 0))
770 (set (match_operand:SI 3 "register_operand" "=*2,r")
771 (plus:SI (mult:SI (match_dup 0)
772 (match_dup 1))
773 (match_dup 2)))]
774 "cris_side_effect_mode_ok (MULT, operands, 3, 2, 0, 1, -1)"
775 "@
776 #
777 clear.d [%3=%2+%0%T1]")
778
779;; clear.d [ry=rz+i]
780
781(define_insn "*clear_sidesi"
782 [(set (mem:SI
783 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r")
784 (match_operand:SI 1 "cris_bdap_operand" "r>Ri,r,>Ri")))
785 (const_int 0))
786 (set (match_operand:SI 2 "register_operand" "=*0,r,r")
787 (plus:SI (match_dup 0)
788 (match_dup 1)))]
789 "cris_side_effect_mode_ok (PLUS, operands, 2, 0, 1, -1, -1)"
790 "*
791{
792 if (which_alternative == 0
793 && (GET_CODE (operands[1]) != CONST_INT
794 || INTVAL (operands[1]) > 127
795 || INTVAL (operands[1]) < -128
796 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
797 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
798 return \"#\";
799 return \"clear.d [%2=%0%S1]\";
800}")
801
802;; clear.w [ry=rx+rw.s2]
803
804(define_insn "*clear_sidehi_biap"
805 [(set (mem:HI (plus:SI
806 (mult:SI (match_operand:SI 0 "register_operand" "r,r")
807 (match_operand:SI 1 "const_int_operand" "n,n"))
808 (match_operand:SI 2 "register_operand" "r,r")))
809 (const_int 0))
810 (set (match_operand:SI 3 "register_operand" "=*2,r")
811 (plus:SI (mult:SI (match_dup 0)
812 (match_dup 1))
813 (match_dup 2)))]
814 "cris_side_effect_mode_ok (MULT, operands, 3, 2, 0, 1, -1)"
815 "@
816 #
817 clear.w [%3=%2+%0%T1]")
818
819;; clear.w [ry=rz+i]
820
821(define_insn "*clear_sidehi"
822 [(set (mem:HI
823 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r")
824 (match_operand:SI 1 "cris_bdap_operand" "r>Ri,r,>Ri")))
825 (const_int 0))
826 (set (match_operand:SI 2 "register_operand" "=*0,r,r")
827 (plus:SI (match_dup 0)
828 (match_dup 1)))]
829 "cris_side_effect_mode_ok (PLUS, operands, 2, 0, 1, -1, -1)"
830 "*
831{
832 if (which_alternative == 0
833 && (GET_CODE (operands[1]) != CONST_INT
834 || INTVAL (operands[1]) > 127
835 || INTVAL (operands[1]) < -128
836 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
837 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
838 return \"#\";
839 return \"clear.w [%2=%0%S1]\";
840}")
841
842;; clear.b [ry=rx+rw.s2]
843
844(define_insn "*clear_sideqi_biap"
845 [(set (mem:QI (plus:SI
846 (mult:SI (match_operand:SI 0 "register_operand" "r,r")
847 (match_operand:SI 1 "const_int_operand" "n,n"))
848 (match_operand:SI 2 "register_operand" "r,r")))
849 (const_int 0))
850 (set (match_operand:SI 3 "register_operand" "=*2,r")
851 (plus:SI (mult:SI (match_dup 0)
852 (match_dup 1))
853 (match_dup 2)))]
854 "cris_side_effect_mode_ok (MULT, operands, 3, 2, 0, 1, -1)"
855 "@
856 #
857 clear.b [%3=%2+%0%T1]")
858
859;; clear.b [ry=rz+i]
860
861(define_insn "*clear_sideqi"
862 [(set (mem:QI
863 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r")
864 (match_operand:SI 1 "cris_bdap_operand" "r>Ri,r,>Ri")))
865 (const_int 0))
866 (set (match_operand:SI 2 "register_operand" "=*0,r,r")
867 (plus:SI (match_dup 0)
868 (match_dup 1)))]
869 "cris_side_effect_mode_ok (PLUS, operands, 2, 0, 1, -1, -1)"
870 "*
871{
872 if (which_alternative == 0
873 && (GET_CODE (operands[1]) != CONST_INT
874 || INTVAL (operands[1]) > 127
875 || INTVAL (operands[1]) < -128
876 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
877 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
878 return \"#\";
879 return \"clear.b [%2=%0%S1]\";
880}")
881\f
882;; To appease test-case gcc.c-torture/execute/920501-2.c (and others) at
883;; -O0, we need a movdi as a temporary measure. Here's how things fail:
884;; A cmpdi RTX needs reloading (global):
885;; (insn 185 326 186 (set (cc0)
886;; (compare (mem/f:DI (reg/v:SI 22) 0)
887;; (const_int 1 [0x1]))) 4 {cmpdi} (nil)
888;; (nil))
889;; Now, reg 22 is reloaded for input address, and the mem is also moved
890;; out of the instruction (into a register), since one of the operands
891;; must be a register. Reg 22 is reloaded (into reg 10), and the mem is
892;; moved out and synthesized in SImode parts (reg 9, reg 10 - should be ok
893;; wrt. overlap). The bad things happen with the synthesis in
894;; emit_move_insn_1; the location where to substitute reg 10 is lost into
895;; two new RTX:es, both still having reg 22. Later on, the left-over reg
896;; 22 is recognized to have an equivalent in memory which is substituted
897;; straight in, and we end up with an unrecognizable insn:
898;; (insn 325 324 326 (set (reg:SI 9 r9)
899;; (mem/f:SI (mem:SI (plus:SI (reg:SI 8 r8)
900;; (const_int -84 [0xffffffac])) 0) 0)) -1 (nil)
901;; (nil))
902;; which is the first part of the reloaded synthesized "movdi".
903;; The right thing would be to add equivalent replacement locations for
904;; insn with pseudos that need more reloading. The question is where.
905
906;; Normal move patterns from SI on.
907
908(define_expand "movsi"
909 [(set
910 (match_operand:SI 0 "nonimmediate_operand" "")
911 (match_operand:SI 1 "cris_general_operand_or_symbol" ""))]
912 ""
913 "
914{
915 /* If the output goes to a MEM, make sure we have zero or a register as
916 input. */
917 if (GET_CODE (operands[0]) == MEM
918 && ! REG_S_P (operands[1])
919 && operands[1] != const0_rtx
920 && ! no_new_pseudos)
921 operands[1] = force_reg (SImode, operands[1]);
922
923 /* If we're generating PIC and have an incoming symbol, validize it to a
924 general operand or something that will match a special pattern.
925
926 FIXME: Do we *have* to recognize anything that would normally be a
927 valid symbol? Can we exclude global PIC addresses with an added
928 offset? */
929 if (flag_pic
930 && CONSTANT_ADDRESS_P (operands[1])
931 && cris_symbol (operands[1]))
932 {
933 /* We must have a register as destination for what we're about to
934 do, and for the patterns we generate. */
935 if (! REG_S_P (operands[0]))
936 {
937 if (no_new_pseudos)
938 abort ();
939 operands[1] = force_reg (SImode, operands[1]);
940 }
941 else
942 {
943 /* Mark a needed PIC setup for a LABEL_REF:s coming in here:
944 they are so rare not-being-branch-targets that we don't mark
945 a function as needing PIC setup just because we have
946 inspected LABEL_REF:s as operands. It is only in
947 __builtin_setjmp and such that we can get a LABEL_REF
948 assigned to a register. */
949 if (GET_CODE (operands[1]) == LABEL_REF)
950 current_function_uses_pic_offset_table = 1;
951
952 /* We don't have to do anything for global PIC operands; they
953 look just like ``[rPIC+sym]''. */
954 if (! cris_got_symbol (operands[1])
955 /* We don't do anything for local PIC operands; we match
956 that with a special alternative. */
957 && ! cris_gotless_symbol (operands[1]))
958 {
959 /* We get here when we have to change something that would
960 be recognizable if it wasn't PIC. A ``sym'' is ok for
961 PIC symbols both with and without a GOT entry. And ``sym
962 + offset'' is ok for local symbols, so the only thing it
963 could be, is a global symbol with an offset. Check and
964 abort if not. */
965 rtx sym = get_related_value (operands[1]);
966 HOST_WIDE_INT offs = get_integer_term (operands[1]);
967
968 if (sym == NULL_RTX || offs == 0)
969 abort ();
970 emit_move_insn (operands[0], sym);
971 if (expand_binop (SImode, add_optab, operands[0],
972 GEN_INT (offs), operands[0], 0,
973 OPTAB_LIB_WIDEN) != operands[0])
974 abort ();
975 DONE;
976 }
977 }
978 }
979}")
980
981(define_insn "*movsi_internal"
982 [(set
983 (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Q>,r,Q>,g,r,r,r,g")
984 (match_operand:SI 1
985 ;; FIXME: We want to put S last, but apparently g matches S.
986 ;; It's a bug: an S is not a general_operand and shouldn't match g.
987 "cris_general_operand_or_gotless_symbol" "r,Q>,M,M,I,r,M,n,!S,g,r"))]
988 ""
989 "*
990{
991 /* Better to have c-switch here; it is worth it to optimize the size of
992 move insns. The alternative would be to try to find more constraint
993 letters. FIXME: Check again. It seems this could shrink a bit. */
994 switch (which_alternative)
995 {
996 case 0:
997 case 1:
998 case 5:
999 case 9:
1000 case 10:
1001 return \"move.d %1,%0\";
1002
1003 case 2:
1004 case 3:
1005 case 6:
1006 return \"clear.d %0\";
1007
1008 /* Constants -32..31 except 0. */
1009 case 4:
1010 return \"moveq %1,%0\";
1011
1012 /* We can win a little on constants -32768..-33, 32..65535. */
1013 case 7:
1014 if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) < 65536)
1015 {
1016 if (INTVAL (operands[1]) < 256)
1017 return \"movu.b %1,%0\";
1018 return \"movu.w %1,%0\";
1019 }
1020 else if (INTVAL (operands[1]) >= -32768 && INTVAL (operands[1]) < 32768)
1021 {
1022 if (INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) < 128)
1023 return \"movs.b %1,%0\";
1024 return \"movs.w %1,%0\";
1025 }
1026 return \"move.d %1,%0\";
1027
1028 case 8:
1029 /* FIXME: Try and split this into pieces GCC makes better code of,
1030 than this multi-insn pattern. Synopsis: wrap the GOT-relative
1031 symbol into an unspec, and when PIC, recognize the unspec
1032 everywhere a symbol is normally recognized. (The PIC register
1033 should be recognized by GCC as pic_offset_table_rtx when needed
1034 and similar for PC.) Each component can then be optimized with
1035 the rest of the code; it should be possible to have a constant
1036 term added on an unspec. Don't forget to add a REG_EQUAL (or
1037 is it REG_EQUIV) note to the destination. It might not be
1038 worth it. Measure.
1039
1040 Note that the 'v' modifier makes PLT references be output as
1041 sym:PLT rather than [rPIC+sym:GOTPLT]. */
1042 return \"move.d %v1,%0\;add.d %P1,%0\";
1043
1044 default:
1045 return \"BOGUS: %1 to %0\";
1046 }
1047}"
1048 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,no,no,no")])
1049\f
1050;; Extend operations with side-effect from mem to register, using
1051;; MOVS/MOVU. These are from mem to register only.
1052;;
1053;; [rx=ry+rz.S]
1054;;
1055;; QImode to HImode
1056;;
1057;; FIXME: Can we omit extend to HImode, since GCC should truncate for
1058;; HImode by itself? Perhaps use only anonymous modes?
1059
1060(define_insn "*ext_sideqihi_biap"
1061 [(set (match_operand:HI 0 "register_operand" "=r,r")
1062 (match_operator:HI
1063 5 "cris_extend_operator"
1064 [(mem:QI (plus:SI
1065 (mult:SI (match_operand:SI 1 "register_operand" "r,r")
1066 (match_operand:SI 2 "const_int_operand" "n,n"))
1067 (match_operand:SI 3 "register_operand" "r,r")))]))
1068 (set (match_operand:SI 4 "register_operand" "=*3,r")
1069 (plus:SI (mult:SI (match_dup 1)
1070 (match_dup 2))
1071 (match_dup 3)))]
1072 "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
1073 "@
1074 #
1075 mov%e5.%m5 [%4=%3+%1%T2],%0")
1076
1077;; QImode to SImode
1078
1079(define_insn "*ext_sideqisi_biap"
1080 [(set (match_operand:SI 0 "register_operand" "=r,r")
1081 (match_operator:SI
1082 5 "cris_extend_operator"
1083 [(mem:QI (plus:SI
1084 (mult:SI (match_operand:SI 1 "register_operand" "r,r")
1085 (match_operand:SI 2 "const_int_operand" "n,n"))
1086 (match_operand:SI 3 "register_operand" "r,r")))]))
1087 (set (match_operand:SI 4 "register_operand" "=*3,r")
1088 (plus:SI (mult:SI (match_dup 1)
1089 (match_dup 2))
1090 (match_dup 3)))]
1091 "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
1092 "@
1093 #
1094 mov%e5.%m5 [%4=%3+%1%T2],%0")
1095
1096;; HImode to SImode
1097
1098(define_insn "*ext_sidehisi_biap"
1099 [(set (match_operand:SI 0 "register_operand" "=r,r")
1100 (match_operator:SI
1101 5 "cris_extend_operator"
1102 [(mem:HI (plus:SI
1103 (mult:SI (match_operand:SI 1 "register_operand" "r,r")
1104 (match_operand:SI 2 "const_int_operand" "n,n"))
1105 (match_operand:SI 3 "register_operand" "r,r")))]))
1106 (set (match_operand:SI 4 "register_operand" "=*3,r")
1107 (plus:SI (mult:SI (match_dup 1)
1108 (match_dup 2))
1109 (match_dup 3)))]
1110 "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
1111 "@
1112 #
1113 mov%e5.%m5 [%4=%3+%1%T2],%0")
1114\f
1115;; Same but [rx=ry+i]
1116
1117;; QImode to HImode
1118
1119(define_insn "*ext_sideqihi"
1120 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1121 (match_operator:HI
1122 4 "cris_extend_operator"
1123 [(mem:QI (plus:SI
1124 (match_operand:SI 1 "cris_bdap_operand" "%r,r,r")
1125 (match_operand:SI 2 "cris_bdap_operand" "r>Ri,r,>Ri")))]))
1126 (set (match_operand:SI 3 "register_operand" "=*1,r,r")
1127 (plus:SI (match_dup 1)
1128 (match_dup 2)))]
1129 "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
1130 "*
1131{
1132 if (which_alternative == 0
1133 && (GET_CODE (operands[2]) != CONST_INT
1134 || INTVAL (operands[2]) > 127
1135 || INTVAL (operands[2]) < -128
1136 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
1137 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
1138 return \"#\";
1139 return \"mov%e4.%m4 [%3=%1%S2],%0\";
1140}")
1141
1142;; QImode to SImode
1143
1144(define_insn "*ext_sideqisi"
1145 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1146 (match_operator:SI
1147 4 "cris_extend_operator"
1148 [(mem:QI (plus:SI
1149 (match_operand:SI 1 "cris_bdap_operand" "%r,r,r")
1150 (match_operand:SI 2 "cris_bdap_operand" "r>Ri,r,>Ri")))]))
1151 (set (match_operand:SI 3 "register_operand" "=*1,r,r")
1152 (plus:SI (match_dup 1)
1153 (match_dup 2)))]
1154 "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
1155 "*
1156{
1157 if (which_alternative == 0
1158 && (GET_CODE (operands[2]) != CONST_INT
1159 || INTVAL (operands[2]) > 127
1160 || INTVAL (operands[2]) < -128
1161 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
1162 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
1163 return \"#\";
1164 return \"mov%e4.%m4 [%3=%1%S2],%0\";
1165}")
1166
1167;; HImode to SImode
1168
1169(define_insn "*ext_sidehisi"
1170 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1171 (match_operator:SI
1172 4 "cris_extend_operator"
1173 [(mem:HI (plus:SI
1174 (match_operand:SI 1 "cris_bdap_operand" "%r,r,r")
1175 (match_operand:SI 2 "cris_bdap_operand" "r>Ri,r,>Ri")))]))
1176 (set (match_operand:SI 3 "register_operand" "=*1,r,r")
1177 (plus:SI (match_dup 1)
1178 (match_dup 2)))]
1179 "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
1180 "*
1181{
1182 if (which_alternative == 0
1183 && (GET_CODE (operands[2]) != CONST_INT
1184 || INTVAL (operands[2]) > 127
1185 || INTVAL (operands[2]) < -128
1186 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
1187 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
1188 return \"#\";
1189 return \"mov%e4.%m4 [%3=%1%S2],%0\";
1190}")
1191\f
1192;; FIXME: See movsi.
1193
1194(define_insn "movhi"
1195 [(set
1196 (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q>,r,Q>,r,r,r,g,g,r")
1197 (match_operand:HI 1 "general_operand" "r,Q>,M,M,I,r,L,O,n,M,r,g"))]
1198 ""
1199 "*
1200{
1201 switch (which_alternative)
1202 {
1203 case 0:
1204 case 1:
1205 case 5:
1206 case 10:
1207 case 11:
1208 return \"move.w %1,%0\";
1209 case 2:
1210 case 3:
1211 case 9:
1212 return \"clear.w %0\";
1213 case 4:
1214 return \"moveq %1,%0\";
1215 case 6:
1216 case 8:
1217 if (INTVAL (operands[1]) < 256 && INTVAL (operands[1]) >= -128)
1218 {
1219 if (INTVAL (operands[1]) > 0)
1220 return \"movu.b %1,%0\";
1221 return \"movs.b %1,%0\";
1222 }
1223 return \"move.w %1,%0\";
1224 case 7:
1225 return \"movEq %b1,%0\";
1226 default:
1227 return \"BOGUS: %1 to %0\";
1228 }
1229}"
1230 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,yes,no,no,no,no")
1231 (set (attr "cc")
1232 (if_then_else (eq_attr "alternative" "7")
1233 (const_string "clobber")
1234 (const_string "normal")))])
1235
1236(define_insn "movstricthi"
1237 [(set
1238 (strict_low_part
1239 (match_operand:HI 0 "nonimmediate_operand" "+r,r,r,Q>,Q>,g,r,g"))
1240 (match_operand:HI 1 "general_operand" "r,Q>,M,M,r,M,g,r"))]
1241 ""
1242 "@
1243 move.w %1,%0
1244 move.w %1,%0
1245 clear.w %0
1246 clear.w %0
1247 move.w %1,%0
1248 clear.w %0
1249 move.w %1,%0
1250 move.w %1,%0"
1251 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
1252\f
1253(define_insn "movqi"
1254 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,Q>,r,r,Q>,r,g,g,r,r")
1255 (match_operand:QI 1 "general_operand" "r,r,Q>,M,M,I,M,r,O,g"))]
1256 ""
1257 "@
1258 move.b %1,%0
1259 move.b %1,%0
1260 move.b %1,%0
1261 clear.b %0
1262 clear.b %0
1263 moveq %1,%0
1264 clear.b %0
1265 move.b %1,%0
1266 moveq %b1,%0
1267 move.b %1,%0"
1268 [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,yes,no")
1269 (set (attr "cc")
1270 (if_then_else (eq_attr "alternative" "8")
1271 (const_string "clobber")
1272 (const_string "normal")))])
1273
1274(define_insn "movstrictqi"
1275 [(set (strict_low_part
1276 (match_operand:QI 0 "nonimmediate_operand" "+r,Q>,r,r,Q>,g,g,r"))
1277 (match_operand:QI 1 "general_operand" "r,r,Q>,M,M,M,r,g"))]
1278 ""
1279 "@
1280 move.b %1,%0
1281 move.b %1,%0
1282 move.b %1,%0
1283 clear.b %0
1284 clear.b %0
1285 clear.b %0
1286 move.b %1,%0
1287 move.b %1,%0"
1288 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
1289
1290;; The valid "quick" bit-patterns are, except for 0.0, denormalized
1291;; values REALLY close to 0, and some NaN:s (I think; their exponent is
1292;; all ones); the worthwhile one is "0.0".
1293;; It will use clear, so we know ALL types of immediate 0 never change cc.
1294
1295(define_insn "movsf"
1296 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,Q>,r,r,Q>,g,g,r")
1297 (match_operand:SF 1 "general_operand" "r,r,Q>,G,G,G,r,g"))]
1298 ""
1299 "@
1300 move.d %1,%0
1301 move.d %1,%0
1302 move.d %1,%0
1303 clear.d %0
1304 clear.d %0
1305 clear.d %0
1306 move.d %1,%0
1307 move.d %1,%0"
1308 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")])
1309\f
1310
1311;; Sign- and zero-extend insns with standard names.
1312;; Those for integer source operand are ordered with the widest source
1313;; type first.
1314
1315;; Sign-extend.
1316
1317(define_insn "extendsidi2"
1318 [(set (match_operand:DI 0 "register_operand" "=r")
1319 (sign_extend:DI (match_operand:SI 1 "general_operand" "g")))]
1320 ""
1321 "move.d %1,%M0\;smi %H0\;neg.d %H0,%H0")
1322
1323(define_insn "extendhidi2"
1324 [(set (match_operand:DI 0 "register_operand" "=r")
1325 (sign_extend:DI (match_operand:HI 1 "general_operand" "g")))]
1326 ""
1327 "movs.w %1,%M0\;smi %H0\;neg.d %H0,%H0")
1328
1329(define_insn "extendhisi2"
1330 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1331 (sign_extend:SI (match_operand:HI 1 "general_operand" "r,Q>,g")))]
1332 ""
1333 "movs.w %1,%0"
1334 [(set_attr "slottable" "yes,yes,no")])
1335
1336(define_insn "extendqidi2"
1337 [(set (match_operand:DI 0 "register_operand" "=r")
1338 (sign_extend:DI (match_operand:QI 1 "general_operand" "g")))]
1339 ""
1340 "movs.b %1,%M0\;smi %H0\;neg.d %H0,%H0")
1341
1342(define_insn "extendqisi2"
1343 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1344 (sign_extend:SI (match_operand:QI 1 "general_operand" "r,Q>,g")))]
1345 ""
1346 "movs.b %1,%0"
1347 [(set_attr "slottable" "yes,yes,no")])
1348
1349;; To do a byte->word exension, extend to dword, exept that the top half
1350;; of the register will be clobbered. FIXME: Perhaps this is not needed.
1351
1352(define_insn "extendqihi2"
1353 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1354 (sign_extend:HI (match_operand:QI 1 "general_operand" "r,Q>,g")))]
1355 ""
1356 "movs.b %1,%0"
1357 [(set_attr "slottable" "yes,yes,no")])
1358\f
1359
1360;; Zero-extend. The DImode ones are synthesized by gcc, so we don't
1361;; specify them here.
1362
1363(define_insn "zero_extendhisi2"
1364 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1365 (zero_extend:SI
1366 (match_operand:HI 1 "nonimmediate_operand" "r,Q>,m")))]
1367 ""
1368 "movu.w %1,%0"
1369 [(set_attr "slottable" "yes,yes,no")])
1370
1371(define_insn "zero_extendqisi2"
1372 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1373 (zero_extend:SI
1374 (match_operand:QI 1 "nonimmediate_operand" "r,Q>,m")))]
1375 ""
1376 "movu.b %1,%0"
1377 [(set_attr "slottable" "yes,yes,no")])
1378
1379;; Same comment as sign-extend QImode to HImode above applies.
1380
1381(define_insn "zero_extendqihi2"
1382 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1383 (zero_extend:HI
1384 (match_operand:QI 1 "nonimmediate_operand" "r,Q>,m")))]
1385 ""
1386 "movu.b %1,%0"
1387 [(set_attr "slottable" "yes,yes,no")])
1388\f
1389;; All kinds of arithmetic and logical instructions.
1390;;
1391;; First, anonymous patterns to match addressing modes with
1392;; side-effects.
1393;;
1394;; op.S [rx=ry+I],rz; (add, sub, or, and, bound).
1395;;
1396;; [rx=ry+rz.S]
1397;; FIXME: These could have anonymous mode for operand 0.
1398
1399;; QImode
1400
1401(define_insn "*op_sideqi_biap"
1402 [(set (match_operand:QI 0 "register_operand" "=r,r")
1403 (match_operator:QI
1404 6 "cris_orthogonal_operator"
1405 [(match_operand:QI 1 "register_operand" "0,0")
1406 (mem:QI (plus:SI
1407 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1408 (match_operand:SI 3 "const_int_operand" "n,n"))
1409 (match_operand:SI 4 "register_operand" "r,r")))]))
1410 (set (match_operand:SI 5 "register_operand" "=*4,r")
1411 (plus:SI (mult:SI (match_dup 2)
1412 (match_dup 3))
1413 (match_dup 4)))]
1414 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1415 "@
1416 #
1417 %x6.%s0 [%5=%4+%2%T3],%0")
1418
1419;; HImode
1420
1421(define_insn "*op_sidehi_biap"
1422 [(set (match_operand:HI 0 "register_operand" "=r,r")
1423 (match_operator:HI
1424 6 "cris_orthogonal_operator"
1425 [(match_operand:HI 1 "register_operand" "0,0")
1426 (mem:HI (plus:SI
1427 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1428 (match_operand:SI 3 "const_int_operand" "n,n"))
1429 (match_operand:SI 4 "register_operand" "r,r")))]))
1430 (set (match_operand:SI 5 "register_operand" "=*4,r")
1431 (plus:SI (mult:SI (match_dup 2)
1432 (match_dup 3))
1433 (match_dup 4)))]
1434 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1435 "@
1436 #
1437 %x6.%s0 [%5=%4+%2%T3],%0")
1438
1439;; SImode
1440
1441(define_insn "*op_sidesi_biap"
1442 [(set (match_operand:SI 0 "register_operand" "=r,r")
1443 (match_operator:SI
1444 6 "cris_orthogonal_operator"
1445 [(match_operand:SI 1 "register_operand" "0,0")
1446 (mem:SI (plus:SI
1447 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1448 (match_operand:SI 3 "const_int_operand" "n,n"))
1449 (match_operand:SI 4 "register_operand" "r,r")))]))
1450 (set (match_operand:SI 5 "register_operand" "=*4,r")
1451 (plus:SI (mult:SI (match_dup 2)
1452 (match_dup 3))
1453 (match_dup 4)))]
1454 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1455 "@
1456 #
1457 %x6.%s0 [%5=%4+%2%T3],%0")
1458\f
1459;; [rx=ry+i] ([%4=%2+%3])
1460;; FIXME: These could have anonymous mode for operand 0.
1461
1462;; QImode
1463
1464(define_insn "*op_sideqi"
1465 [(set (match_operand:QI 0 "register_operand" "=r,r,r")
1466 (match_operator:QI
1467 5 "cris_orthogonal_operator"
1468 [(match_operand:QI 1 "register_operand" "0,0,0")
1469 (mem:QI (plus:SI
1470 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1471 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))]))
1472 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1473 (plus:SI (match_dup 2)
1474 (match_dup 3)))]
1475 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1476 "*
1477{
1478 if (which_alternative == 0
1479 && (GET_CODE (operands[3]) != CONST_INT
1480 || INTVAL (operands[3]) > 127
1481 || INTVAL (operands[3]) < -128
1482 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1483 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1484 return \"#\";
1485 return \"%x5.%s0 [%4=%2%S3],%0\";
1486}")
1487
1488;; HImode
1489
1490(define_insn "*op_sidehi"
1491 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1492 (match_operator:HI
1493 5 "cris_orthogonal_operator"
1494 [(match_operand:HI 1 "register_operand" "0,0,0")
1495 (mem:HI (plus:SI
1496 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1497 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))]))
1498 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1499 (plus:SI (match_dup 2)
1500 (match_dup 3)))]
1501 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1502 "*
1503{
1504 if (which_alternative == 0
1505 && (GET_CODE (operands[3]) != CONST_INT
1506 || INTVAL (operands[3]) > 127
1507 || INTVAL (operands[3]) < -128
1508 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1509 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1510 return \"#\";
1511 return \"%x5.%s0 [%4=%2%S3],%0\";
1512}")
1513
1514;; SImode
1515
1516(define_insn "*op_sidesi"
1517 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1518 (match_operator:SI
1519 5 "cris_orthogonal_operator"
1520 [(match_operand:SI 1 "register_operand" "0,0,0")
1521 (mem:SI (plus:SI
1522 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1523 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))]))
1524 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1525 (plus:SI (match_dup 2)
1526 (match_dup 3)))]
1527 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1528 "*
1529{
1530 if (which_alternative == 0
1531 && (GET_CODE (operands[3]) != CONST_INT
1532 || INTVAL (operands[3]) > 127
1533 || INTVAL (operands[3]) < -128
1534 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1535 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1536 return \"#\";
1537 return \"%x5.%s0 [%4=%2%S3],%0\";
1538}")
1539\f
1540;; To match all cases for commutative operations we may have to have the
1541;; following pattern for add, or & and. I do not know really, but it does
1542;; not break anything.
1543;;
1544;; FIXME: This really ought to be checked.
1545;;
1546;; op.S [rx=ry+I],rz;
1547;;
1548;; [rx=ry+rz.S]
1549;; FIXME: These could have anonymous mode for operand 0.
1550
1551;; QImode
1552
1553(define_insn "*op_swap_sideqi_biap"
1554 [(set (match_operand:QI 0 "register_operand" "=r,r")
1555 (match_operator:QI
1556 6 "cris_commutative_orth_op"
1557 [(mem:QI (plus:SI
1558 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1559 (match_operand:SI 3 "const_int_operand" "n,n"))
1560 (match_operand:SI 4 "register_operand" "r,r")))
1561 (match_operand:QI 1 "register_operand" "0,0")]))
1562 (set (match_operand:SI 5 "register_operand" "=*4,r")
1563 (plus:SI (mult:SI (match_dup 2)
1564 (match_dup 3))
1565 (match_dup 4)))]
1566 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1567 "@
1568 #
1569 %x6.%s0 [%5=%4+%2%T3],%0")
1570
1571;; HImode
1572
1573(define_insn "*op_swap_sidehi_biap"
1574 [(set (match_operand:HI 0 "register_operand" "=r,r")
1575 (match_operator:HI
1576 6 "cris_commutative_orth_op"
1577 [(mem:HI (plus:SI
1578 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1579 (match_operand:SI 3 "const_int_operand" "n,n"))
1580 (match_operand:SI 4 "register_operand" "r,r")))
1581 (match_operand:HI 1 "register_operand" "0,0")]))
1582 (set (match_operand:SI 5 "register_operand" "=*4,r")
1583 (plus:SI (mult:SI (match_dup 2)
1584 (match_dup 3))
1585 (match_dup 4)))]
1586 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1587 "@
1588 #
1589 %x6.%s0 [%5=%4+%2%T3],%0")
1590
1591;; SImode
1592
1593(define_insn "*op_swap_sidesi_biap"
1594 [(set (match_operand:SI 0 "register_operand" "=r,r")
1595 (match_operator:SI
1596 6 "cris_commutative_orth_op"
1597 [(mem:SI (plus:SI
1598 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1599 (match_operand:SI 3 "const_int_operand" "n,n"))
1600 (match_operand:SI 4 "register_operand" "r,r")))
1601 (match_operand:SI 1 "register_operand" "0,0")]))
1602 (set (match_operand:SI 5 "register_operand" "=*4,r")
1603 (plus:SI (mult:SI (match_dup 2)
1604 (match_dup 3))
1605 (match_dup 4)))]
1606 "cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1607 "@
1608 #
1609 %x6.%s0 [%5=%4+%2%T3],%0")
1610\f
1611;; [rx=ry+i] ([%4=%2+%3])
1612;; FIXME: These could have anonymous mode for operand 0.
1613
1614;; QImode
1615
1616(define_insn "*op_swap_sideqi"
1617 [(set (match_operand:QI 0 "register_operand" "=r,r,r")
1618 (match_operator:QI
1619 5 "cris_commutative_orth_op"
1620 [(mem:QI
1621 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1622 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))
1623 (match_operand:QI 1 "register_operand" "0,0,0")]))
1624 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1625 (plus:SI (match_dup 2)
1626 (match_dup 3)))]
1627 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1628 "*
1629{
1630 if (which_alternative == 0
1631 && (GET_CODE (operands[3]) != CONST_INT
1632 || INTVAL (operands[3]) > 127
1633 || INTVAL (operands[3]) < -128
1634 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1635 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1636 return \"#\";
1637 return \"%x5.%s0 [%4=%2%S3],%0\";
1638}")
1639
1640;; HImode
1641
1642(define_insn "*op_swap_sidehi"
1643 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1644 (match_operator:HI
1645 5 "cris_commutative_orth_op"
1646 [(mem:HI
1647 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1648 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))
1649 (match_operand:HI 1 "register_operand" "0,0,0")]))
1650 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1651 (plus:SI (match_dup 2)
1652 (match_dup 3)))]
1653 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1654 "*
1655{
1656 if (which_alternative == 0
1657 && (GET_CODE (operands[3]) != CONST_INT
1658 || INTVAL (operands[3]) > 127
1659 || INTVAL (operands[3]) < -128
1660 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1661 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1662 return \"#\";
1663 return \"%x5.%s0 [%4=%2%S3],%0\";
1664}")
1665
1666;; SImode
1667
1668(define_insn "*op_swap_sidesi"
1669 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1670 (match_operator:SI
1671 5 "cris_commutative_orth_op"
1672 [(mem:SI
1673 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1674 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))
1675 (match_operand:SI 1 "register_operand" "0,0,0")]))
1676 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1677 (plus:SI (match_dup 2)
1678 (match_dup 3)))]
1679 "cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1680 "*
1681{
1682 if (which_alternative == 0
1683 && (GET_CODE (operands[3]) != CONST_INT
1684 || INTVAL (operands[3]) > 127
1685 || INTVAL (operands[3]) < -128
1686 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1687 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1688 return \"#\";
1689 return \"%x5.%s0 [%4=%2%S3],%0\";
1690}")
1691\f
1692;; Add operations, standard names.
1693
1694;; Note that for the 'P' constraint, the high part can be -1 or 0. We
1695;; output the insn through the 'A' output modifier as "adds.w" and "addq",
1696;; respectively.
1697(define_insn "adddi3"
1698 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
1699 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,r")
1700 (match_operand:DI 2 "general_operand" "J,N,P,g,!To")))]
1701 ""
1702 "@
1703 addq %2,%M0\;ax\;addq 0,%H0
1704 subq %n2,%M0\;ax\;subq 0,%H0
1705 add%e2.%z2 %2,%M0\;ax\;%A2 %H2,%H0
1706 add.d %M2,%M0\;ax\;add.d %H2,%H0
1707 add.d %M2,%M1,%M0\;ax\;add.d %H2,%H1,%H0")
1708
1709(define_insn "addsi3"
1710 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1711 (plus:SI
1712 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r")
1713 (match_operand:SI 2 "general_operand" "r,Q>,J,N,n,g,!To,0")))]
1714
1715;; The last constraint is due to that after reload, the '%' is not
1716;; honored, and canonicalization doesn't care about keeping the same
1717;; register as in destination. This will happen after insn splitting.
1718;; gcc <= 2.7.2. FIXME: Check for gcc-2.9x
1719
1720 ""
1721 "*
1722{
1723 switch (which_alternative)
1724 {
1725 case 0:
1726 case 1:
1727 return \"add.d %2,%0\";
1728 case 2:
1729 return \"addq %2,%0\";
1730 case 3:
1731 return \"subq %n2,%0\";
1732 case 4:
1733 /* 'Known value', but not in -63..63.
1734 Check if addu/subu may be used. */
1735 if (INTVAL (operands[2]) > 0)
1736 {
1737 if (INTVAL (operands[2]) < 256)
1738 return \"addu.b %2,%0\";
1739 if (INTVAL (operands[2]) < 65536)
1740 return \"addu.w %2,%0\";
1741 }
1742 else
1743 {
1744 if (INTVAL (operands[2]) >= -255)
1745 return \"subu.b %n2,%0\";
1746 if (INTVAL (operands[2]) >= -65535)
1747 return \"subu.w %n2,%0\";
1748 }
1749 return \"add.d %2,%0\";
1750 case 6:
1751 return \"add.d %2,%1,%0\";
1752 case 5:
1753 return \"add.d %2,%0\";
1754 case 7:
1755 return \"add.d %1,%0\";
1756 default:
1757 return \"BOGUS addsi %2+%1 to %0\";
1758 }
1759}"
1760 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,yes")])
1761\f
1762(define_insn "addhi3"
1763 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
1764 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,r")
1765 (match_operand:HI 2 "general_operand" "r,Q>,J,N,g,!To")))]
1766 ""
1767 "@
1768 add.w %2,%0
1769 add.w %2,%0
1770 addq %2,%0
1771 subq %n2,%0
1772 add.w %2,%0
1773 add.w %2,%1,%0"
1774 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
1775 (set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
1776
1777(define_insn "addqi3"
1778 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r,r")
1779 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0,r")
1780 (match_operand:QI 2 "general_operand" "r,Q>,J,N,O,g,!To")))]
1781 ""
1782 "@
1783 add.b %2,%0
1784 add.b %2,%0
1785 addq %2,%0
1786 subq %n2,%0
1787 subQ -%b2,%0
1788 add.b %2,%0
1789 add.b %2,%1,%0"
1790 [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no")
1791 (set_attr "cc" "normal,normal,clobber,clobber,clobber,normal,normal")])
1792\f
1793;; Subtract.
1794;;
1795;; Note that because of insn canonicalization these will *seldom* but
1796;; rarely be used with a known constant as an operand.
1797
1798;; Note that for the 'P' constraint, the high part can be -1 or 0. We
1799;; output the insn through the 'D' output modifier as "subs.w" and "subq",
1800;; respectively.
1801(define_insn "subdi3"
1802 [(set (match_operand:DI 0 "register_operand" "=r,r,r,&r,&r")
1803 (minus:DI (match_operand:DI 1 "register_operand" "0,0,0,0,r")
1804 (match_operand:DI 2 "general_operand" "J,N,P,g,!To")))]
1805 ""
1806 "@
1807 subq %2,%M0\;ax\;subq 0,%H0
1808 addq %n2,%M0\;ax\;addq 0,%H0
1809 sub%e2.%z2 %2,%M0\;ax\;%D2 %H2,%H0
1810 sub.d %M2,%M0\;ax\;sub.d %H2,%H0
1811 sub.d %M2,%M1,%M0\;ax\;sub.d %H2,%H1,%H0")
1812
1813(define_insn "subsi3"
1814 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1815 (minus:SI
1816 (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0,r")
1817 (match_operand:SI 2 "general_operand" "r,Q>,J,N,P,n,g,!To")))]
1818 ""
1819
1820;; This does not do the optimal: "addu.w 65535,r0" when %2 is negative.
1821;; But then again, %2 should not be negative.
1822
1823 "@
1824 sub.d %2,%0
1825 sub.d %2,%0
1826 subq %2,%0
1827 addq %n2,%0
1828 sub%e2.%z2 %2,%0
1829 sub.d %2,%0
1830 sub.d %2,%0
1831 sub.d %2,%1,%0"
1832 [(set_attr "slottable" "yes,yes,yes,yes,no,no,no,no")])
1833\f
1834(define_insn "subhi3"
1835 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
1836 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,r")
1837 (match_operand:HI 2 "general_operand" "r,Q>,J,N,g,!To")))]
1838 ""
1839 "@
1840 sub.w %2,%0
1841 sub.w %2,%0
1842 subq %2,%0
1843 addq %n2,%0
1844 sub.w %2,%0
1845 sub.w %2,%1,%0"
1846 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
1847 (set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
1848
1849(define_insn "subqi3"
1850 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1851 (minus:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,r")
1852 (match_operand:QI 2 "general_operand" "r,Q>,J,N,g,!To")))]
1853 ""
1854 "@
1855 sub.b %2,%0
1856 sub.b %2,%0
1857 subq %2,%0
1858 addq %2,%0
1859 sub.b %2,%0
1860 sub.b %2,%1,%0"
1861 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
1862 (set_attr "cc" "normal,normal,clobber,clobber,normal,normal")])
1863\f
1864;; CRIS has some add/sub-with-sign/zero-extend instructions.
1865;; Although these perform sign/zero-extension to SImode, they are
1866;; equally applicable for the HImode case.
1867;; FIXME: Check; GCC should handle the widening.
1868;; Note that these must be located after the normal add/sub patterns,
1869;; so not to get constants into any less specific operands.
1870;;
1871;; Extend with add/sub and side-effect.
1872;;
1873;; ADDS/SUBS/ADDU/SUBU and BOUND, which needs a check for zero_extend
1874;;
1875;; adds/subs/addu/subu bound [rx=ry+rz.S]
1876;; FIXME: These could have anonymous mode for operand 0.
1877
1878;; QImode to HImode
1879;; FIXME: GCC should widen.
1880
1881(define_insn "*extopqihi_side_biap"
1882 [(set (match_operand:HI 0 "register_operand" "=r,r")
1883 (match_operator:HI
1884 6 "cris_operand_extend_operator"
1885 [(match_operand:HI 1 "register_operand" "0,0")
1886 (match_operator:HI
1887 7 "cris_extend_operator"
1888 [(mem:QI (plus:SI
1889 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1890 (match_operand:SI 3 "const_int_operand" "n,n"))
1891 (match_operand:SI 4 "register_operand" "r,r")))])]))
1892 (set (match_operand:SI 5 "register_operand" "=*4,r")
1893 (plus:SI (mult:SI (match_dup 2)
1894 (match_dup 3))
1895 (match_dup 4)))]
1896 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[7]) == ZERO_EXTEND)
1897 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1898 "@
1899 #
1900 %x6%e7.%m7 [%5=%4+%2%T3],%0")
1901
1902;; QImode to SImode
1903
1904(define_insn "*extopqisi_side_biap"
1905 [(set (match_operand:SI 0 "register_operand" "=r,r")
1906 (match_operator:SI
1907 6 "cris_operand_extend_operator"
1908 [(match_operand:SI 1 "register_operand" "0,0")
1909 (match_operator:SI
1910 7 "cris_extend_operator"
1911 [(mem:QI (plus:SI
1912 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1913 (match_operand:SI 3 "const_int_operand" "n,n"))
1914 (match_operand:SI 4 "register_operand" "r,r")))])]))
1915 (set (match_operand:SI 5 "register_operand" "=*4,r")
1916 (plus:SI (mult:SI (match_dup 2)
1917 (match_dup 3))
1918 (match_dup 4)))]
1919 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[7]) == ZERO_EXTEND)
1920 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1921 "@
1922 #
1923 %x6%e7.%m7 [%5=%4+%2%T3],%0")
1924
1925;; HImode to SImode
1926
1927(define_insn "*extophisi_side_biap"
1928 [(set (match_operand:SI 0 "register_operand" "=r,r")
1929 (match_operator:SI
1930 6 "cris_operand_extend_operator"
1931 [(match_operand:SI 1 "register_operand" "0,0")
1932 (match_operator:SI
1933 7 "cris_extend_operator"
1934 [(mem:HI (plus:SI
1935 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
1936 (match_operand:SI 3 "const_int_operand" "n,n"))
1937 (match_operand:SI 4 "register_operand" "r,r")))])]))
1938 (set (match_operand:SI 5 "register_operand" "=*4,r")
1939 (plus:SI (mult:SI (match_dup 2)
1940 (match_dup 3))
1941 (match_dup 4)))]
1942 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[7]) == ZERO_EXTEND)
1943 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
1944 "@
1945 #
1946 %x6%e7.%m7 [%5=%4+%2%T3],%0")
1947\f
1948
1949;; [rx=ry+i]
1950;; FIXME: These could have anonymous mode for operand 0.
1951
1952;; QImode to HImode
1953
1954(define_insn "*extopqihi_side"
1955 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1956 (match_operator:HI
1957 5 "cris_operand_extend_operator"
1958 [(match_operand:HI 1 "register_operand" "0,0,0")
1959 (match_operator:HI
1960 6 "cris_extend_operator"
1961 [(mem:QI
1962 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1963 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")
1964 ))])]))
1965 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1966 (plus:SI (match_dup 2)
1967 (match_dup 3)))]
1968 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
1969 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
1970 "*
1971{
1972 if (which_alternative == 0
1973 && (GET_CODE (operands[3]) != CONST_INT
1974 || INTVAL (operands[3]) > 127
1975 || INTVAL (operands[3]) < -128
1976 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
1977 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
1978 return \"#\";
1979 return \"%x5%e6.%m6 [%4=%2%S3],%0\";
1980}")
1981
1982;; QImode to SImode
1983
1984(define_insn "*extopqisi_side"
1985 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1986 (match_operator:SI
1987 5 "cris_operand_extend_operator"
1988 [(match_operand:SI 1 "register_operand" "0,0,0")
1989 (match_operator:SI
1990 6 "cris_extend_operator"
1991 [(mem:QI
1992 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
1993 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")
1994 ))])]))
1995 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
1996 (plus:SI (match_dup 2)
1997 (match_dup 3)))]
1998
1999 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
2000 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
2001 "*
2002{
2003 if (which_alternative == 0
2004 && (GET_CODE (operands[3]) != CONST_INT
2005 || INTVAL (operands[3]) > 127
2006 || INTVAL (operands[3]) < -128
2007 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
2008 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
2009 return \"#\";
2010 return \"%x5%e6.%m6 [%4=%2%S3],%0\";
2011}")
2012
2013;; HImode to SImode
2014
2015(define_insn "*extophisi_side"
2016 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2017 (match_operator:SI
2018 5 "cris_operand_extend_operator"
2019 [(match_operand:SI 1 "register_operand" "0,0,0")
2020 (match_operator:SI
2021 6 "cris_extend_operator"
2022 [(mem:HI
2023 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
2024 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")
2025 ))])]))
2026 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
2027 (plus:SI (match_dup 2)
2028 (match_dup 3)))]
2029 "(GET_CODE (operands[5]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
2030 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
2031 "*
2032{
2033 if (which_alternative == 0
2034 && (GET_CODE (operands[3]) != CONST_INT
2035 || INTVAL (operands[3]) > 127
2036 || INTVAL (operands[3]) < -128
2037 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
2038 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
2039 return \"#\";
2040 return \"%x5%e6.%m6 [%4=%2%S3],%0\";
2041}")
2042\f
2043
2044;; As with op.S we may have to add special pattern to match commuted
2045;; operands to adds/addu and bound
2046;;
2047;; adds/addu/bound [rx=ry+rz.S]
2048
2049;; QImode to HImode
2050;; FIXME: GCC should widen.
2051;; FIXME: These could have anonymous mode for operand 0.
2052
2053(define_insn "*extopqihi_swap_side_biap"
2054 [(set (match_operand:HI 0 "register_operand" "=r,r")
2055 (match_operator:HI
2056 7 "cris_plus_or_bound_operator"
2057 [(match_operator:HI
2058 6 "cris_extend_operator"
2059 [(mem:QI (plus:SI
2060 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2061 (match_operand:SI 3 "const_int_operand" "n,n"))
2062 (match_operand:SI 4 "register_operand" "r,r")))])
2063 (match_operand:HI 1 "register_operand" "0,0")]))
2064 (set (match_operand:SI 5 "register_operand" "=*4,r")
2065 (plus:SI (mult:SI (match_dup 2)
2066 (match_dup 3))
2067 (match_dup 4)))]
2068 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
2069 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
2070 "@
2071 #
2072 %x7%e6.%m6 [%5=%4+%2%T3],%0")
2073
2074;; QImode to SImode
2075
2076(define_insn "*extopqisi_swap_side_biap"
2077 [(set (match_operand:SI 0 "register_operand" "=r,r")
2078 (match_operator:SI
2079 7 "cris_plus_or_bound_operator"
2080 [(match_operator:SI
2081 6 "cris_extend_operator"
2082 [(mem:QI (plus:SI
2083 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2084 (match_operand:SI 3 "const_int_operand" "n,n"))
2085 (match_operand:SI 4 "register_operand" "r,r")))])
2086 (match_operand:SI 1 "register_operand" "0,0")]))
2087 (set (match_operand:SI 5 "register_operand" "=*4,r")
2088 (plus:SI (mult:SI (match_dup 2)
2089 (match_dup 3))
2090 (match_dup 4)))]
2091 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
2092 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
2093 "@
2094 #
2095 %x7%e6.%m6 [%5=%4+%2%T3],%0")
2096
2097;; HImode to SImode
2098(define_insn "*extophisi_swap_side_biap"
2099 [(set (match_operand:SI 0 "register_operand" "=r,r")
2100 (match_operator:SI
2101 7 "cris_plus_or_bound_operator"
2102 [(match_operator:SI
2103 6 "cris_extend_operator"
2104 [(mem:HI (plus:SI
2105 (mult:SI (match_operand:SI 2 "register_operand" "r,r")
2106 (match_operand:SI 3 "const_int_operand" "n,n"))
2107 (match_operand:SI 4 "register_operand" "r,r")))])
2108 (match_operand:SI 1 "register_operand" "0,0")]))
2109 (set (match_operand:SI 5 "register_operand" "=*4,r")
2110 (plus:SI (mult:SI (match_dup 2)
2111 (match_dup 3))
2112 (match_dup 4)))]
2113 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[6]) == ZERO_EXTEND)
2114 && cris_side_effect_mode_ok (MULT, operands, 5, 4, 2, 3, 0)"
2115 "@
2116 #
2117 %x7%e6.%m6 [%5=%4+%2%T3],%0")
2118\f
2119;; [rx=ry+i]
2120;; FIXME: These could have anonymous mode for operand 0.
2121;; FIXME: GCC should widen.
2122
2123;; QImode to HImode
2124
2125(define_insn "*extopqihi_swap_side"
2126 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2127 (match_operator:HI
2128 6 "cris_plus_or_bound_operator"
2129 [(match_operator:HI
2130 5 "cris_extend_operator"
2131 [(mem:QI (plus:SI
2132 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
2133 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))])
2134 (match_operand:HI 1 "register_operand" "0,0,0")]))
2135 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
2136 (plus:SI (match_dup 2)
2137 (match_dup 3)))]
2138 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[5]) == ZERO_EXTEND)
2139 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
2140 "*
2141{
2142 if (which_alternative == 0
2143 && (GET_CODE (operands[3]) != CONST_INT
2144 || INTVAL (operands[3]) > 127
2145 || INTVAL (operands[3]) < -128
2146 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
2147 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
2148 return \"#\";
2149 return \"%x6%e5.%m5 [%4=%2%S3],%0\";
2150}")
2151
2152;; QImode to SImode
2153
2154(define_insn "*extopqisi_swap_side"
2155 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2156 (match_operator:SI
2157 6 "cris_plus_or_bound_operator"
2158 [(match_operator:SI
2159 5 "cris_extend_operator"
2160 [(mem:QI (plus:SI
2161 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
2162 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))])
2163 (match_operand:SI 1 "register_operand" "0,0,0")]))
2164 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
2165 (plus:SI (match_dup 2)
2166 (match_dup 3)))]
2167 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[5]) == ZERO_EXTEND)
2168 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
2169 "*
2170{
2171 if (which_alternative == 0
2172 && (GET_CODE (operands[3]) != CONST_INT
2173 || INTVAL (operands[3]) > 127
2174 || INTVAL (operands[3]) < -128
2175 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
2176 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
2177 return \"#\";
2178 return \"%x6%e5.%m5 [%4=%2%S3],%0\";
2179}")
2180
2181;; HImode to SImode
2182
2183(define_insn "*extophisi_swap_side"
2184 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2185 (match_operator:SI
2186 6 "cris_plus_or_bound_operator"
2187 [(match_operator:SI
2188 5 "cris_extend_operator"
2189 [(mem:HI (plus:SI
2190 (match_operand:SI 2 "cris_bdap_operand" "%r,r,r")
2191 (match_operand:SI 3 "cris_bdap_operand" "r>Ri,r,>Ri")))])
2192 (match_operand:SI 1 "register_operand" "0,0,0")]))
2193 (set (match_operand:SI 4 "register_operand" "=*2,r,r")
2194 (plus:SI (match_dup 2)
2195 (match_dup 3)))]
2196 "(GET_CODE (operands[6]) != UMIN || GET_CODE (operands[5]) == ZERO_EXTEND)
2197 && cris_side_effect_mode_ok (PLUS, operands, 4, 2, 3, -1, 0)"
2198 "*
2199{
2200 if (which_alternative == 0
2201 && (GET_CODE (operands[3]) != CONST_INT
2202 || INTVAL (operands[3]) > 127
2203 || INTVAL (operands[3]) < -128
2204 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
2205 || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
2206 return \"#\";
2207 return \"%x6%e5.%m5 [%4=%2%S3],%0\";
2208}")
2209\f
2210;; Extend versions (zero/sign) of normal add/sub (no side-effects).
2211;; FIXME: These could have anonymous mode for operand 0.
2212
2213;; QImode to HImode
2214;; FIXME: GCC should widen.
2215
2216(define_insn "*extopqihi"
2217 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2218 (match_operator:HI
2219 3 "cris_operand_extend_operator"
2220 [(match_operand:HI 1 "register_operand" "0,0,0,r")
2221 (match_operator:HI
2222 4 "cris_extend_operator"
2223 [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])]))]
2224 "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
2225 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
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")
2283 (match_operator:HI
2284 4 "cris_plus_or_bound_operator"
2285 [(match_operator:HI
2286 3 "cris_extend_operator"
2287 [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])
2288 (match_operand:HI 1 "register_operand" "0,0,0,r")]))]
2289 "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
2290 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
2291 && operands[1] != frame_pointer_rtx"
2292 "@
2293 %x4%e3.%m3 %2,%0
2294 %x4%e3.%m3 %2,%0
2295 %x4%e3.%m3 %2,%0
2296 %x4%e3.%m3 %2,%1,%0"
2297 [(set_attr "slottable" "yes,yes,no,no")
2298 (set_attr "cc" "clobber")])
2299
2300;; QImode to SImode
2301
2302(define_insn "*extopqisi_swap"
2303 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2304 (match_operator:SI
2305 4 "cris_plus_or_bound_operator"
2306 [(match_operator:SI
2307 3 "cris_extend_operator"
2308 [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])
2309 (match_operand:SI 1 "register_operand" "0,0,0,r")]))]
2310 "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
2311 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
2312 && operands[1] != frame_pointer_rtx"
2313 "@
2314 %x4%e3.%m3 %2,%0
2315 %x4%e3.%m3 %2,%0
2316 %x4%e3.%m3 %2,%0
2317 %x4%e3.%m3 %2,%1,%0"
2318 [(set_attr "slottable" "yes,yes,no,no")])
2319
2320;; HImode to SImode
2321
2322(define_insn "*extophisi_swap"
2323 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2324 (match_operator:SI
2325 4 "cris_plus_or_bound_operator"
2326 [(match_operator:SI
2327 3 "cris_extend_operator"
2328 [(match_operand:HI 2 "nonimmediate_operand" "r,Q>,m,!To")])
2329 (match_operand:SI 1 "register_operand" "0,0,0,r")]))]
2330 "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
2331 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
2332 && operands[1] != frame_pointer_rtx"
2333 "@
2334 %x4%e3.%m3 %2,%0
2335 %x4%e3.%m3 %2,%0
2336 %x4%e3.%m3 %2,%0
2337 %x4%e3.%m3 %2,%1,%0"
2338 [(set_attr "slottable" "yes,yes,no,no")])
2339\f
2340;; This is the special case when we use what corresponds to the
2341;; instruction above in "casesi". Do *not* change it to use the generic
2342;; pattern and "REG 15" as pc; I did that and it led to madness and
2343;; maintenance problems: Instead of (as imagined) recognizing and removing
2344;; or replacing this pattern with something simpler, other variant
2345;; patterns were recognized or combined, including some prefix variants
2346;; where the value in pc is not that of the next instruction (which means
2347;; this instruction actually *is* special and *should* be marked as such).
2348;; When switching from the "generic pattern match" approach to this simpler
2349;; approach, there were insignificant differences in gcc, ipps and
2350;; product code, somehow due to scratching reload behind the ear or
2351;; something. Testcase "gcc" looked .01% slower and 4 bytes bigger;
2352;; product code became .001% smaller but "looked better". The testcase
2353;; "ipps" was just different at register allocation).
2354;;
2355;; Assumptions in the jump optimizer forces us to use IF_THEN_ELSE in this
2356;; pattern with the default-label as the else, with the "if" being
2357;; index-is-less-than the max number of cases plus one. The default-label
2358;; is attached to the end of the case-table at time of output.
2359
2360(define_insn "*casesi_adds_w"
2361 [(set (pc)
2362 (if_then_else
2363 (ltu (match_operand:SI 0 "register_operand" "r")
2364 (match_operand:SI 1 "const_int_operand" "n"))
2365 (plus:SI (sign_extend:SI
2366 (mem:HI
2367 (plus:SI (mult:SI (match_dup 0) (const_int 2))
2368 (pc))))
2369 (pc))
2370 (label_ref (match_operand 2 "" ""))))
2371 (use (label_ref (match_operand 3 "" "")))]
2372
2373 "operands[0] != frame_pointer_rtx"
2374
2375 "adds.w [$pc+%0.w],$pc"
2376 [(set_attr "cc" "clobber")])
2377\f
2378;; Multiply instructions.
2379
2380;; Sometimes powers of 2 (which are normally canonicalized to a
2381;; left-shift) appear here, as a result of address reloading.
2382;; As a special, for values 3 and 5, we can match with an addi, so add those.
2383;;
2384;; FIXME: This may be unnecessary now.
2385;; Explicitly named for convenience of having a gen_... function.
2386
2387(define_insn "addi_mul"
2388 [(set (match_operand:SI 0 "register_operand" "=r")
2389 (mult:SI
2390 (match_operand:SI 1 "register_operand" "%0")
2391 (match_operand:SI 2 "const_int_operand" "n")))]
2392 "operands[0] != frame_pointer_rtx
2393 && operands[1] != frame_pointer_rtx
2394 && GET_CODE (operands[2]) == CONST_INT
2395 && (INTVAL (operands[2]) == 2
2396 || INTVAL (operands[2]) == 4 || INTVAL (operands[2]) == 3
2397 || INTVAL (operands[2]) == 5)"
2398 "*
2399{
2400 if (INTVAL (operands[2]) == 2)
2401 return \"lslq 1,%0\";
2402 else if (INTVAL (operands[2]) == 4)
2403 return \"lslq 2,%0\";
2404 else if (INTVAL (operands[2]) == 3)
2405 return \"addi %0.w,%0\";
2406 else if (INTVAL (operands[2]) == 5)
2407 return \"addi %0.d,%0\";
2408 return \"BAD: adr_mulsi: %0=%1*%2\";
2409}"
2410[(set_attr "slottable" "yes")
2411 ;; No flags are changed if this insn is "addi", but it does not seem
2412 ;; worth the trouble to distinguish that to the lslq cases.
2413 (set_attr "cc" "clobber")])
2414
2415;; The addi insn as it is normally used.
2416
2417(define_insn "*addi"
2418 [(set (match_operand:SI 0 "register_operand" "=r")
2419 (plus:SI
2420 (mult:SI (match_operand:SI 2 "register_operand" "r")
2421 (match_operand:SI 3 "const_int_operand" "n"))
2422 (match_operand:SI 1 "register_operand" "0")))]
2423 "operands[0] != frame_pointer_rtx
2424 && operands[1] != frame_pointer_rtx
2425 && GET_CODE (operands[3]) == CONST_INT
2426 && (INTVAL (operands[3]) == 1
2427 || INTVAL (operands[3]) == 2 || INTVAL (operands[3]) == 4)"
2428 "addi %2%T3,%0"
2429 [(set_attr "slottable" "yes")
2430 (set_attr "cc" "none")])
2431
2432;; The mstep instruction. Probably not useful by itself; it's to
2433;; non-linear wrt. the other insns. We used to expand to it, so at least
2434;; it's correct.
2435
2436(define_insn "mstep_shift"
2437 [(set (match_operand:SI 0 "register_operand" "=r")
2438 (if_then_else:SI
2439 (lt:SI (cc0) (const_int 0))
2440 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2441 (const_int 1))
2442 (match_operand:SI 2 "register_operand" "r"))
2443 (ashift:SI (match_operand:SI 3 "register_operand" "0")
2444 (const_int 1))))]
2445 ""
2446 "mstep %2,%0"
2447 [(set_attr "slottable" "yes")])
2448
2449;; When illegitimate addresses are legitimized, sometimes gcc forgets
2450;; to canonicalize the multiplications.
2451;;
2452;; FIXME: Check gcc > 2.7.2, remove and possibly fix in gcc.
2453
2454(define_insn "mstep_mul"
2455 [(set (match_operand:SI 0 "register_operand" "=r")
2456 (if_then_else:SI
2457 (lt:SI (cc0) (const_int 0))
2458 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
2459 (const_int 2))
2460 (match_operand:SI 2 "register_operand" "r"))
2461 (mult:SI (match_operand:SI 3 "register_operand" "0")
2462 (const_int 2))))]
2463 "operands[0] != frame_pointer_rtx
2464 && operands[1] != frame_pointer_rtx
2465 && operands[2] != frame_pointer_rtx
2466 && operands[3] != frame_pointer_rtx"
2467 "mstep %2,%0"
2468 [(set_attr "slottable" "yes")])
2469
2470(define_insn "umulhisi3"
2471 [(set (match_operand:SI 0 "register_operand" "=r")
2472 (mult:SI
2473 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
2474 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
2475 "TARGET_HAS_MUL_INSNS"
2476 "mulu.w %2,%0"
2477 [(set_attr "slottable" "yes")
2478 ;; Just N unusable here, but let's be safe.
2479 (set_attr "cc" "clobber")])
2480
2481(define_insn "umulqihi3"
2482 [(set (match_operand:HI 0 "register_operand" "=r")
2483 (mult:HI
2484 (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
2485 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2486 "TARGET_HAS_MUL_INSNS"
2487 "mulu.b %2,%0"
2488 [(set_attr "slottable" "yes")
2489 ;; Not exactly sure, but let's be safe.
2490 (set_attr "cc" "clobber")])
2491
2492;; Note that gcc does not make use of such a thing as umulqisi3. It gets
2493;; confused and will erroneously use it instead of umulhisi3, failing (at
2494;; least) gcc.c-torture/execute/arith-rand.c at all optimization levels.
2495;; Inspection of optab code shows that there must be only one widening
2496;; multiplication per mode widened to.
2497
2498(define_insn "mulsi3"
2499 [(set (match_operand:SI 0 "register_operand" "=r")
2500 (mult:SI (match_operand:SI 1 "register_operand" "0")
2501 (match_operand:SI 2 "register_operand" "r")))]
2502 "TARGET_HAS_MUL_INSNS"
2503 "muls.d %2,%0"
2504 [(set_attr "slottable" "yes")
2505 ;; Just N unusable here, but let's be safe.
2506 (set_attr "cc" "clobber")])
2507\f
2508;; A few multiply variations.
2509
2510;; This really extends to SImode, so cc should be considered clobbered.
2511
2512(define_insn "mulqihi3"
2513 [(set (match_operand:HI 0 "register_operand" "=r")
2514 (mult:HI
2515 (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))
2516 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2517 "TARGET_HAS_MUL_INSNS"
2518 "muls.b %2,%0"
2519 [(set_attr "slottable" "yes")
2520 (set_attr "cc" "clobber")])
2521
2522(define_insn "mulhisi3"
2523 [(set (match_operand:SI 0 "register_operand" "=r")
2524 (mult:SI
2525 (sign_extend:SI (match_operand:HI 1 "register_operand" "0"))
2526 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
2527 "TARGET_HAS_MUL_INSNS"
2528 "muls.w %2,%0"
2529 [(set_attr "slottable" "yes")
2530 ;; Just N unusable here, but let's be safe.
2531 (set_attr "cc" "clobber")])
2532
2533;; When needed, we can get the high 32 bits from the overflow
2534;; register. We don't care to split and optimize these.
2535;;
2536;; Note that cc0 is still valid after the move-from-overflow-register
2537;; insn; no special precaution need to be taken in cris_notice_update_cc.
2538
2539(define_insn "mulsidi3"
2540 [(set (match_operand:DI 0 "register_operand" "=r")
2541 (mult:DI
2542 (sign_extend:DI (match_operand:SI 1 "register_operand" "0"))
2543 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2544 "TARGET_HAS_MUL_INSNS"
2545 "muls.d %2,%M0\;move $mof,%H0")
2546
2547(define_insn "umulsidi3"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (mult:DI
2550 (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
2551 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2552 "TARGET_HAS_MUL_INSNS"
2553 "mulu.d %2,%M0\;move $mof,%H0")
2554
2555;; This pattern would probably not be needed if we add "mof" in its own
2556;; register class (and open a can of worms about /not/ pairing it with a
2557;; "normal" register). Having multiple register classes here, and
2558;; applicable to the v10 variant only, seems worse than having these two
2559;; patterns with multi-insn contents for now (may change; having a free
2560;; call-clobbered register is worth some trouble).
2561
2562(define_insn "smulsi3_highpart"
2563 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
2564 (truncate:SI
2565 (lshiftrt:DI
2566 (mult:DI
2567 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
2568 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r,r")))
2569 (const_int 32))))
2570 (clobber (match_scratch:SI 3 "=X,1,1"))]
2571 "TARGET_HAS_MUL_INSNS"
2572 "muls.d %2,%1\;move $mof,%0"
2573 [(set_attr "cc" "clobber")])
2574
2575(define_insn "umulsi3_highpart"
2576 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
2577 (truncate:SI
2578 (lshiftrt:DI
2579 (mult:DI
2580 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
2581 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r,r")))
2582 (const_int 32))))
2583 (clobber (match_scratch:SI 3 "=X,1,1"))]
2584 "TARGET_HAS_MUL_INSNS"
2585 "mulu.d %2,%1\;move $mof,%0"
2586 [(set_attr "cc" "clobber")])
2587\f
2588;; Divide and modulus instructions. CRIS only has a step instruction.
2589
2590(define_insn "dstep_shift"
2591 [(set (match_operand:SI 0 "register_operand" "=r")
2592 (if_then_else:SI
2593 (geu:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2594 (const_int 1))
2595 (match_operand:SI 2 "register_operand" "r"))
2596 (minus:SI (ashift:SI (match_operand:SI 3 "register_operand" "0")
2597 (const_int 1))
2598 (match_operand:SI 4 "register_operand" "2"))
2599 (ashift:SI (match_operand:SI 5 "register_operand" "0")
2600 (const_int 1))))]
2601 ""
2602 "dstep %2,%0"
2603 [(set_attr "slottable" "yes")])
2604
2605;; Here's a variant with mult instead of ashift.
2606;;
2607;; FIXME: This should be investigated. Which one matches through combination?
2608
2609(define_insn "dstep_mul"
2610 [(set (match_operand:SI 0 "register_operand" "=r")
2611 (if_then_else:SI
2612 (geu:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
2613 (const_int 2))
2614 (match_operand:SI 2 "register_operand" "r"))
2615 (minus:SI (mult:SI (match_operand:SI 3 "register_operand" "0")
2616 (const_int 2))
2617 (match_operand:SI 4 "register_operand" "2"))
2618 (mult:SI (match_operand:SI 5 "register_operand" "0")
2619 (const_int 2))))]
2620 "operands[0] != frame_pointer_rtx
2621 && operands[1] != frame_pointer_rtx
2622 && operands[2] != frame_pointer_rtx
2623 && operands[3] != frame_pointer_rtx"
2624 "dstep %2,%0"
2625 [(set_attr "slottable" "yes")])
2626\f
2627;; Logical operators.
2628
2629;; Bitwise "and".
2630
2631;; There is no use in defining "anddi3", because gcc can expand this by
2632;; itself, and make reasonable code without interference.
2633
2634;; If the first operand is memory or a register and is the same as the
2635;; second operand, and the third operand is -256 or -65536, we can use
2636;; CLEAR instead. Or, if the first operand is a register, and the third
2637;; operand is 255 or 65535, we can zero_extend.
f5143c46 2638;; GCC isn't smart enough to recognize these cases (yet), and they seem
0b85d816
HPN
2639;; to be common enough to be worthwhile.
2640;; FIXME: This should be made obsolete.
2641
2642(define_expand "andsi3"
2643 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2644 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2645 (match_operand:SI 2 "general_operand" "")))]
2646 ""
2647 "
2648{
2649 if (! (GET_CODE (operands[2]) == CONST_INT
2650 && (((INTVAL (operands[2]) == -256
2651 || INTVAL (operands[2]) == -65536)
2652 && rtx_equal_p (operands[1], operands[0]))
2653 || ((INTVAL (operands[2]) == 255
2654 || INTVAL (operands[2]) == 65535)
2655 && REG_P (operands[0])))))
2656 {
2657 /* Make intermediate steps if operand0 is not a register or
2658 operand1 is not a register, and hope that the reload pass will
2659 make something useful out of it. Note that the operands are
2660 *not* canonicalized. For the moment, I chicken out on this,
2661 because all or most ports do not describe 'and' with
2662 canonicalized operands, and I seem to remember magic in reload,
2663 checking that operand1 has constraint '%0', in which case
2664 operand0 and operand1 must have similar predicates.
2665 FIXME: Investigate. */
2666 rtx reg0 = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
2667 rtx reg1 = operands[1];
2668
2669 if (! REG_P (reg1))
2670 {
2671 emit_move_insn (reg0, reg1);
2672 reg1 = reg0;
2673 }
2674
2675 emit_insn (gen_rtx_SET (SImode, reg0,
2676 gen_rtx_AND (SImode, reg1, operands[2])));
2677
2678 /* Make sure we get the right *final* destination. */
2679 if (! REG_P (operands[0]))
2680 emit_move_insn (operands[0], reg0);
2681
2682 DONE;
2683 }
2684}")
2685
2686;; Some special cases of andsi3.
2687
2688(define_insn "*andsi_movu"
2689 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2690 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q>,m")
2691 (match_operand:SI 2 "const_int_operand" "n,n,n")))]
2692 "INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535"
2693 "movu.%z2 %1,%0"
2694 [(set_attr "slottable" "yes,yes,no")])
2695
2696(define_insn "*andsi_clear"
2697 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q>,Q>,m,m")
2698 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
2699 (match_operand:SI 2 "const_int_operand" "P,n,P,n,P,n")))]
2700 "INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256"
2701 "@
2702 cLear.b %0
2703 cLear.w %0
2704 cLear.b %0
2705 cLear.w %0
2706 cLear.b %0
2707 cLear.w %0"
2708 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
2709 (set_attr "cc" "none")])
2710
2711;; This is a catch-all pattern, taking care of everything that was not
2712;; matched in the insns above.
2713;;
2714;; Sidenote: the tightening from "nonimmediate_operand" to
2715;; "register_operand" for operand 1 actually increased the register
2716;; pressure (worse code). That will hopefully change with an
2717;; improved reload pass.
2718
2719(define_insn "*expanded_andsi"
2720 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
2721 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,r")
2722 (match_operand:SI 2 "general_operand" "I,r,Q>,g,!To")))]
2723 ""
2724 "@
2725 andq %2,%0
2726 and.d %2,%0
2727 and.d %2,%0
2728 and.d %2,%0
2729 and.d %2,%1,%0"
2730 [(set_attr "slottable" "yes,yes,yes,no,no")])
2731\f
2732;; For both QI and HI we may use the quick patterns. This results in
2733;; useless condition codes, but that is used rarely enough for it to
2734;; normally be a win (could check ahead for use of cc0, but seems to be
2735;; more pain than win).
2736
2737;; FIXME: See note for andsi3
2738
2739(define_expand "andhi3"
2740 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2741 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
2742 (match_operand:HI 2 "general_operand" "")))]
2743 ""
2744 "
2745{
2746 if (! (GET_CODE (operands[2]) == CONST_INT
2747 && (((INTVAL (operands[2]) == -256
2748 || INTVAL (operands[2]) == 65280)
2749 && rtx_equal_p (operands[1], operands[0]))
2750 || (INTVAL (operands[2]) == 255
2751 && REG_P (operands[0])))))
2752 {
2753 /* See comment for andsi3. */
2754 rtx reg0 = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (HImode);
2755 rtx reg1 = operands[1];
2756
2757 if (! REG_P (reg1))
2758 {
2759 emit_move_insn (reg0, reg1);
2760 reg1 = reg0;
2761 }
2762
2763 emit_insn (gen_rtx_SET (HImode, reg0,
2764 gen_rtx_AND (HImode, reg1, operands[2])));
2765
2766 /* Make sure we get the right destination. */
2767 if (! REG_P (operands[0]))
2768 emit_move_insn (operands[0], reg0);
2769
2770 DONE;
2771 }
2772}")
2773
2774;; Some fast andhi3 special cases.
2775
2776(define_insn "*andhi_movu"
2777 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2778 (and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q>,m")
2779 (const_int 255)))]
2780 ""
2781 "mOvu.b %1,%0"
2782 [(set_attr "slottable" "yes,yes,no")])
2783
2784(define_insn "*andhi_clear_signed"
2785 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q>,m")
2786 (and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
2787 (const_int -256)))]
2788 ""
2789 "cLear.b %0"
2790 [(set_attr "slottable" "yes,yes,no")
2791 (set_attr "cc" "none")])
2792
2793;; FIXME: Either this or the pattern above should be redundant.
2794(define_insn "*andhi_clear_unsigned"
2795 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q>,m")
2796 (and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
2797 (const_int 65280)))]
2798 ""
2799 "cLear.b %0"
2800 [(set_attr "slottable" "yes,yes,no")
2801 (set_attr "cc" "none")])
2802
2803;; Catch-all andhi3 pattern.
2804
2805(define_insn "*expanded_andhi"
2806 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2807 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,r")
2808 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))]
2809
2810;; Sidenote: the tightening from "general_operand" to
2811;; "register_operand" for operand 1 actually increased the register
2812;; pressure (worse code). That will hopefully change with an
2813;; improved reload pass.
2814
2815 ""
2816 "@
2817 andq %2,%0
2818 and.w %2,%0
2819 and.w %2,%0
2820 and.w %2,%0
2821 anDq %b2,%0
2822 and.w %2,%0
2823 and.w %2,%1,%0"
2824 [(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
2825 (set_attr "cc" "clobber,normal,normal,normal,clobber,normal,normal")])
2826
2827;; A strict_low_part pattern.
2828
2829(define_insn "*andhi_lowpart"
2830 [(set (strict_low_part
2831 (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r"))
2832 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,r")
2833 (match_operand:HI 2 "general_operand" "r,Q>,L,O,g,!To")))]
2834 ""
2835 "@
2836 and.w %2,%0
2837 and.w %2,%0
2838 and.w %2,%0
2839 anDq %b2,%0
2840 and.w %2,%0
2841 and.w %2,%1,%0"
2842 [(set_attr "slottable" "yes,yes,no,yes,no,no")
2843 (set_attr "cc" "normal,normal,normal,clobber,normal,normal")])
2844\f
2845(define_insn "andqi3"
2846 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2847 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,r")
2848 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))]
2849 ""
2850 "@
2851 andq %2,%0
2852 and.b %2,%0
2853 and.b %2,%0
2854 andQ %b2,%0
2855 and.b %2,%0
2856 and.b %2,%1,%0"
2857 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
2858 (set_attr "cc" "clobber,normal,normal,clobber,normal,normal")])
2859
2860(define_insn "*andqi_lowpart"
2861 [(set (strict_low_part
2862 (match_operand:QI 0 "register_operand" "=r,r,r,r,r"))
2863 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,r")
2864 (match_operand:QI 2 "general_operand" "r,Q>,O,g,!To")))]
2865 ""
2866 "@
2867 and.b %2,%0
2868 and.b %2,%0
2869 andQ %b2,%0
2870 and.b %2,%0
2871 and.b %2,%1,%0"
2872 [(set_attr "slottable" "yes,yes,yes,no,no")
2873 (set_attr "cc" "normal,normal,clobber,normal,normal")])
2874\f
2875;; Bitwise or.
2876
2877;; Same comment as anddi3 applies here - no need for such a pattern.
2878
2879;; It seems there's no need to jump through hoops to get good code such as
2880;; with andsi3.
2881
2882(define_insn "iorsi3"
2883 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
2884 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,r")
2885 (match_operand:SI 2 "general_operand" "I,r,Q>,n,g,!To")))]
2886 ""
2887 "@
2888 orq %2,%0
2889 or.d %2,%0
2890 or.d %2,%0
2891 oR.%s2 %2,%0
2892 or.d %2,%0
2893 or.d %2,%1,%0"
2894 [(set_attr "slottable" "yes,yes,yes,no,no,no")
2895 (set_attr "cc" "normal,normal,normal,clobber,normal,normal")])
2896
2897(define_insn "iorhi3"
2898 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
2899 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,r")
2900 (match_operand:HI 2 "general_operand" "I,r,Q>,L,O,g,!To")))]
2901 ""
2902 "@
2903 orq %2,%0
2904 or.w %2,%0
2905 or.w %2,%0
2906 or.w %2,%0
2907 oRq %b2,%0
2908 or.w %2,%0
2909 or.w %2,%1,%0"
2910 [(set_attr "slottable" "yes,yes,yes,no,yes,no,no")
2911 (set_attr "cc" "clobber,normal,normal,normal,clobber,normal,normal")])
2912
2913(define_insn "iorqi3"
2914 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2915 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,r")
2916 (match_operand:QI 2 "general_operand" "I,r,Q>,O,g,!To")))]
2917 ""
2918 "@
2919 orq %2,%0
2920 or.b %2,%0
2921 or.b %2,%0
2922 orQ %b2,%0
2923 or.b %2,%0
2924 or.b %2,%1,%0"
2925 [(set_attr "slottable" "yes,yes,yes,yes,no,no")
2926 (set_attr "cc" "clobber,normal,normal,clobber,normal,normal")])
2927\f
2928;; Exclusive-or
2929
2930;; See comment about "anddi3" for xordi3 - no need for such a pattern.
2931
2932(define_insn "xorsi3"
2933 [(set (match_operand:SI 0 "register_operand" "=r")
2934 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2935 (match_operand:SI 2 "register_operand" "r")))]
2936 ""
2937 "xor %2,%0"
2938 [(set_attr "slottable" "yes")])
2939
2940(define_insn "xorhi3"
2941 [(set (match_operand:HI 0 "register_operand" "=r")
2942 (xor:HI (match_operand:HI 1 "register_operand" "%0")
2943 (match_operand:HI 2 "register_operand" "r")))]
2944 ""
2945 "xor %2,%0"
2946 [(set_attr "slottable" "yes")
2947 (set_attr "cc" "clobber")])
2948
2949(define_insn "xorqi3"
2950 [(set (match_operand:QI 0 "register_operand" "=r")
2951 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2952 (match_operand:QI 2 "register_operand" "r")))]
2953 ""
2954 "xor %2,%0"
2955 [(set_attr "slottable" "yes")
2956 (set_attr "cc" "clobber")])
2957\f
2958;; Negation insns.
2959
2960;; Questionable use, here mostly as a (slightly usable) define_expand
2961;; example.
2962
2963(define_expand "negsf2"
2964 [(set (match_dup 2)
2965 (match_dup 3))
2966 (parallel [(set (match_operand:SF 0 "register_operand" "=r")
2967 (neg:SF (match_operand:SF 1
2968 "register_operand" "0")))
2969 (use (match_dup 2))])]
2970 ""
2971 "
2972{
2973 operands[2] = gen_reg_rtx (SImode);
2974 operands[3] = GEN_INT (1 << 31);
2975}")
2976
2977(define_insn "*expanded_negsf2"
2978 [(set (match_operand:SF 0 "register_operand" "=r")
2979 (neg:SF (match_operand:SF 1 "register_operand" "0")))
2980 (use (match_operand:SI 2 "register_operand" "r"))]
2981 ""
2982 "xor %2,%0"
2983 [(set_attr "slottable" "yes")])
2984
2985;; No "negdi2" although we could make one up that may be faster than
2986;; the one in libgcc.
2987
2988(define_insn "negsi2"
2989 [(set (match_operand:SI 0 "register_operand" "=r")
2990 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
2991 ""
2992 "neg.d %1,%0"
2993 [(set_attr "slottable" "yes")])
2994
2995(define_insn "neghi2"
2996 [(set (match_operand:HI 0 "register_operand" "=r")
2997 (neg:HI (match_operand:HI 1 "register_operand" "r")))]
2998 ""
2999 "neg.w %1,%0"
3000 [(set_attr "slottable" "yes")])
3001
3002(define_insn "negqi2"
3003 [(set (match_operand:QI 0 "register_operand" "=r")
3004 (neg:QI (match_operand:QI 1 "register_operand" "r")))]
3005 ""
3006 "neg.b %1,%0"
3007 [(set_attr "slottable" "yes")])
3008\f
3009;; One-complements.
3010
3011;; See comment on anddi3 - no need for a DImode pattern.
3012
3013(define_insn "one_cmplsi2"
3014 [(set (match_operand:SI 0 "register_operand" "=r")
3015 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3016 ""
3017 "not %0"
3018 [(set_attr "slottable" "yes")])
3019
3020(define_insn "one_cmplhi2"
3021 [(set (match_operand:HI 0 "register_operand" "=r")
3022 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3023 ""
3024 "not %0"
3025 [(set_attr "slottable" "yes")
3026 (set_attr "cc" "clobber")])
3027
3028(define_insn "one_cmplqi2"
3029 [(set (match_operand:QI 0 "register_operand" "=r")
3030 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3031 ""
3032 "not %0"
3033 [(set_attr "slottable" "yes")
3034 (set_attr "cc" "clobber")])
3035\f
3036;; Arithmetic shift right.
3037
3038(define_insn "ashrsi3"
3039 [(set (match_operand:SI 0 "register_operand" "=r")
3040 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
3041 (match_operand:SI 2 "nonmemory_operand" "Kr")))]
3042 ""
3043 "*
3044{
3045 if (REG_S_P (operands[2]))
3046 return \"asr.d %2,%0\";
3047
3048 return \"asrq %2,%0\";
3049}"
3050 [(set_attr "slottable" "yes")])
3051
3052;; Since gcc gets lost, and forgets to zero-extend the source (or mask
3053;; the destination) when it changes shifts of lower modes into SImode,
3054;; it is better to make these expands an anonymous patterns instead of
3055;; the more correct define_insns. This occurs when gcc thinks that is
3056;; is better to widen to SImode and use immediate shift count.
3057
3058;; FIXME: Is this legacy or still true for gcc >= 2.7.2?
3059
3060(define_expand "ashrhi3"
3061 [(set (match_dup 3)
3062 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
3063 (set (match_dup 4)
3064 (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm")))
3065 (set (match_dup 5) (ashiftrt:SI (match_dup 3) (match_dup 4)))
3066 (set (match_operand:HI 0 "general_operand" "=g")
3067 (subreg:HI (match_dup 5) 0))]
3068 ""
3069 "
3070{
3071 int i;
3072
3073 for (i = 3; i < 6; i++)
3074 operands[i] = gen_reg_rtx (SImode);
3075}")
3076
3077(define_insn "*expanded_ashrhi"
3078 [(set (match_operand:HI 0 "register_operand" "=r")
3079 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
3080 (match_operand:HI 2 "register_operand" "r")))]
3081 ""
3082 "asr.w %2,%0"
3083 [(set_attr "slottable" "yes")])
3084
3085(define_insn "*ashrhi_lowpart"
3086 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
3087 (ashiftrt:HI (match_dup 0)
3088 (match_operand:HI 1 "register_operand" "r")))]
3089 ""
3090 "asr.w %1,%0"
3091 [(set_attr "slottable" "yes")])
3092
3093;; Same comment goes as for "ashrhi3".
3094
3095(define_expand "ashrqi3"
3096 [(set (match_dup 3)
3097 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))
3098 (set (match_dup 4)
3099 (zero_extend:SI (match_operand:QI 2 "nonimmediate_operand" "g")))
3100 (set (match_dup 5) (ashiftrt:SI (match_dup 3) (match_dup 4)))
3101 (set (match_operand:QI 0 "general_operand" "=g")
3102 (subreg:QI (match_dup 5) 0))]
3103 ""
3104 "
3105{
3106 int i;
3107
3108 for (i = 3; i < 6; i++)
3109 operands[i] = gen_reg_rtx (SImode);
3110}")
3111
3112(define_insn "*expanded_ashrqi"
3113 [(set (match_operand:QI 0 "register_operand" "=r")
3114 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
3115 (match_operand:QI 2 "register_operand" "r")))]
3116 ""
3117 "asr.b %2,%0"
3118 [(set_attr "slottable" "yes")])
3119
3120;; A strict_low_part matcher.
3121
3122(define_insn "*ashrqi_lowpart"
3123 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
3124 (ashiftrt:QI (match_dup 0)
3125 (match_operand:QI 1 "register_operand" "r")))]
3126 ""
3127 "asr.b %1,%0"
3128 [(set_attr "slottable" "yes")])
3129\f
3130;; Logical shift right.
3131
3132(define_insn "lshrsi3"
3133 [(set (match_operand:SI 0 "register_operand" "=r")
3134 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3135 (match_operand:SI 2 "nonmemory_operand" "Kr")))]
3136 ""
3137 "*
3138{
3139 if (REG_S_P (operands[2]))
3140 return \"lsr.d %2,%0\";
3141
3142 return \"lsrq %2,%0\";
3143}"
3144 [(set_attr "slottable" "yes")])
3145
3146;; Same comments as for ashrhi3.
3147
3148(define_expand "lshrhi3"
3149 [(set (match_dup 3)
3150 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))
3151 (set (match_dup 4)
3152 (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "g")))
3153 (set (match_dup 5) (lshiftrt:SI (match_dup 3) (match_dup 4)))
3154 (set (match_operand:HI 0 "general_operand" "=g")
3155 (subreg:HI (match_dup 5) 0))]
3156 ""
3157 "
3158{
3159 int i;
3160
3161 for (i = 3; i < 6; i++)
3162 operands[i] = gen_reg_rtx (SImode);
3163}")
3164
3165(define_insn "*expanded_lshrhi"
3166 [(set (match_operand:HI 0 "register_operand" "=r")
3167 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
3168 (match_operand:HI 2 "register_operand" "r")))]
3169 ""
3170 "lsr.w %2,%0"
3171 [(set_attr "slottable" "yes")])
3172
3173;; A strict_low_part matcher.
3174
3175(define_insn "*lshrhi_lowpart"
3176 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
3177 (lshiftrt:HI (match_dup 0)
3178 (match_operand:HI 1 "register_operand" "r")))]
3179 ""
3180 "lsr.w %1,%0"
3181 [(set_attr "slottable" "yes")])
3182
3183;; Same comments as for ashrhi3.
3184
3185(define_expand "lshrqi3"
3186 [(set (match_dup 3)
3187 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))
3188 (set (match_dup 4)
3189 (zero_extend:SI (match_operand:QI 2 "nonimmediate_operand" "g")))
3190 (set (match_dup 5) (lshiftrt:SI (match_dup 3) (match_dup 4)))
3191 (set (match_operand:QI 0 "general_operand" "=g")
3192 (subreg:QI (match_dup 5) 0))]
3193 ""
3194 "
3195{
3196 int i;
3197
3198 for (i = 3; i < 6; i++)
3199 operands[i] = gen_reg_rtx (SImode);
3200}")
3201
3202(define_insn "*expanded_lshrqi"
3203 [(set (match_operand:QI 0 "register_operand" "=r")
3204 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
3205 (match_operand:QI 2 "register_operand" "r")))]
3206 ""
3207 "lsr.b %2,%0"
3208 [(set_attr "slottable" "yes")])
3209
3210;; A strict_low_part matcher.
3211
3212(define_insn "*lshrqi_lowpart"
3213 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
3214 (lshiftrt:QI (match_dup 0)
3215 (match_operand:QI 1 "register_operand" "r")))]
3216 ""
3217 "lsr.b %1,%0"
3218 [(set_attr "slottable" "yes")])
3219\f
3220;; Arithmetic/logical shift left.
3221
3222(define_insn "ashlsi3"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (ashift:SI (match_operand:SI 1 "register_operand" "0")
3225 (match_operand:SI 2 "nonmemory_operand" "Kr")))]
3226 ""
3227 "*
3228{
3229 if (REG_S_P (operands[2]))
3230 return \"lsl.d %2,%0\";
3231
3232 return \"lslq %2,%0\";
3233}"
3234 [(set_attr "slottable" "yes")])
3235
3236;; For narrower modes than SI, we can use lslq although it makes cc
3237;; unusable. The win is that we do not have to reload the shift-count
3238;; into a register.
3239
3240(define_insn "ashlhi3"
3241 [(set (match_operand:HI 0 "register_operand" "=r,r")
3242 (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
3243 (match_operand:HI 2 "nonmemory_operand" "r,K")))]
3244 ""
3245 "*
3246{
3247 return
3248 (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 15)
3249 ? \"moveq 0,%0\"
3250 : (CONSTANT_P (operands[2])
3251 ? \"lslq %2,%0\" : \"lsl.w %2,%0\");
3252}"
3253 [(set_attr "slottable" "yes")
3254 (set_attr "cc" "normal,clobber")])
3255
3256;; A strict_low_part matcher.
3257
3258(define_insn "*ashlhi_lowpart"
3259 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
3260 (ashift:HI (match_dup 0)
3261 (match_operand:HI 1 "register_operand" "r")))]
3262 ""
3263 "lsl.w %1,%0"
3264 [(set_attr "slottable" "yes")])
3265
3266(define_insn "ashlqi3"
3267 [(set (match_operand:QI 0 "register_operand" "=r,r")
3268 (ashift:QI (match_operand:QI 1 "register_operand" "0,0")
3269 (match_operand:QI 2 "nonmemory_operand" "r,K")))]
3270 ""
3271 "*
3272{
3273 return
3274 (GET_CODE (operands[2]) == CONST_INT
3275 && INTVAL (operands[2]) > 7)
3276 ? \"moveq 0,%0\"
3277 : (CONSTANT_P (operands[2])
3278 ? \"lslq %2,%0\" : \"lsl.b %2,%0\");
3279}"
3280 [(set_attr "slottable" "yes")
3281 (set_attr "cc" "normal,clobber")])
3282
3283;; A strict_low_part matcher.
3284
3285(define_insn "*ashlqi_lowpart"
3286 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
3287 (ashift:QI (match_dup 0)
3288 (match_operand:QI 1 "register_operand" "r")))]
3289 ""
3290 "lsl.b %1,%0"
3291 [(set_attr "slottable" "yes")])
3292\f
3293;; Various strange insns that gcc likes.
3294
3295;; Fortunately, it is simple to construct an abssf (although it may not
3296;; be very much used in practice).
3297
3298(define_insn "abssf2"
3299 [(set (match_operand:SF 0 "register_operand" "=r")
3300 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
3301 ""
3302 "lslq 1,%0\;lsrq 1,%0")
3303
3304(define_insn "abssi2"
3305 [(set (match_operand:SI 0 "register_operand" "=r")
3306 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
3307 ""
3308 "abs %1,%0"
3309 [(set_attr "slottable" "yes")])
3310
3311;; FIXME: GCC should be able to do these expansions itself.
3312
3313(define_expand "abshi2"
3314 [(set (match_dup 2)
3315 (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))
3316 (set (match_dup 3) (abs:SI (match_dup 2)))
3317 (set (match_operand:HI 0 "register_operand" "=r")
3318 (subreg:HI (match_dup 3) 0))]
3319 ""
3320 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
3321
3322(define_expand "absqi2"
3323 [(set (match_dup 2)
3324 (sign_extend:SI (match_operand:QI 1 "general_operand" "g")))
3325 (set (match_dup 3) (abs:SI (match_dup 2)))
3326 (set (match_operand:QI 0 "register_operand" "=r")
3327 (subreg:QI (match_dup 3) 0))]
3328 ""
3329 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
3330\f
3331;; Bound-insn. Defined to be the same as an unsigned minimum, which is an
3332;; operation supported by gcc. Used in casesi, but used now and then in
3333;; normal code too.
3334
3335(define_insn "uminsi3"
3336 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3337 (umin:SI (match_operand:SI 1 "register_operand" "%0,0,0,r")
3338 (match_operand:SI 2 "general_operand" "r,Q>,g,!STo")))]
3339 ""
3340 "*
3341{
3342 if (GET_CODE (operands[2]) == CONST_INT)
3343 {
3344 if (INTVAL (operands[2]) < 256)
3345 return \"bound.b %2,%0\";
3346
3347 if (INTVAL (operands[2]) < 65536)
3348 return \"bound.w %2,%0\";
3349 }
3350 else if (which_alternative == 3)
3351 return \"bound.d %2,%1,%0\";
3352
3353 return \"bound.d %2,%0\";
3354}"
3355 [(set_attr "slottable" "yes,yes,no,no")])
3356\f
3357;; Jump and branch insns.
3358
3359(define_insn "jump"
3360 [(set (pc)
3361 (label_ref (match_operand 0 "" "")))]
3362 ""
3363 "ba %l0%#"
3364 [(set_attr "slottable" "has_slot")])
3365
3366;; Testcase gcc.c-torture/compile/991213-3.c fails if we allow a constant
3367;; here, since the insn is not recognized as an indirect jump by
3368;; jmp_uses_reg_or_mem used by computed_jump_p. Perhaps it is a kludge to
3369;; change from general_operand to nonimmediate_operand (at least the docs
3370;; should be changed), but then again the pattern is called indirect_jump.
3371(define_insn "indirect_jump"
3372 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
3373 ""
3374 "jump %0")
3375
3376;; Return insn. Used whenever the epilogue is very simple; if it is only
3377;; a single ret or jump [sp+] or a contiguous sequence of movem:able saved
3378;; registers. No allocated stack space is allowed.
3379;; Note that for this pattern, although named, it is ok to check the
3380;; context of the insn in the test, not only compiler switches.
3381
3382(define_insn "return"
3383 [(return)]
3384 "cris_simple_epilogue ()"
3385 "*
3386{
3387 int i;
3388
3389 /* Just needs to hold a 'movem [sp+],rN'. */
3390 char rd[sizeof (\"movem [$sp+],$r99\")];
3391
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"
3766 [(set_attr "slottable" "yes")])
3767
3768(define_insn "slt"
3769 [(set (match_operand:SI 0 "register_operand" "=r")
3770 (lt:SI (cc0) (const_int 0)))]
3771 ""
3772 "*
3773{
3774 return
3775 (cc_prev_status.flags & CC_NO_OVERFLOW)
3776 ? \"smi %0\" : \"slt %0\";
3777}"
3778 [(set_attr "slottable" "yes")
3779 (set_attr "cc" "none")])
3780
3781(define_insn "sne"
3782 [(set (match_operand:SI 0 "register_operand" "=r")
3783 (ne:SI (cc0) (const_int 0)))]
3784 ""
3785 "sne %0"
3786 [(set_attr "slottable" "yes")
3787 (set_attr "cc" "none")])
3788\f
3789;; Call insns.
3790
3791;; We need to make these patterns "expand", since the real operand is
3792;; hidden in a (mem:QI ) inside operand[0] (call_value: operand[1]),
3793;; and cannot be checked if it were a "normal" pattern.
3794;; Note that "call" and "call_value" are *always* called with a
3795;; mem-operand for operand 0 and 1 respective. What happens for combined
3796;; instructions is a different issue.
3797
3798(define_expand "call"
3799 [(parallel [(call (match_operand:QI 0 "cris_mem_call_operand" "")
3800 (match_operand 1 "general_operand" ""))
3801 ;; 16 is the srp (can't use the symbolic name here)
3802 (clobber (reg:SI 16))])]
3803 ""
3804 "
3805{
3806 rtx op0;
3807
3808 if (GET_CODE (operands[0]) != MEM)
3809 abort ();
3810
3811 if (flag_pic)
3812 {
3813 op0 = XEXP (operands[0], 0);
3814
3815 /* It might be that code can be generated that jumps to 0 (or to a
3816 specific address). Don't abort on that. At least there's a
3817 test-case. */
3818 if (CONSTANT_ADDRESS_P (op0) && GET_CODE (op0) != CONST_INT)
3819 {
3820 if (no_new_pseudos)
3821 abort ();
3822
3823 /* For local symbols (non-PLT), get the plain symbol reference
3824 into a register. For symbols that can be PLT, make them PLT. */
3825 if (cris_gotless_symbol (op0) || GET_CODE (op0) != SYMBOL_REF)
3826 op0 = force_reg (Pmode, op0);
3827 else if (cris_symbol (op0))
3828 /* FIXME: Would hanging a REG_EQUIV/EQUAL on that register
3829 for the symbol cause bad recombinatorial effects? */
3830 op0 = force_reg (Pmode,
3831 gen_rtx_CONST
3832 (VOIDmode,
3833 gen_rtx_UNSPEC (VOIDmode,
3834 gen_rtvec (1, op0), 0)));
3835 else
3836 abort ();
3837
3838 operands[0] = gen_rtx_MEM (GET_MODE (operands[0]), op0);
3839 }
3840 }
3841}")
3842
3843;; Accept *anything* as operand 1. Accept operands for operand 0 in
3844;; order of preference (Q includes r, but r is shorter, faster)
3845
3846(define_insn "*expanded_call"
3847 [(call (mem:QI (match_operand:SI
3848 0 "cris_general_operand_or_plt_symbol" "r,Q>,g,S"))
3849 (match_operand 1 "" ""))
3850 (clobber (reg:SI 16))] ;; 16 is the srp (can't use symbolic name)
3851 "! TARGET_AVOID_GOTPLT"
3852 "jsr %0")
3853
3854;; Same as above, since can't afford wasting a constraint letter to mean
3855;; "S unless TARGET_AVOID_GOTPLT".
3856(define_insn "*expanded_call_no_gotplt"
3857 [(call (mem:QI (match_operand:SI
3858 0 "cris_general_operand_or_plt_symbol" "r,Q>,g"))
3859 (match_operand 1 "" ""))
3860 (clobber (reg:SI 16))] ;; 16 is the srp (can't use symbolic name)
3861 "TARGET_AVOID_GOTPLT"
3862 "jsr %0")
3863
3864(define_expand "call_value"
3865 [(parallel [(set (match_operand 0 "" "")
3866 (call (match_operand:QI 1 "cris_mem_call_operand" "")
3867 (match_operand 2 "" "")))
3868 ;; 16 is the srp (can't use symbolic name)
3869 (clobber (reg:SI 16))])]
3870 ""
3871 "
3872{
3873 rtx op1;
3874
3875 if (GET_CODE (operands[1]) != MEM)
3876 abort ();
3877
3878 if (flag_pic)
3879 {
3880 op1 = XEXP (operands[1], 0);
3881
3882 /* It might be that code can be generated that jumps to 0 (or to a
3883 specific address). Don't abort on that. At least there's a
3884 test-case. */
3885 if (CONSTANT_ADDRESS_P (op1) && GET_CODE (op1) != CONST_INT)
3886 {
3887 if (no_new_pseudos)
3888 abort ();
3889
3890 if (cris_gotless_symbol (op1))
3891 op1 = force_reg (Pmode, op1);
3892 else if (cris_symbol (op1))
3893 /* FIXME: Would hanging a REG_EQUIV/EQUAL on that register
3894 for the symbol cause bad recombinatorial effects? */
3895 op1 = force_reg (Pmode,
3896 gen_rtx_CONST
3897 (VOIDmode,
3898 gen_rtx_UNSPEC (VOIDmode,
3899 gen_rtvec (1, op1), 0)));
3900 else
3901 abort ();
3902
3903 operands[1] = gen_rtx_MEM (GET_MODE (operands[1]), op1);
3904 }
3905 }
3906}")
3907
3908;; Accept *anything* as operand 2. The validity other than "general" of
3909;; operand 0 will be checked elsewhere. Accept operands for operand 1 in
3910;; order of preference (Q includes r, but r is shorter, faster).
3911;; We also accept a PLT symbol. We output it as [rPIC+sym:GOTPLT] rather
3912;; than requiring getting rPIC + sym:PLT into a register.
3913
3914(define_insn "*expanded_call_value"
3915 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g,g")
3916 (call (mem:QI (match_operand:SI
3917 1 "cris_general_operand_or_plt_symbol" "r,Q>,g,S"))
3918 (match_operand 2 "" "")))
3919 (clobber (reg:SI 16))]
3920 "! TARGET_AVOID_GOTPLT"
3921 "Jsr %1"
3922 [(set_attr "cc" "clobber")])
3923
3924;; Same as above, since can't afford wasting a constraint letter to mean
3925;; "S unless TARGET_AVOID_GOTPLT".
3926(define_insn "*expanded_call_value_no_gotplt"
3927 [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
3928 (call (mem:QI (match_operand:SI
3929 1 "cris_general_operand_or_plt_symbol" "r,Q>,g"))
3930 (match_operand 2 "" "")))
3931 (clobber (reg:SI 16))]
3932 "TARGET_AVOID_GOTPLT"
3933 "Jsr %1"
3934 [(set_attr "cc" "clobber")])
3935
3936;; Used in debugging. No use for the direct pattern; unfilled
3937;; delayed-branches are taken care of by other means.
3938
3939(define_insn "nop"
3940 [(const_int 0)]
3941 ""
3942 "nop"
3943 [(set_attr "cc" "none")])
3944\f
3945;; We expand on casesi so we can use "bound" and "add offset fetched from
3946;; a table to pc" (adds.w [pc+%0.w],pc).
3947
3948;; Note: if you change the "parallel" (or add anything after it) in
3949;; this expansion, you must change the macro ASM_OUTPUT_CASE_END
3950;; accordingly, to add the default case at the end of the jump-table.
3951
3952(define_expand "casesi"
3953 [(set (match_dup 5) (match_operand:SI 0 "general_operand" ""))
3954 (set (match_dup 6)
3955 (minus:SI (match_dup 5)
3956 (match_operand:SI 1 "const_int_operand" "n")))
3957 (set (match_dup 7)
3958 (umin:SI (match_dup 6)
3959 (match_operand:SI 2 "const_int_operand" "n")))
3960 (parallel
3961 [(set (pc)
3962 (if_then_else
3963 (ltu (match_dup 7) (match_dup 2))
3964 (plus:SI (sign_extend:SI
3965 (mem:HI
3966 (plus:SI (mult:SI (match_dup 7) (const_int 2))
3967 (pc))))
3968 (pc))
3969 (label_ref (match_operand 4 "" ""))))
3970 (use (label_ref (match_operand 3 "" "")))])]
3971 ""
3972 "
3973{
3974 operands[2] = plus_constant (operands[2], 1);
3975 operands[5] = gen_reg_rtx (SImode);
3976 operands[6] = gen_reg_rtx (SImode);
3977 operands[7] = gen_reg_rtx (SImode);
3978}")
3979\f
3980;; Split-patterns. Some of them have modes unspecified. This
3981;; should always be ok; if for no other reason sparc.md has it as
3982;; well.
3983;;
3984;; When register_operand is specified for an operand, we can get a
3985;; subreg as well (Axis-990331), so don't just assume that REG_P is true
3986;; for a register_operand and that REGNO can be used as is. It is best to
3987;; guard with REG_P, unless it is worth it to adjust for the subreg case.
3988
3989;; op [rx + 0],ry,rz
3990;; The index to rx is optimized into zero, and gone.
3991
3992;; First, recognize bound [rx],ry,rz; where [rx] is zero-extended,
3993;; and add/sub [rx],ry,rz, with zero or sign-extend on [rx].
3994;; Split this into:
3995;; move ry,rz
3996;; op [rx],rz
3997;; Lose if rz=ry or rx=rz.
3998;; Call this op-extend-split
3999
4000(define_split
4001 [(set (match_operand 0 "register_operand" "")
4002 (match_operator
4003 4 "cris_operand_extend_operator"
4004 [(match_operand 1 "register_operand" "")
4005 (match_operator
4006 3 "cris_extend_operator"
4007 [(match_operand 2 "memory_operand" "")])]))]
4008 "REG_P (operands[0])
4009 && REG_P (operands[1])
4010 && REGNO (operands[1]) != REGNO (operands[0])
4011 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4012 && REG_P (XEXP (operands[2], 0))
4013 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4014 [(set (match_dup 0)
4015 (match_dup 1))
4016 (set (match_dup 0)
4017 (match_op_dup
4018 4 [(match_dup 0)
4019 (match_op_dup 3 [(match_dup 2)])]))]
4020 "")
4021
4022;; As op-extend-split, but recognize and split op [rz],ry,rz into
4023;; ext [rz],rz
4024;; op ry,rz
4025;; Do this for plus or bound only, being commutative operations, since we
4026;; have swapped the operands.
4027;; Call this op-extend-split-rx=rz
4028
4029(define_split
4030 [(set (match_operand 0 "register_operand" "")
4031 (match_operator
4032 4 "cris_plus_or_bound_operator"
4033 [(match_operand 1 "register_operand" "")
4034 (match_operator
4035 3 "cris_extend_operator"
4036 [(match_operand 2 "memory_operand" "")])]))]
4037 "REG_P (operands[0])
4038 && REG_P (operands[1])
4039 && REGNO (operands[1]) != REGNO (operands[0])
4040 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4041 && REG_P (XEXP (operands[2], 0))
4042 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4043 [(set (match_dup 0)
4044 (match_op_dup 3 [(match_dup 2)]))
4045 (set (match_dup 0)
4046 (match_op_dup
4047 4 [(match_dup 0)
4048 (match_dup 1)]))]
4049 "")
4050
4051;; As the op-extend-split, but swapped operands, and only for
4052;; plus or bound, being the commutative extend-operators. FIXME: Why is
4053;; this needed? Is it?
4054;; Call this op-extend-split-swapped
4055
4056(define_split
4057 [(set (match_operand 0 "register_operand" "")
4058 (match_operator
4059 4 "cris_plus_or_bound_operator"
4060 [(match_operator
4061 3 "cris_extend_operator"
4062 [(match_operand 2 "memory_operand" "")])
4063 (match_operand 1 "register_operand" "")]))]
4064 "REG_P (operands[0])
4065 && REG_P (operands[1])
4066 && REGNO (operands[1]) != REGNO (operands[0])
4067 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4068 && REG_P (XEXP (operands[2], 0))
4069 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4070 [(set (match_dup 0)
4071 (match_dup 1))
4072 (set (match_dup 0)
4073 (match_op_dup
4074 4 [(match_dup 0)
4075 (match_op_dup 3 [(match_dup 2)])]))]
4076 "")
4077
4078;; As op-extend-split-rx=rz, but swapped operands, only for plus or
4079;; bound. Call this op-extend-split-swapped-rx=rz.
4080
4081(define_split
4082 [(set (match_operand 0 "register_operand" "")
4083 (match_operator
4084 4 "cris_plus_or_bound_operator"
4085 [(match_operator
4086 3 "cris_extend_operator"
4087 [(match_operand 2 "memory_operand" "")])
4088 (match_operand 1 "register_operand" "")]))]
4089 "REG_P (operands[0])
4090 && REG_P (operands[1])
4091 && REGNO (operands[1]) != REGNO (operands[0])
4092 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4093 && REG_P (XEXP (operands[2], 0))
4094 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4095 [(set (match_dup 0)
4096 (match_op_dup 3 [(match_dup 2)]))
4097 (set (match_dup 0)
4098 (match_op_dup
4099 4 [(match_dup 0)
4100 (match_dup 1)]))]
4101 "")
4102
4103;; As op-extend-split, but the mem operand is not extended.
4104;;
4105;; op [rx],ry,rz changed into
4106;; move ry,rz
4107;; op [rx],rz
4108;; lose if ry=rz or rx=rz
4109;; Call this op-extend.
4110
4111(define_split
4112 [(set (match_operand 0 "register_operand" "")
4113 (match_operator
4114 3 "cris_orthogonal_operator"
4115 [(match_operand 1 "register_operand" "")
4116 (match_operand 2 "memory_operand" "")]))]
4117 "REG_P (operands[0])
4118 && REG_P (operands[1])
4119 && REGNO (operands[1]) != REGNO (operands[0])
4120 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4121 && REG_P (XEXP (operands[2], 0))
4122 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4123 [(set (match_dup 0)
4124 (match_dup 1))
4125 (set (match_dup 0)
4126 (match_op_dup
4127 3 [(match_dup 0)
4128 (match_dup 2)]))]
4129 "")
4130
4131;; As op-extend-split-rx=rz, non-extended.
4132;; Call this op-split-rx=rz
4133
4134(define_split
4135 [(set (match_operand 0 "register_operand" "")
4136 (match_operator
4137 3 "cris_commutative_orth_op"
4138 [(match_operand 2 "memory_operand" "")
4139 (match_operand 1 "register_operand" "")]))]
4140 "REG_P (operands[0])
4141 && REG_P (operands[1])
4142 && REGNO (operands[1]) != REGNO (operands[0])
4143 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4144 && REG_P (XEXP (operands[2], 0))
4145 && REGNO (XEXP (operands[2], 0)) != REGNO (operands[0])"
4146 [(set (match_dup 0)
4147 (match_dup 1))
4148 (set (match_dup 0)
4149 (match_op_dup
4150 3 [(match_dup 0)
4151 (match_dup 2)]))]
4152 "")
4153
4154;; As op-extend-split-swapped, nonextended.
4155;; Call this op-split-swapped.
4156
4157(define_split
4158 [(set (match_operand 0 "register_operand" "")
4159 (match_operator
4160 3 "cris_commutative_orth_op"
4161 [(match_operand 1 "register_operand" "")
4162 (match_operand 2 "memory_operand" "")]))]
4163 "REG_P (operands[0]) && REG_P (operands[1])
4164 && REGNO (operands[1]) != REGNO (operands[0])
4165 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4166 && REG_P (XEXP (operands[2], 0))
4167 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4168 [(set (match_dup 0)
4169 (match_dup 2))
4170 (set (match_dup 0)
4171 (match_op_dup
4172 3 [(match_dup 0)
4173 (match_dup 1)]))]
4174 "")
4175
4176;; As op-extend-split-swapped-rx=rz, non-extended.
4177;; Call this op-split-swapped-rx=rz.
4178
4179(define_split
4180 [(set (match_operand 0 "register_operand" "")
4181 (match_operator
4182 3 "cris_orthogonal_operator"
4183 [(match_operand 2 "memory_operand" "")
4184 (match_operand 1 "register_operand" "")]))]
4185 "REG_P (operands[0]) && REG_P (operands[1])
4186 && REGNO (operands[1]) != REGNO (operands[0])
4187 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4188 && REG_P (XEXP (operands[2], 0))
4189 && REGNO (XEXP (operands[2], 0)) == REGNO (operands[0])"
4190 [(set (match_dup 0)
4191 (match_dup 2))
4192 (set (match_dup 0)
4193 (match_op_dup
4194 3 [(match_dup 0)
4195 (match_dup 1)]))]
4196 "")
4197\f
4198;; Splits for all cases in side-effect insns where (possibly after reload
4199;; and register allocation) rx and ry in [rx=ry+i] are equal.
4200
4201;; move.S1 [rx=rx+rz.S2],ry
4202
4203(define_split
4204 [(parallel
4205 [(set (match_operand 0 "register_operand" "")
4206 (mem (plus:SI
4207 (mult:SI (match_operand:SI 1 "register_operand" "")
4208 (match_operand:SI 2 "const_int_operand" ""))
4209 (match_operand:SI 3 "register_operand" ""))))
4210 (set (match_operand:SI 4 "register_operand" "")
4211 (plus:SI (mult:SI (match_dup 1)
4212 (match_dup 2))
4213 (match_dup 3)))])]
4214 "REG_P (operands[3]) && REG_P (operands[4])
4215 && REGNO (operands[3]) == REGNO (operands[4])"
4216 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
4217 (match_dup 3)))
4218 (set (match_dup 0) (match_dup 5))]
4219 "operands[5] = gen_rtx_MEM (GET_MODE (operands[0]), operands[3]);")
4220
4221;; move.S1 [rx=rx+i],ry
4222
4223(define_split
4224 [(parallel
4225 [(set (match_operand 0 "register_operand" "")
4226 (mem
4227 (plus:SI (match_operand:SI 1 "cris_bdap_operand" "")
4228 (match_operand:SI 2 "cris_bdap_operand" ""))))
4229 (set (match_operand:SI 3 "register_operand" "")
4230 (plus:SI (match_dup 1)
4231 (match_dup 2)))])]
4232 "(rtx_equal_p (operands[3], operands[1])
4233 || rtx_equal_p (operands[3], operands[2]))"
4234 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))
4235 (set (match_dup 0) (match_dup 4))]
4236 "operands[4] = gen_rtx_MEM (GET_MODE (operands[0]), operands[3]);")
4237
4238;; move.S1 ry,[rx=rx+rz.S2]
4239
4240(define_split
4241 [(parallel
4242 [(set (mem (plus:SI
4243 (mult:SI (match_operand:SI 0 "register_operand" "")
4244 (match_operand:SI 1 "const_int_operand" ""))
4245 (match_operand:SI 2 "register_operand" "")))
4246 (match_operand 3 "register_operand" ""))
4247 (set (match_operand:SI 4 "register_operand" "")
4248 (plus:SI (mult:SI (match_dup 0)
4249 (match_dup 1))
4250 (match_dup 2)))])]
4251 "REG_P (operands[2]) && REG_P (operands[4])
4252 && REGNO (operands[4]) == REGNO (operands[2])"
4253 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
4254 (match_dup 2)))
4255 (set (match_dup 5) (match_dup 3))]
4256 "operands[5] = gen_rtx_MEM (GET_MODE (operands[3]), operands[4]);")
4257
4258;; move.S1 ry,[rx=rx+i]
4259
4260(define_split
4261 [(parallel
4262 [(set (mem
4263 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
4264 (match_operand:SI 1 "cris_bdap_operand" "")))
4265 (match_operand 2 "register_operand" ""))
4266 (set (match_operand:SI 3 "register_operand" "")
4267 (plus:SI (match_dup 0)
4268 (match_dup 1)))])]
4269 "(rtx_equal_p (operands[3], operands[0])
4270 || rtx_equal_p (operands[3], operands[1]))"
4271 [(set (match_dup 3) (plus:SI (match_dup 0) (match_dup 1)))
4272 (set (match_dup 5) (match_dup 2))]
4273 "operands[5] = gen_rtx_MEM (GET_MODE (operands[2]), operands[3]);")
4274
4275;; clear.d ry,[rx=rx+rz.S2]
4276
4277(define_split
4278 [(parallel
4279 [(set (mem:SI (plus:SI
4280 (mult:SI (match_operand:SI 0 "register_operand" "")
4281 (match_operand:SI 1 "const_int_operand" ""))
4282 (match_operand:SI 2 "register_operand" "")))
4283 (const_int 0))
4284 (set (match_operand:SI 3 "register_operand" "")
4285 (plus:SI (mult:SI (match_dup 0)
4286 (match_dup 1))
4287 (match_dup 2)))])]
4288 "REG_P (operands[2]) && REG_P (operands[3])
4289 && REGNO (operands[3]) == REGNO (operands[2])"
4290 [(set (match_dup 3) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
4291 (match_dup 2)))
4292 (set (mem:SI (match_dup 3)) (const_int 0))]
4293 "")
4294
4295;; clear.w ry,[rx=rx+rz.S2]
4296
4297(define_split
4298 [(parallel
4299 [(set (mem:HI (plus:SI
4300 (mult:SI (match_operand:SI 0 "register_operand" "")
4301 (match_operand:SI 1 "const_int_operand" ""))
4302 (match_operand:SI 2 "register_operand" "")))
4303 (const_int 0))
4304 (set (match_operand:SI 3 "register_operand" "")
4305 (plus:SI (mult:SI (match_dup 0)
4306 (match_dup 1))
4307 (match_dup 2)))])]
4308 "REG_P (operands[2]) && REG_P (operands[3])
4309 && REGNO (operands[3]) == REGNO (operands[2])"
4310 [(set (match_dup 3) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
4311 (match_dup 2)))
4312 (set (mem:HI (match_dup 3)) (const_int 0))]
4313 "")
4314
4315;; clear.b ry,[rx=rx+rz.S2]
4316
4317(define_split
4318 [(parallel
4319 [(set (mem:QI (plus:SI
4320 (mult:SI (match_operand:SI 0 "register_operand" "")
4321 (match_operand:SI 1 "const_int_operand" ""))
4322 (match_operand:SI 2 "register_operand" "")))
4323 (const_int 0))
4324 (set (match_operand:SI 3 "register_operand" "")
4325 (plus:SI (mult:SI (match_dup 0)
4326 (match_dup 1))
4327 (match_dup 2)))])]
4328 "REG_P (operands[2]) && REG_P (operands[3])
4329 && REGNO (operands[3]) == REGNO (operands[2])"
4330 [(set (match_dup 3) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
4331 (match_dup 2)))
4332 (set (mem:QI (match_dup 3)) (const_int 0))]
4333 "")
4334
4335;; clear.d ry,[rx=rx+i]
4336
4337(define_split
4338 [(parallel
4339 [(set (mem:SI
4340 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
4341 (match_operand:SI 1 "cris_bdap_operand" "")))
4342 (const_int 0))
4343 (set (match_operand:SI 2 "register_operand" "")
4344 (plus:SI (match_dup 0)
4345 (match_dup 1)))])]
4346 "(rtx_equal_p (operands[0], operands[2])
4347 || rtx_equal_p (operands[2], operands[1]))"
4348 [(set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))
4349 (set (mem:SI (match_dup 2)) (const_int 0))]
4350 "")
4351
4352;; clear.w ry,[rx=rx+i]
4353
4354(define_split
4355 [(parallel
4356 [(set (mem:HI
4357 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
4358 (match_operand:SI 1 "cris_bdap_operand" "")))
4359 (const_int 0))
4360 (set (match_operand:SI 2 "register_operand" "")
4361 (plus:SI (match_dup 0)
4362 (match_dup 1)))])]
4363 "(rtx_equal_p (operands[0], operands[2])
4364 || rtx_equal_p (operands[2], operands[1]))"
4365 [(set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))
4366 (set (mem:HI (match_dup 2)) (const_int 0))]
4367 "")
4368
4369;; clear.b ry,[rx=rx+i]
4370
4371(define_split
4372 [(parallel
4373 [(set (mem:QI
4374 (plus:SI (match_operand:SI 0 "cris_bdap_operand" "")
4375 (match_operand:SI 1 "cris_bdap_operand" "")))
4376 (const_int 0))
4377 (set (match_operand:SI 2 "register_operand" "")
4378 (plus:SI (match_dup 0)
4379 (match_dup 1)))])]
4380 "(rtx_equal_p (operands[0], operands[2])
4381 || rtx_equal_p (operands[2], operands[1]))"
4382 [(set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))
4383 (set (mem:QI (match_dup 2)) (const_int 0))]
4384 "")
4385
4386;; mov(s|u).S1 [rx=rx+rz.S2],ry
4387
4388(define_split
4389 [(parallel
4390 [(set (match_operand 0 "register_operand" "")
4391 (match_operator
4392 5 "cris_extend_operator"
4393 [(mem (plus:SI
4394 (mult:SI (match_operand:SI 1 "register_operand" "")
4395 (match_operand:SI 2 "const_int_operand" ""))
4396 (match_operand:SI 3 "register_operand" "")))]))
4397 (set (match_operand:SI 4 "register_operand" "")
4398 (plus:SI (mult:SI (match_dup 1)
4399 (match_dup 2))
4400 (match_dup 3)))])]
4401 "REG_P (operands[3])
4402 && REG_P (operands[4])
4403 && REGNO (operands[3]) == REGNO (operands[4])"
4404 [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
4405 (match_dup 3)))
4406 (set (match_dup 0) (match_op_dup 5 [(match_dup 6)]))]
4407 "operands[6] = gen_rtx_MEM (GET_MODE (XEXP (operands[5],0)),
4408 operands[4]);")
4409
4410;; mov(s|u).S1 [rx=rx+i],ry
4411
4412(define_split
4413 [(parallel
4414 [(set (match_operand 0 "register_operand" "")
4415 (match_operator
4416 4 "cris_extend_operator"
4417 [(mem (plus:SI
4418 (match_operand:SI 1 "cris_bdap_operand" "")
4419 (match_operand:SI 2 "cris_bdap_operand" "")))]))
4420 (set (match_operand:SI 3 "register_operand" "")
4421 (plus:SI (match_dup 1)
4422 (match_dup 2)))])]
4423 "(rtx_equal_p (operands[1], operands[3])
4424 || rtx_equal_p (operands[2], operands[3]))"
4425 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))
4426 (set (match_dup 0) (match_op_dup 4 [(match_dup 5)]))]
4427 "operands[5] = gen_rtx_MEM (GET_MODE (XEXP (operands[4], 0)),
4428 operands[3]);")
4429
4430;; op.S1 [rx=rx+i],ry
4431
4432(define_split
4433 [(parallel
4434 [(set (match_operand 0 "register_operand" "")
4435 (match_operator
4436 5 "cris_orthogonal_operator"
4437 [(match_operand 1 "register_operand" "")
4438 (mem (plus:SI
4439 (match_operand:SI 2 "cris_bdap_operand" "")
4440 (match_operand:SI 3 "cris_bdap_operand" "")))]))
4441 (set (match_operand:SI 4 "register_operand" "")
4442 (plus:SI (match_dup 2)
4443 (match_dup 3)))])]
4444 "(rtx_equal_p (operands[4], operands[2])
4445 || rtx_equal_p (operands[4], operands[3]))"
4446 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4447 (set (match_dup 0) (match_op_dup 5 [(match_dup 1) (match_dup 6)]))]
4448 "operands[6] = gen_rtx_MEM (GET_MODE (operands[0]), operands[4]);")
4449
4450;; op.S1 [rx=rx+rz.S2],ry
4451
4452(define_split
4453 [(parallel
4454 [(set (match_operand 0 "register_operand" "")
4455 (match_operator
4456 6 "cris_orthogonal_operator"
4457 [(match_operand 1 "register_operand" "")
4458 (mem (plus:SI
4459 (mult:SI (match_operand:SI 2 "register_operand" "")
4460 (match_operand:SI 3 "const_int_operand" ""))
4461 (match_operand:SI 4 "register_operand" "")))]))
4462 (set (match_operand:SI 5 "register_operand" "")
4463 (plus:SI (mult:SI (match_dup 2)
4464 (match_dup 3))
4465 (match_dup 4)))])]
4466 "REG_P (operands[4])
4467 && REG_P (operands[5])
4468 && REGNO (operands[5]) == REGNO (operands[4])"
4469 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4470 (match_dup 4)))
4471 (set (match_dup 0) (match_op_dup 6 [(match_dup 1) (match_dup 7)]))]
4472 "operands[7] = gen_rtx_MEM (GET_MODE (operands[0]), operands[5]);")
4473
4474;; op.S1 [rx=rx+rz.S2],ry (swapped)
4475
4476(define_split
4477 [(parallel
4478 [(set (match_operand 0 "register_operand" "")
4479 (match_operator
4480 6 "cris_commutative_orth_op"
4481 [(mem (plus:SI
4482 (mult:SI (match_operand:SI 2 "register_operand" "")
4483 (match_operand:SI 3 "const_int_operand" ""))
4484 (match_operand:SI 4 "register_operand" "")))
4485 (match_operand 1 "register_operand" "")]))
4486 (set (match_operand:SI 5 "register_operand" "")
4487 (plus:SI (mult:SI (match_dup 2)
4488 (match_dup 3))
4489 (match_dup 4)))])]
4490 "REG_P (operands[4])
4491 && REG_P (operands[5])
4492 && REGNO (operands[5]) == REGNO (operands[4])"
4493 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4494 (match_dup 4)))
4495 (set (match_dup 0) (match_op_dup 6 [(match_dup 7) (match_dup 1)]))]
4496 "operands[7] = gen_rtx_MEM (GET_MODE (operands[0]), operands[5]);")
4497
4498;; op.S1 [rx=rx+i],ry (swapped)
4499
4500(define_split
4501 [(parallel
4502 [(set (match_operand 0 "register_operand" "")
4503 (match_operator
4504 5 "cris_commutative_orth_op"
4505 [(mem
4506 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "")
4507 (match_operand:SI 3 "cris_bdap_operand" "")))
4508 (match_operand 1 "register_operand" "")]))
4509 (set (match_operand:SI 4 "register_operand" "")
4510 (plus:SI (match_dup 2)
4511 (match_dup 3)))])]
4512 "(rtx_equal_p (operands[4], operands[2])
4513 || rtx_equal_p (operands[4], operands[3]))"
4514 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4515 (set (match_dup 0) (match_op_dup 5 [(match_dup 6) (match_dup 1)]))]
4516 "operands[6] = gen_rtx_MEM (GET_MODE (operands[0]), operands[4]);")
4517
4518;; op(s|u).S1 [rx=rx+rz.S2],ry
4519
4520(define_split
4521 [(parallel
4522 [(set (match_operand 0 "register_operand" "")
4523 (match_operator
4524 6 "cris_operand_extend_operator"
4525 [(match_operand 1 "register_operand" "")
4526 (match_operator
4527 7 "cris_extend_operator"
4528 [(mem (plus:SI
4529 (mult:SI (match_operand:SI 2 "register_operand" "")
4530 (match_operand:SI 3 "const_int_operand" ""))
4531 (match_operand:SI 4 "register_operand" "")))])]))
4532 (set (match_operand:SI 5 "register_operand" "")
4533 (plus:SI (mult:SI (match_dup 2)
4534 (match_dup 3))
4535 (match_dup 4)))])]
4536 "REG_P (operands[4])
4537 && REG_P (operands[5])
4538 && REGNO (operands[5]) == REGNO (operands[4])"
4539 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4540 (match_dup 4)))
4541 (set (match_dup 0) (match_op_dup 6 [(match_dup 1) (match_dup 8)]))]
4542 "operands[8] = gen_rtx (GET_CODE (operands[7]), GET_MODE (operands[7]),
4543 gen_rtx_MEM (GET_MODE (XEXP (operands[7], 0)),
4544 operands[5]));")
4545
4546;; op(s|u).S1 [rx=rx+i],ry
4547
4548(define_split
4549 [(parallel
4550 [(set (match_operand 0 "register_operand" "")
4551 (match_operator
4552 5 "cris_operand_extend_operator"
4553 [(match_operand 1 "register_operand" "")
4554 (match_operator
4555 6 "cris_extend_operator"
4556 [(mem
4557 (plus:SI (match_operand:SI 2 "cris_bdap_operand" "")
4558 (match_operand:SI 3 "cris_bdap_operand" "")
4559 ))])]))
4560 (set (match_operand:SI 4 "register_operand" "")
4561 (plus:SI (match_dup 2)
4562 (match_dup 3)))])]
4563 "(rtx_equal_p (operands[4], operands[2])
4564 || rtx_equal_p (operands[4], operands[3]))"
4565 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4566 (set (match_dup 0) (match_op_dup 5 [(match_dup 1) (match_dup 7)]))]
4567 "operands[7] = gen_rtx (GET_CODE (operands[6]), GET_MODE (operands[6]),
4568 gen_rtx_MEM (GET_MODE (XEXP (operands[6], 0)),
4569 operands[4]));")
4570
4571;; op(s|u).S1 [rx=rx+rz.S2],ry (swapped, plus or bound)
4572
4573(define_split
4574 [(parallel
4575 [(set (match_operand 0 "register_operand" "")
4576 (match_operator
4577 7 "cris_plus_or_bound_operator"
4578 [(match_operator
4579 6 "cris_extend_operator"
4580 [(mem (plus:SI
4581 (mult:SI (match_operand:SI 2 "register_operand" "")
4582 (match_operand:SI 3 "const_int_operand" ""))
4583 (match_operand:SI 4 "register_operand" "")))])
4584 (match_operand 1 "register_operand" "")]))
4585 (set (match_operand:SI 5 "register_operand" "")
4586 (plus:SI (mult:SI (match_dup 2)
4587 (match_dup 3))
4588 (match_dup 4)))])]
4589 "REG_P (operands[4]) && REG_P (operands[5])
4590 && REGNO (operands[5]) == REGNO (operands[4])"
4591 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4592 (match_dup 4)))
4593 (set (match_dup 0) (match_op_dup 6 [(match_dup 8) (match_dup 1)]))]
4594 "operands[8] = gen_rtx (GET_CODE (operands[6]), GET_MODE (operands[6]),
4595 gen_rtx_MEM (GET_MODE (XEXP (operands[6], 0)),
4596 operands[5]));")
4597
4598;; op(s|u).S1 [rx=rx+i],ry (swapped, plus or bound)
4599
4600(define_split
4601 [(parallel
4602 [(set (match_operand 0 "register_operand" "")
4603 (match_operator
4604 6 "cris_plus_or_bound_operator"
4605 [(match_operator
4606 5 "cris_extend_operator"
4607 [(mem (plus:SI
4608 (match_operand:SI 2 "cris_bdap_operand" "")
4609 (match_operand:SI 3 "cris_bdap_operand" "")))])
4610 (match_operand 1 "register_operand" "")]))
4611 (set (match_operand:SI 4 "register_operand" "")
4612 (plus:SI (match_dup 2)
4613 (match_dup 3)))])]
4614 "(rtx_equal_p (operands[4], operands[2])
4615 || rtx_equal_p (operands[4], operands[3]))"
4616 [(set (match_dup 4) (plus:SI (match_dup 2) (match_dup 3)))
4617 (set (match_dup 0) (match_op_dup 6 [(match_dup 7) (match_dup 1)]))]
4618 "operands[7] = gen_rtx (GET_CODE (operands[5]), GET_MODE (operands[5]),
4619 gen_rtx_MEM (GET_MODE (XEXP (operands[5], 0)),
4620 operands[4]));")
4621\f
4622;; Splits for addressing prefixes that have no side-effects, so we can
4623;; fill a delay slot. Never split if we lose something, though.
4624
4625;; If we have a
4626;; move [indirect_ref],rx
4627;; where indirect ref = {const, [r+], [r]}, it costs as much as
4628;; move indirect_ref,rx
4629;; move [rx],rx
4630;; Take care not to allow indirect_ref = register.
4631
4632;; We're not allowed to generate copies of registers with different mode
4633;; until after reload; copying pseudos upsets reload. CVS as of
4634;; 2001-08-24, unwind-dw2-fde.c, _Unwind_Find_FDE ICE in
4635;; cselib_invalidate_regno.
4636
4637(define_split
4638 [(set (match_operand 0 "register_operand" "")
4639 (match_operand 1 "indirect_operand" ""))]
4640 "reload_completed
4641 && REG_P (operands[0])
4642 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4643 && (GET_CODE (XEXP (operands[1], 0)) == MEM
4644 || CONSTANT_P (XEXP (operands[1], 0)))"
4645 [(set (match_dup 2) (match_dup 4))
4646 (set (match_dup 0) (match_dup 3))]
4647 "operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
4648 operands[3] = gen_rtx_MEM (GET_MODE (operands[0]), operands[2]);
4649 operands[4] = XEXP (operands[1], 0);")
4650
4651;; As the above, but MOVS and MOVU.
4652
4653(define_split
4654 [(set (match_operand 0 "register_operand" "")
4655 (match_operator
4656 4 "cris_extend_operator"
4657 [(match_operand 1 "indirect_operand" "")]))]
4658 "reload_completed
4659 && REG_P (operands[0])
4660 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
4661 && (GET_CODE (XEXP (operands[1], 0)) == MEM
4662 || CONSTANT_P (XEXP (operands[1], 0)))"
4663 [(set (match_dup 2) (match_dup 5))
4664 (set (match_dup 0) (match_op_dup 4 [(match_dup 3)]))]
4665 "operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
4666 operands[3] = gen_rtx_MEM (GET_MODE (XEXP (operands[4], 0)), operands[2]);
4667 operands[5] = XEXP (operands[1], 0);")
4668\f
4669;; Various peephole optimizations.
4670;;
4671;; Watch out: when you exchange one set of instructions for another, the
4672;; condition codes setting must be the same, or you have to CC_INIT or
4673;; whatever is appropriate, in the pattern before you emit the
4674;; assembly text. This is best done here, not in cris_notice_update_cc,
4675;; to keep changes local to their cause.
4676;;
4677;; Do not add patterns that you do not know will be matched.
4678;; Please also add a self-contained test-case.
4679
4680;; We have trouble with and:s and shifts. Maybe something is broken in
4681;; gcc? Or it could just be that bitfield insn expansion is a bit
4682;; suboptimal when not having extzv insns.
4683
4684(define_peephole
4685 [(set (match_operand 0 "register_operand" "=r")
4686 (ashiftrt:SI (match_dup 0)
4687 (match_operand:SI 1 "const_int_operand" "n")))
4688 (set (match_dup 0)
4689 (and:SI (match_dup 0)
4690 (match_operand 2 "const_int_operand" "n")))]
4691 "INTVAL (operands[2]) > 31
4692 && INTVAL (operands[2]) < 255
4693 && INTVAL (operands[1]) > 23"
4694
4695;; The m flag should be ignored, because this will be a *byte* "and"
4696;; operation.
4697
4698 "*
4699{
4700 cc_status.flags |= CC_NOT_NEGATIVE;
4701
4702 return \"lsrq %1,%0\;and.b %2,%0\";
4703}")
4704
4705(define_peephole
4706 [(set (match_operand 0 "register_operand" "=r")
4707 (ashiftrt:SI (match_dup 0)
4708 (match_operand:SI 1 "const_int_operand" "n")))
4709 (set (match_dup 0)
4710 (and:SI (match_dup 0)
4711 (match_operand 2 "const_int_operand" "n")))]
4712 "INTVAL (operands[2]) > 31
4713 && INTVAL (operands[2]) < 65535
4714 && INTVAL (operands[2]) != 255
4715 && INTVAL (operands[1]) > 15"
4716
4717;; The m flag should be ignored, because this will be a *word* "and"
4718;; operation.
4719
4720 "*
4721{
4722 cc_status.flags |= CC_NOT_NEGATIVE;
4723
4724 return \"lsrq %1,%0\;and.w %2,%0\";
4725}")
4726
4727(define_peephole
4728 [(set (match_operand 0 "register_operand" "=r")
4729 (lshiftrt:SI (match_dup 0)
4730 (match_operand:SI 1 "const_int_operand" "n")))
4731 (set (match_dup 0)
4732 (and:SI (match_dup 0)
4733 (match_operand 2 "const_int_operand" "n")))]
4734 "INTVAL (operands[2]) > 31
4735 && INTVAL (operands[2]) < 255
4736 && INTVAL (operands[1]) > 23"
4737
4738;; The m flag should be ignored, because this will be a *byte* "and"
4739;; operation.
4740
4741 "*
4742{
4743 cc_status.flags |= CC_NOT_NEGATIVE;
4744
4745 return \"lsrq %1,%0\;and.b %2,%0\";
4746}")
4747
4748(define_peephole
4749 [(set (match_operand 0 "register_operand" "=r")
4750 (lshiftrt:SI (match_dup 0)
4751 (match_operand:SI 1 "const_int_operand" "n")))
4752 (set (match_dup 0)
4753 (and:SI (match_dup 0)
4754 (match_operand 2 "const_int_operand" "n")))]
4755 "INTVAL (operands[2]) > 31 && INTVAL (operands[2]) < 65535
4756 && INTVAL (operands[2]) != 255
4757 && INTVAL (operands[1]) > 15"
4758
4759;; The m flag should be ignored, because this will be a *word* "and"
4760;; operation.
4761
4762 "*
4763{
4764 cc_status.flags |= CC_NOT_NEGATIVE;
4765
4766 return \"lsrq %1,%0\;and.w %2,%0\";
4767}")
4768\f
4769
4770;; Change
4771;; add.d n,rx
4772;; move [rx],ry
4773;; into
4774;; move [rx=rx+n],ry
4775;; when -128 <= n <= 127.
4776;; This will reduce the size of the assembler code for n = [-128..127],
4777;; and speed up accordingly.
4778
4779(define_peephole
4780 [(set (match_operand:SI 0 "register_operand" "=r")
4781 (plus:SI (match_operand:SI 1 "register_operand" "0")
4782 (match_operand:SI 2 "const_int_operand" "n")))
4783 (set (match_operand 3 "register_operand" "=r")
4784 (mem (match_dup 0)))]
4785 "GET_MODE (operands[3]) != DImode
4786 && REGNO (operands[3]) != REGNO (operands[0])
4787 && (BASE_P (operands[1]) || BASE_P (operands[2]))
4788 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
4789 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
4790 && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
4791 "move.%s3 [%0=%1%S2],%3")
4792
4793;; Vice versa: move ry,[rx=rx+n]
4794
4795(define_peephole
4796 [(set (match_operand:SI 0 "register_operand" "=r")
4797 (plus:SI (match_operand:SI 1 "register_operand" "0")
4798 (match_operand:SI 2 "const_int_operand" "n")))
4799 (set (mem (match_dup 0))
4800 (match_operand 3 "register_operand" "=r"))]
4801 "GET_MODE (operands[3]) != DImode
4802 && REGNO (operands[3]) != REGNO (operands[0])
4803 && (BASE_P (operands[1]) || BASE_P (operands[2]))
4804 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
4805 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
4806 && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
4807 "move.%s3 %3,[%0=%1%S2]"
4808 [(set_attr "cc" "none")])
4809\f
4810;; As above, change:
4811;; add.d n,rx
4812;; op.d [rx],ry
4813;; into:
4814;; op.d [rx=rx+n],ry
4815;; Saves when n = [-128..127].
4816;;
4817;; Splitting and joining combinations for side-effect modes are slightly
4818;; out of hand. They probably will not save the time they take typing in,
4819;; not to mention the bugs that creep in. FIXME: Get rid of as many of
4820;; the splits and peepholes as possible.
4821
4822(define_peephole
4823 [(set (match_operand:SI 0 "register_operand" "=r")
4824 (plus:SI (match_operand:SI 1 "register_operand" "0")
4825 (match_operand:SI 2 "const_int_operand" "n")))
4826 (set (match_operand 3 "register_operand" "=r")
4827 (match_operator 4 "cris_orthogonal_operator"
4828 [(match_dup 3)
4829 (mem (match_dup 0))]))]
4830 "GET_MODE (operands[3]) != DImode
4831 && REGNO (operands[0]) != REGNO (operands[3])
4832 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
4833 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
4834 && INTVAL (operands[2]) >= -128
4835 && INTVAL (operands[2]) <= 127"
4836 "%x4.%s3 [%0=%1%S2],%3")
4837
4838;; Sometimes, for some reason the pattern
4839;; move x,rx
4840;; add y,rx
4841;; move [rx],rz
4842;; will occur. Solve this, and likewise for to-memory.
4843
4844(define_peephole
4845 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
4846 (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Ri,r,>Ri"))
4847 (set (match_dup 0)
4848 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Ri,r")
4849 (match_operand:SI 3 "cris_bdap_biap_operand" "r>Ri,r,0,0")))
4850 (set (match_operand 4 "register_operand" "=r,r,r,r")
4851 (mem (match_dup 0)))]
4852 "(rtx_equal_p (operands[2], operands[0])
4853 || rtx_equal_p (operands[3], operands[0]))
4854 && cris_side_effect_mode_ok (PLUS, operands, 0,
4855 (REG_S_P (operands[1])
4856 ? 1
4857 : (rtx_equal_p (operands[2], operands[0])
4858 ? 3 : 2)),
4859 (! REG_S_P (operands[1])
4860 ? 1
4861 : (rtx_equal_p (operands[2], operands[0])
4862 ? 3 : 2)),
4863 -1, 4)"
4864 "@
4865 move.%s4 [%0=%1%S3],%4
4866 move.%s4 [%0=%3%S1],%4
4867 move.%s4 [%0=%1%S2],%4
4868 move.%s4 [%0=%2%S1],%4")
4869
4870;; As above but to memory.
4871
4872(define_peephole
4873 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
4874 (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Ri,r,>Ri"))
4875 (set (match_dup 0)
4876 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Ri,r")
4877 (match_operand:SI 3 "cris_bdap_biap_operand" "r>Ri,r,0,0")))
4878 (set (mem (match_dup 0))
4879 (match_operand 4 "register_operand" "=r,r,r,r"))]
4880 "(rtx_equal_p (operands[2], operands[0])
4881 || rtx_equal_p (operands[3], operands[0]))
4882 && cris_side_effect_mode_ok (PLUS, operands, 0,
4883 (REG_S_P (operands[1])
4884 ? 1
4885 : (rtx_equal_p (operands[2], operands[0])
4886 ? 3 : 2)),
4887 (! REG_S_P (operands[1])
4888 ? 1
4889 : (rtx_equal_p (operands[2], operands[0])
4890 ? 3 : 2)),
4891 -1, 4)"
4892 "@
4893 move.%s4 %4,[%0=%1%S3]
4894 move.%s4 %4,[%0=%3%S1]
4895 move.%s4 %4,[%0=%1%S2]
4896 move.%s4 %4,[%0=%2%S1]"
4897 [(set_attr "cc" "none")])
4898
4899
4900;; As the move from-memory above, but with an operation.
4901
4902(define_peephole
4903 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
4904 (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Ri,r,>Ri"))
4905 (set (match_dup 0)
4906 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Ri,r")
4907 (match_operand:SI 3 "cris_bdap_biap_operand" "r>Ri,r,0,0")))
4908 (set (match_operand 4 "register_operand" "=r,r,r,r")
4909 (match_operator 5 "cris_orthogonal_operator"
4910 [(match_dup 3)
4911 (mem (match_dup 0))]))]
4912 "(rtx_equal_p (operands[2], operands[0])
4913 || rtx_equal_p (operands[3], operands[0]))
4914 && cris_side_effect_mode_ok (PLUS, operands, 0,
4915 (REG_S_P (operands[1])
4916 ? 1
4917 : (rtx_equal_p (operands[2], operands[0])
4918 ? 3 : 2)),
4919 (! REG_S_P (operands[1])
4920 ? 1
4921 : (rtx_equal_p (operands[2], operands[0])
4922 ? 3 : 2)),
4923 -1, 4)"
4924 "@
4925 %x5.%s4 [%0=%1%S3],%4
4926 %x5.%s4 [%0=%3%S1],%4
4927 %x5.%s4 [%0=%1%S2],%4
4928 %x5.%s4 [%0=%2%S1],%4")
4929
4930;; Same, but with swapped operands (and commutative operation).
4931
4932(define_peephole
4933 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
4934 (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Ri,r,>Ri"))
4935 (set (match_dup 0)
4936 (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Ri,r")
4937 (match_operand:SI 3 "cris_bdap_biap_operand" "r>Ri,r,0,0")))
4938 (set (match_operand 4 "register_operand" "=r,r,r,r")
4939 (match_operator 5 "cris_commutative_orth_op"
4940 [(mem (match_dup 0))
4941 (match_dup 3)]))]
4942 "(rtx_equal_p (operands[2], operands[0])
4943 || rtx_equal_p (operands[3], operands[0]))
4944 && cris_side_effect_mode_ok (PLUS, operands, 0,
4945 (REG_S_P (operands[1])
4946 ? 1
4947 : (rtx_equal_p (operands[2], operands[0])
4948 ? 3 : 2)),
4949 (! REG_S_P (operands[1])
4950 ? 1
4951 : (rtx_equal_p (operands[2], operands[0])
4952 ? 3 : 2)),
4953 -1, 4)"
4954 "@
4955 %x5.%s4 [%0=%1%S3],%4
4956 %x5.%s4 [%0=%3%S1],%4
4957 %x5.%s4 [%0=%1%S2],%4
4958 %x5.%s4 [%0=%2%S1],%4")
4959
4960;; Another spotted bad code:
4961;; move rx,ry
4962;; move [ry],ry
4963
4964(define_peephole
4965 [(set (match_operand:SI 0 "register_operand" "=r")
4966 (match_operand:SI 1 "register_operand" "r"))
4967 (set (match_operand 2 "register_operand" "=r")
4968 (mem (match_dup 0)))]
4969 "REGNO (operands[0]) == REGNO (operands[2])
4970 && GET_MODE_SIZE (GET_MODE (operands[2])) <= UNITS_PER_WORD"
4971 "move.%s2 [%1],%0"
4972 [(set_attr "slottable" "yes")])
4973
4974;; And a simple variant with extended operand.
4975
4976(define_peephole
4977 [(set (match_operand:SI 0 "register_operand" "=r")
4978 (match_operand:SI 1 "register_operand" "r"))
4979 (set (match_operand 2 "register_operand" "=r")
4980 (match_operator 3 "cris_extend_operator" [(mem (match_dup 0))]))]
4981 "REGNO (operands[0]) == REGNO (operands[2])
4982 && GET_MODE_SIZE (GET_MODE (operands[2])) <= UNITS_PER_WORD"
4983 "mov%e3.%m3 [%1],%0"
4984 [(set_attr "slottable" "yes")])
4985\f
4986;; Here are all peepholes that have a saved testcase.
4987;; Do not add new peepholes without testcases.
4988
4989;; peep-1:
4990;; move.d [r10+16],r9
4991;; and.d r12,r9
4992;; change to
4993;; and.d [r10+16],r12,r9
4994;; With generalization of the operation, the size and the addressing mode.
4995;; This seems to be the result of a quirk in register allocation
4996;; missing the three-operand cases when having different predicates.
4997;; Maybe that it matters that it is a commutative operation.
4998;; This pattern helps that situation, but there's still the increased
4999;; register pressure.
5000;; Note that adding the noncommutative variant did not show any matches
5001;; in ipps and cc1, so it's not here.
5002
5003(define_peephole
5004 [(set (match_operand 0 "register_operand" "=r,r,r,r")
5005 (mem (plus:SI
5006 (match_operand:SI 1 "cris_bdap_biap_operand" "r,r>Ri,r,r>Ri")
5007 (match_operand:SI 2 "cris_bdap_biap_operand" "r>Ri,r,r>Ri,r"))))
5008 (set (match_dup 0)
5009 (match_operator 5 "cris_commutative_orth_op"
5010 [(match_operand 3 "register_operand" "0,0,r,r")
5011 (match_operand 4 "register_operand" "r,r,0,0")]))]
5012 "(rtx_equal_p (operands[3], operands[0])
5013 || rtx_equal_p (operands[4], operands[0]))
5014 && ! rtx_equal_p (operands[3], operands[4])
5015 && (REG_S_P (operands[1]) || REG_S_P (operands[2]))
5016 && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD"
5017 "@
5018 %x5.%s0 [%1%S2],%4,%0
5019 %x5.%s0 [%2%S1],%4,%0
5020 %x5.%s0 [%1%S2],%3,%0
5021 %x5.%s0 [%2%S1],%3,%0")
5022
5023;; peep-2:
5024;; I cannot tell GCC (2.1, 2.7.2) how to correctly reload an instruction
5025;; that looks like
5026;; and.b some_byte,const,reg_32
5027;; where reg_32 is the destination of the "three-address" code optimally.
5028;; It should be:
5029;; movu.b some_byte,reg_32
5030;; and.b const,reg_32
5031;; but is turns into:
5032;; move.b some_byte,reg_32
5033;; and.d const,reg_32
5034;; Fix it here.
5035
5036(define_peephole
5037 [(set (match_operand:SI 0 "register_operand" "=r")
5038 (match_operand:SI 1 "nonimmediate_operand" "rm"))
5039 (set (match_operand:SI 2 "register_operand" "=0")
5040 (and:SI (match_dup 0)
5041 (match_operand:SI 3 "const_int_operand" "n")))]
5042
5043 ;; Since the size of the memory access could be made different here,
5044 ;; don't do this for a mem-volatile access.
5045
5046 "REGNO (operands[2]) == REGNO (operands[0])
5047 && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
5048 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
5049 && (GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1]))"
5050 "*
5051{
5052 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O'))
5053 return \"movu.%z3 %1,%0\;andq %b3,%0\";
5054
5055 cc_status.flags |= CC_NOT_NEGATIVE;
5056
5057 return \"movu.%z3 %1,%0\;and.%z3 %3,%0\";
5058}")
5059
5060;; peep-3
5061
5062(define_peephole
5063 [(set (match_operand 0 "register_operand" "=r")
5064 (match_operand 1 "nonimmediate_operand" "rm"))
5065 (set (match_operand:SI 2 "register_operand" "=r")
5066 (and:SI (subreg:SI (match_dup 0) 0)
5067 (match_operand 3 "const_int_operand" "n")))]
5068
5069 ;; Since the size of the memory access could be made different here,
5070 ;; don't do this for a mem-volatile access.
5071
5072 "REGNO (operands[0]) == REGNO (operands[2])
5073 && INTVAL (operands[3]) > 0
5074 && INTVAL (operands[3]) <= 65535
5075 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
5076 && (GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1]))"
5077 "*
5078{
5079 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O'))
5080 return \"movu.%z3 %1,%0\;andq %b3,%0\";
5081
5082 cc_status.flags |= CC_NOT_NEGATIVE;
5083
5084 return \"movu.%z3 %1,%0\;and.%z3 %3,%0\";
5085}")
5086\f
5087;; Local variables:
5088;; mode:emacs-lisp
5089;; comment-start: ";; "
5090;; eval: (set-syntax-table (copy-sequence (syntax-table)))
5091;; eval: (modify-syntax-entry ?[ "(]")
5092;; eval: (modify-syntax-entry ?] ")[")
5093;; eval: (modify-syntax-entry ?{ "(}")
5094;; eval: (modify-syntax-entry ?} "){")
5095;; eval: (setq indent-tabs-mode t)
5096;; End: