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