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