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