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