]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
(SUBTARGET_SWITCHES): Renamed from ARM_EXTRA_TARGET_SWITCHES.
[thirdparty/gcc.git] / gcc / config / arm / arm.md
CommitLineData
3d91c5d6 1;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
9c532fac 2;; Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
b11cae9e 3;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4;; and Martin Simmons (@harleqn.co.uk).
9c08d1fa 5;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
b11cae9e 6
7;; This file is part of GNU CC.
8
9;; GNU CC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
14;; GNU CC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GNU CC; see the file COPYING. If not, write to
21;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
9c08d1fa 25;; There are patterns in this file to support XFmode arithmetic.
3d91c5d6 26;; Unfortunately RISC iX doesn't work well with these so they are disabled.
9c08d1fa 27;; (See arm.h)
28\f
29;; UNSPEC Usage:
30;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
31;; the mode is MODE_FLOAT
32;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
33;; the mode is MODE_FLOAT
87b22bf7 34;; 2 `push multiple' operation: operand 0 is the first register. Subsequent
35;; registers are in parallel (use...) expressions.
b11cae9e 36\f
9c08d1fa 37;; Attributes
38
39; condition codes: this one is used by final_prescan_insn to speed up
40; conditionalizing instructions. It saves having to scan the rtl to see if
41; it uses or alters the condition codes.
42
43; USE means that the condition codes are used by the insn in the process of
44; outputting code, this means (at present) that we can't use the insn in
45; inlined branches
46
47; SET means that the purpose of the insn is to set the condition codes in a
48; well defined manner.
49
50; CLOB means that the condition codes are altered in an undefined manner, if
51; they are altered at all
52
53; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
54; but are if the branch wasn't taken; the effect is to limit the branch
55; elimination scanning.
56
57; NOCOND means that the condition codes are niether altered nor affect the
58; output of this insn
59
60(define_attr "conds" "use,set,clob,jump_clob,nocond"
61 (const_string "nocond"))
62
63; CPU attribute is used to determine whether condition codes are clobbered
64; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
65; arm2 and arm3 the condition codes are restored by the return.
66
67(define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
68
3d91c5d6 69; Floating Point Unit. If we only have floating point emulation, then there
70; is no point in scheduling the floating point insns. (Well, for best
71; performance we should try and group them together).
72
73(define_attr "fpu" "fpa,fpe" (const (symbol_ref "arm_fpu_attr")))
74
094e994f 75; LENGTH of an instruction (in bytes)
76(define_attr "length" "" (const_int 4))
9c08d1fa 77
78; An assembler sequence may clobber the condition codes without us knowing
79(define_asm_attributes
80 [(set_attr "conds" "clob")
094e994f 81 (set_attr "length" "4")])
9c08d1fa 82
83; TYPE attribute is used to detect floating point instructions which, if
84; running on a co-processor can run in parallel with other, basic instructions
85; If write-buffer scheduling is enabled then it can also be used in the
86; scheduling of writes.
87
88; Classification of each insn
89; normal any data instruction that doesn't hit memory or fp regs
90; block blockage insn, this blocks all functional units
91; float a floating point arithmetic operation (subject to expansion)
3d91c5d6 92; fdivx XFmode floating point division
93; fdivd DFmode floating point division
94; fdivs SFmode floating point division
95; fmul Floating point multiply
96; ffmul Fast floating point multiply
97; farith Floating point arithmetic (4 cycle)
98; ffarith Fast floating point arithmetic (2 cycle)
9c08d1fa 99; float_em a floating point arithmetic operation that is normally emulated
3d91c5d6 100; even on a machine with an fpa.
9c08d1fa 101; f_load a floating point load from memory
102; f_store a floating point store to memory
103; f_mem_r a transfer of a floating point register to a real reg via mem
104; r_mem_f the reverse of f_mem_r
105; f_2_r fast transfer float to arm (no memory needed)
106; r_2_f fast transfer arm to float
107; call a subroutine call
108; load any load from memory
109; store1 store 1 word to memory from arm registers
110; store2 store 2 words
111; store3 store 3 words
112; store4 store 4 words
113;
114(define_attr "type"
3d91c5d6 115 "normal,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
9c08d1fa 116 (const_string "normal"))
117
118(define_attr "write_conflict" "no,yes"
119 (if_then_else (eq_attr "type"
120 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
121 (const_string "yes")
122 (const_string "no")))
123
124; The write buffer on some of the arm6 processors is hard to model exactly.
125; There is room in the buffer for up to two addresses and up to eight words
126; of memory, but the two needn't be split evenly. When writing the two
127; addresses are fully pipelined. However, a read from memory that is not
128; currently in the cache will block until the writes have completed.
129; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
130; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
131; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
132; cycle to add as well.
133
134;; (define_function_unit {name} {num-units} {n-users} {test}
135;; {ready-delay} {issue-delay} [{conflict-list}])
3d91c5d6 136(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
137 (eq_attr "type" "fdivx")) 71 69)
138
139(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
140 (eq_attr "type" "fdivd")) 59 57)
141
142(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
143 (eq_attr "type" "fdivs")) 31 29)
144
145(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
146 (eq_attr "type" "fmul")) 9 7)
147
148(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
149 (eq_attr "type" "ffmul")) 6 4)
150
151(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
152 (eq_attr "type" "farith")) 4 2)
153
154(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
155 (eq_attr "type" "ffarith")) 2 2)
156
157(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
158 (eq_attr "type" "r_2_f")) 5 3)
159
160(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
161 (eq_attr "type" "f_2_r")) 1 2)
162
163;; The fpa10 doesn't really have a memory read unit, but it can start to
164;; speculatively execute the instruction in the pipeline, provided the data
165;; is already loaded, so pretend reads have a delay of 2 (and that the
166;; pipeline is infinite.
167
168(define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
169 (eq_attr "type" "f_load")) 3 1)
9c08d1fa 170
171(define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
172 [(eq_attr "write_conflict" "yes")])
173(define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
174 [(eq_attr "write_conflict" "yes")])
175(define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
176 [(eq_attr "write_conflict" "yes")])
177(define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
178 [(eq_attr "write_conflict" "yes")])
179(define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
180 [(eq_attr "write_conflict" "yes")])
181\f
182;; Note: For DImode insns, there is normally no reason why operands should
183;; not be in the same register, what we don't want is for something being
184;; written to partially overlap something that is an input.
185
b11cae9e 186;; Addition insns.
187
188(define_insn "adddi3"
9c08d1fa 189 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
190 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
191 (match_operand:DI 2 "s_register_operand" "r,0")))
192 (clobber (reg:CC 24))]
b11cae9e 193 ""
e2348bcb 194 "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
9c08d1fa 195[(set_attr "conds" "clob")
094e994f 196 (set_attr "length" "8")])
9c08d1fa 197
198(define_insn ""
199 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
200 (plus:DI (sign_extend:DI
201 (match_operand:SI 1 "s_register_operand" "r,r"))
202 (match_operand:DI 2 "s_register_operand" "r,0")))
203 (clobber (reg:CC 24))]
204 ""
e2348bcb 205 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
9c08d1fa 206[(set_attr "conds" "clob")
094e994f 207 (set_attr "length" "8")])
9c08d1fa 208
209(define_insn ""
210 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
211 (plus:DI (zero_extend:DI
212 (match_operand:SI 1 "s_register_operand" "r,r"))
213 (match_operand:DI 2 "s_register_operand" "r,0")))
214 (clobber (reg:CC 24))]
215 ""
e2348bcb 216 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
9c08d1fa 217[(set_attr "conds" "clob")
094e994f 218 (set_attr "length" "8")])
b11cae9e 219
87b22bf7 220(define_expand "addsi3"
221 [(set (match_operand:SI 0 "s_register_operand" "")
222 (plus:SI (match_operand:SI 1 "s_register_operand" "")
223 (match_operand:SI 2 "reg_or_int_operand" "")))]
224 ""
225 "
226 if (GET_CODE (operands[2]) == CONST_INT)
227 {
228 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
229 operands[1],
230 (reload_in_progress || reload_completed ? 0
231 : preserve_subexpressions_p ()));
232 DONE;
233 }
234")
235
236(define_split
237 [(set (match_operand:SI 0 "s_register_operand" "")
238 (plus:SI (match_operand:SI 1 "s_register_operand" "")
239 (match_operand:SI 2 "const_int_operand" "")))]
240 "! (const_ok_for_arm (INTVAL (operands[2]))
241 || const_ok_for_arm (-INTVAL (operands[2])))"
242 [(clobber (const_int 0))]
243 "
244 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
245 operands[1], 0);
246 DONE;
247")
248
249(define_insn ""
250 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
251 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
252 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
b11cae9e 253 ""
5565501b 254 "@
255 add%?\\t%0, %1, %2
87b22bf7 256 sub%?\\t%0, %1, #%n2
257 #"
258[(set_attr "length" "4,4,16")])
b11cae9e 259
9c08d1fa 260(define_insn ""
261 [(set (reg:CC_NOOV 24)
5565501b 262 (compare:CC_NOOV
263 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
264 (match_operand:SI 2 "arm_add_operand" "rI,L"))
265 (const_int 0)))
266 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 267 (plus:SI (match_dup 1) (match_dup 2)))]
268 ""
5565501b 269 "@
270 add%?s\\t%0, %1, %2
271 sub%?s\\t%0, %1, #%n2"
9c08d1fa 272[(set_attr "conds" "set")])
273
274(define_insn ""
275 [(set (reg:CC 24)
5565501b 276 (compare:CC (match_operand:SI 1 "s_register_operand" "r,r")
277 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
278 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 279 (plus:SI (match_dup 1) (match_dup 2)))]
280 ""
5565501b 281 "@
282 add%?s\\t%0, %1, %2
283 sub%?s\\t%0, %1, #%n2"
9c08d1fa 284[(set_attr "conds" "set")])
285
286(define_insn "incscc"
287 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
288 (plus:SI (match_operator:SI 2 "comparison_operator"
289 [(reg 24) (const_int 0)])
290 (match_operand:SI 1 "s_register_operand" "0,?r")))]
b11cae9e 291 ""
5565501b 292 "@
293 add%d2\\t%0, %1, #1
294 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
9c08d1fa 295[(set_attr "conds" "use")
5565501b 296 (set_attr "length" "4,8")])
9c08d1fa 297
298; If a constant is too big to fit in a single instruction then the constant
299; will be pre-loaded into a register taking at least two insns, we might be
300; able to merge it with an add, but it depends on the exact value.
301
302(define_split
303 [(set (match_operand:SI 0 "s_register_operand" "=r")
304 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
305 (match_operand:SI 2 "immediate_operand" "n")))]
306 "!(const_ok_for_arm (INTVAL (operands[2]))
307 || const_ok_for_arm (-INTVAL (operands[2])))"
308 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
309 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
310 "
311{
312 unsigned int val = (unsigned) INTVAL (operands[2]);
313 int i;
314 unsigned int temp;
315
316 /* this code is similar to the approach followed in movsi, but it must
317 generate exactly two insns */
318
319 for (i = 30; i >= 0; i -= 2)
320 {
321 if (val & (3 << i))
322 {
323 i -= 6;
324 if (i < 0) i = 0;
325 if (const_ok_for_arm (temp = (val & ~(255 << i))))
326 {
327 val &= 255 << i;
328 break;
329 }
330 /* we might be able to do this as (larger number - small number) */
331 temp = ((val >> i) & 255) + 1;
332 if (temp > 255 && i < 24)
333 {
334 i += 2;
335 temp = ((val >> i) & 255) + 1;
336 }
337 if (const_ok_for_arm ((temp << i) - val))
338 {
339 i = temp << i;
340 temp = (unsigned) - (int) (i - val);
341 val = i;
342 break;
343 }
344 FAIL;
345 }
346 }
347 /* if we got here, we have found a way of doing it in two instructions.
348 the two constants are in val and temp */
349 operands[2] = GEN_INT ((int)val);
350 operands[3] = GEN_INT ((int)temp);
351}
b11cae9e 352")
353
9c08d1fa 354(define_insn "addsf3"
355 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
356 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
357 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
358 ""
5565501b 359 "@
360 adf%?s\\t%0, %1, %2
361 suf%?s\\t%0, %1, #%N2"
3d91c5d6 362[(set_attr "type" "farith")])
9c08d1fa 363
b11cae9e 364(define_insn "adddf3"
9c08d1fa 365 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
366 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
367 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
368 ""
5565501b 369 "@
370 adf%?d\\t%0, %1, %2
371 suf%?d\\t%0, %1, #%N2"
3d91c5d6 372[(set_attr "type" "farith")])
9c08d1fa 373
374(define_insn ""
375 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
376 (plus:DF (float_extend:DF
377 (match_operand:SF 1 "s_register_operand" "f,f"))
378 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
379 ""
5565501b 380 "@
381 adf%?d\\t%0, %1, %2
382 suf%?d\\t%0, %1, #%N2"
3d91c5d6 383[(set_attr "type" "farith")])
9c08d1fa 384
385(define_insn ""
386 [(set (match_operand:DF 0 "s_register_operand" "=f")
387 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
388 (float_extend:DF
389 (match_operand:SF 2 "s_register_operand" "f"))))]
b11cae9e 390 ""
40dbec34 391 "adf%?d\\t%0, %1, %2"
3d91c5d6 392[(set_attr "type" "farith")])
9c08d1fa 393
394(define_insn ""
395 [(set (match_operand:DF 0 "s_register_operand" "=f")
396 (plus:DF (float_extend:DF
397 (match_operand:SF 1 "s_register_operand" "f"))
398 (float_extend:DF
399 (match_operand:SF 2 "s_register_operand" "f"))))]
400 ""
40dbec34 401 "adf%?d\\t%0, %1, %2"
3d91c5d6 402[(set_attr "type" "farith")])
9c08d1fa 403
404(define_insn "addxf3"
405 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
406 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
407 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
408 "ENABLE_XF_PATTERNS"
5565501b 409 "@
410 adf%?e\\t%0, %1, %2
411 suf%?e\\t%0, %1, #%N2"
3d91c5d6 412[(set_attr "type" "farith")])
b11cae9e 413
414(define_insn "subdi3"
9c08d1fa 415 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
416 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
417 (match_operand:DI 2 "s_register_operand" "r,0,0")))
418 (clobber (reg:CC 24))]
b11cae9e 419 ""
e2348bcb 420 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
9c08d1fa 421[(set_attr "conds" "clob")
094e994f 422 (set_attr "length" "8")])
9c08d1fa 423
424(define_insn ""
425 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
426 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
427 (zero_extend:DI
428 (match_operand:SI 2 "s_register_operand" "r,r"))))
429 (clobber (reg:CC 24))]
430 ""
e2348bcb 431 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
9c08d1fa 432[(set_attr "conds" "clob")
094e994f 433 (set_attr "length" "8")])
9c08d1fa 434
435(define_insn ""
436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
437 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
438 (sign_extend:DI
439 (match_operand:SI 2 "s_register_operand" "r,r"))))
440 (clobber (reg:CC 24))]
441 ""
e2348bcb 442 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
9c08d1fa 443[(set_attr "conds" "clob")
094e994f 444 (set_attr "length" "8")])
9c08d1fa 445
446(define_insn ""
447 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
448 (minus:DI (zero_extend:DI
449 (match_operand:SI 2 "s_register_operand" "r,r"))
450 (match_operand:DI 1 "s_register_operand" "?r,0")))
451 (clobber (reg:CC 24))]
452 ""
e2348bcb 453 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
9c08d1fa 454[(set_attr "conds" "clob")
094e994f 455 (set_attr "length" "8")])
9c08d1fa 456
457(define_insn ""
458 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
459 (minus:DI (sign_extend:DI
460 (match_operand:SI 2 "s_register_operand" "r,r"))
461 (match_operand:DI 1 "s_register_operand" "?r,0")))
462 (clobber (reg:CC 24))]
463 ""
e2348bcb 464 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
9c08d1fa 465[(set_attr "conds" "clob")
094e994f 466 (set_attr "length" "8")])
9c08d1fa 467
468(define_insn ""
469 [(set (match_operand:DI 0 "s_register_operand" "=r")
470 (minus:DI (zero_extend:DI
471 (match_operand:SI 1 "s_register_operand" "r"))
472 (zero_extend:DI
473 (match_operand:SI 2 "s_register_operand" "r"))))
474 (clobber (reg:CC 24))]
475 ""
e2348bcb 476 "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
9c08d1fa 477[(set_attr "conds" "clob")
094e994f 478 (set_attr "length" "8")])
b11cae9e 479
87b22bf7 480(define_expand "subsi3"
481 [(set (match_operand:SI 0 "s_register_operand" "")
482 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
483 (match_operand:SI 2 "s_register_operand" "")))]
484 ""
485 "
486 if (GET_CODE (operands[1]) == CONST_INT)
487 {
488 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
489 operands[2],
490 (reload_in_progress || reload_completed ? 0
491 : preserve_subexpressions_p ()));
492 DONE;
493 }
494")
495
496(define_insn ""
9c08d1fa 497 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 498 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
499 (match_operand:SI 2 "s_register_operand" "r,r")))]
b11cae9e 500 ""
e2348bcb 501 "@
87b22bf7 502 rsb%?\\t%0, %2, %1
503 #"
504[(set_attr "length" "4,16")])
505
506(define_split
507 [(set (match_operand:SI 0 "s_register_operand" "")
508 (minus:SI (match_operand:SI 1 "const_int_operand" "")
509 (match_operand:SI 2 "s_register_operand" "")))]
510 "! const_ok_for_arm (INTVAL (operands[1]))"
511 [(clobber (const_int 0))]
512 "
513 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
514 operands[2], 0);
515 DONE;
516")
b11cae9e 517
9c08d1fa 518(define_insn ""
519 [(set (reg:CC_NOOV 24)
520 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
521 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
522 (const_int 0)))
523 (set (match_operand:SI 0 "s_register_operand" "=r,r")
524 (minus:SI (match_dup 1) (match_dup 2)))]
525 ""
e2348bcb 526 "@
40dbec34 527 sub%?s\\t%0, %1, %2
528 rsb%?s\\t%0, %2, %1"
9c08d1fa 529[(set_attr "conds" "set")])
530
531(define_insn "decscc"
532 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
533 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
534 (match_operator:SI 2 "comparison_operator"
535 [(reg 24) (const_int 0)])))]
536 ""
e2348bcb 537 "@
538 sub%d2\\t%0, %1, #1
539 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
9c08d1fa 540[(set_attr "conds" "use")
094e994f 541 (set_attr "length" "*,8")])
9c08d1fa 542
b11cae9e 543(define_insn "subsf3"
9c08d1fa 544 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
c8f69309 545 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
546 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
b11cae9e 547 ""
e2348bcb 548 "@
40dbec34 549 suf%?s\\t%0, %1, %2
550 rsf%?s\\t%0, %2, %1"
3d91c5d6 551[(set_attr "type" "farith")])
b11cae9e 552
553(define_insn "subdf3"
9c08d1fa 554 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
c8f69309 555 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
9c08d1fa 556 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
b11cae9e 557 ""
e2348bcb 558 "@
40dbec34 559 suf%?d\\t%0, %1, %2
560 rsf%?d\\t%0, %2, %1"
3d91c5d6 561[(set_attr "type" "farith")])
9c08d1fa 562
563(define_insn ""
564 [(set (match_operand:DF 0 "s_register_operand" "=f")
565 (minus:DF (float_extend:DF
566 (match_operand:SF 1 "s_register_operand" "f"))
567 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
568 ""
40dbec34 569 "suf%?d\\t%0, %1, %2"
3d91c5d6 570[(set_attr "type" "farith")])
9c08d1fa 571
572(define_insn ""
573 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
574 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
575 (float_extend:DF
576 (match_operand:SF 2 "s_register_operand" "f,f"))))]
577 ""
e2348bcb 578 "@
40dbec34 579 suf%?d\\t%0, %1, %2
580 rsf%?d\\t%0, %2, %1"
3d91c5d6 581[(set_attr "type" "farith")])
9c08d1fa 582
583(define_insn ""
584 [(set (match_operand:DF 0 "s_register_operand" "=f")
585 (minus:DF (float_extend:DF
586 (match_operand:SF 1 "s_register_operand" "f"))
587 (float_extend:DF
588 (match_operand:SF 2 "s_register_operand" "f"))))]
589 ""
40dbec34 590 "suf%?d\\t%0, %1, %2"
3d91c5d6 591[(set_attr "type" "farith")])
9c08d1fa 592
593(define_insn "subxf3"
594 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
595 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
596 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
597 "ENABLE_XF_PATTERNS"
e2348bcb 598 "@
40dbec34 599 suf%?e\\t%0, %1, %2
600 rsf%?e\\t%0, %2, %1"
3d91c5d6 601[(set_attr "type" "farith")])
b11cae9e 602\f
603;; Multiplication insns
604
9c08d1fa 605;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
b11cae9e 606(define_insn "mulsi3"
9c08d1fa 607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
608 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
609 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
b11cae9e 610 ""
40dbec34 611 "mul%?\\t%0, %2, %1")
b11cae9e 612
9c08d1fa 613(define_insn ""
614 [(set (reg:CC_NOOV 24)
615 (compare:CC_NOOV (mult:SI
616 (match_operand:SI 2 "s_register_operand" "r,r")
617 (match_operand:SI 1 "s_register_operand" "%?r,0"))
618 (const_int 0)))
619 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
620 (mult:SI (match_dup 2) (match_dup 1)))]
621 ""
40dbec34 622 "mul%?s\\t%0, %2, %1"
9c08d1fa 623[(set_attr "conds" "set")])
624
625(define_insn ""
626 [(set (reg:CC_NOOV 24)
627 (compare:CC_NOOV (mult:SI
628 (match_operand:SI 2 "s_register_operand" "r,r")
629 (match_operand:SI 1 "s_register_operand" "%?r,0"))
630 (const_int 0)))
631 (clobber (match_scratch:SI 0 "=&r,&r"))]
632 ""
40dbec34 633 "mul%?s\\t%0, %2, %1"
9c08d1fa 634[(set_attr "conds" "set")])
635
b11cae9e 636;; Unnamed templates to match MLA instruction.
637
638(define_insn ""
9c08d1fa 639 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 640 (plus:SI
9c08d1fa 641 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
642 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
643 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
b11cae9e 644 ""
40dbec34 645 "mla%?\\t%0, %2, %1, %3")
b11cae9e 646
647(define_insn ""
9c08d1fa 648 [(set (reg:CC_NOOV 24)
649 (compare:CC_NOOV (plus:SI
650 (mult:SI
651 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
652 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
653 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
654 (const_int 0)))
655 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
656 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
657 (match_dup 3)))]
b11cae9e 658 ""
40dbec34 659 "mla%?s\\t%0, %2, %1, %3"
9c08d1fa 660[(set_attr "conds" "set")])
661
662(define_insn ""
663 [(set (reg:CC_NOOV 24)
664 (compare:CC_NOOV (plus:SI
665 (mult:SI
666 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
667 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
668 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
669 (const_int 0)))
670 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
671 ""
40dbec34 672 "mla%?s\\t%0, %2, %1, %3"
9c08d1fa 673[(set_attr "conds" "set")])
b11cae9e 674
675(define_insn "mulsf3"
9c08d1fa 676 [(set (match_operand:SF 0 "s_register_operand" "=f")
677 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
c8f69309 678 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
b11cae9e 679 ""
40dbec34 680 "fml%?s\\t%0, %1, %2"
3d91c5d6 681[(set_attr "type" "ffmul")])
b11cae9e 682
683(define_insn "muldf3"
9c08d1fa 684 [(set (match_operand:DF 0 "s_register_operand" "=f")
685 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
c8f69309 686 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
b11cae9e 687 ""
40dbec34 688 "muf%?d\\t%0, %1, %2"
3d91c5d6 689[(set_attr "type" "fmul")])
9c08d1fa 690
691(define_insn ""
692 [(set (match_operand:DF 0 "s_register_operand" "=f")
693 (mult:DF (float_extend:DF
694 (match_operand:SF 1 "s_register_operand" "f"))
695 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
696 ""
40dbec34 697 "muf%?d\\t%0, %1, %2"
3d91c5d6 698[(set_attr "type" "fmul")])
9c08d1fa 699
700(define_insn ""
701 [(set (match_operand:DF 0 "s_register_operand" "=f")
702 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
703 (float_extend:DF
704 (match_operand:SF 2 "s_register_operand" "f"))))]
705 ""
40dbec34 706 "muf%?d\\t%0, %1, %2"
3d91c5d6 707[(set_attr "type" "fmul")])
9c08d1fa 708
709(define_insn ""
710 [(set (match_operand:DF 0 "s_register_operand" "=f")
711 (mult:DF (float_extend:DF
712 (match_operand:SF 1 "s_register_operand" "f"))
713 (float_extend:DF
714 (match_operand:SF 2 "s_register_operand" "f"))))]
715 ""
40dbec34 716 "muf%?d\\t%0, %1, %2"
3d91c5d6 717[(set_attr "type" "fmul")])
9c08d1fa 718
719(define_insn "mulxf3"
720 [(set (match_operand:XF 0 "s_register_operand" "=f")
721 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
722 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
723 "ENABLE_XF_PATTERNS"
40dbec34 724 "muf%?e\\t%0, %1, %2"
3d91c5d6 725[(set_attr "type" "fmul")])
b11cae9e 726\f
727;; Division insns
728
729(define_insn "divsf3"
9c08d1fa 730 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
c8f69309 731 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
732 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
b11cae9e 733 ""
e2348bcb 734 "@
40dbec34 735 fdv%?s\\t%0, %1, %2
736 frd%?s\\t%0, %2, %1"
3d91c5d6 737[(set_attr "type" "fdivs")])
b11cae9e 738
739(define_insn "divdf3"
9c08d1fa 740 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
c8f69309 741 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
742 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
b11cae9e 743 ""
e2348bcb 744 "@
40dbec34 745 dvf%?d\\t%0, %1, %2
746 rdf%?d\\t%0, %2, %1"
3d91c5d6 747[(set_attr "type" "fdivd")])
9c08d1fa 748
749(define_insn ""
750 [(set (match_operand:DF 0 "s_register_operand" "=f")
751 (div:DF (float_extend:DF
752 (match_operand:SF 1 "s_register_operand" "f"))
753 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
754 ""
40dbec34 755 "dvf%?d\\t%0, %1, %2"
3d91c5d6 756[(set_attr "type" "fdivd")])
9c08d1fa 757
758(define_insn ""
759 [(set (match_operand:DF 0 "s_register_operand" "=f")
760 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
761 (float_extend:DF
762 (match_operand:SF 2 "s_register_operand" "f"))))]
763 ""
40dbec34 764 "rdf%?d\\t%0, %2, %1"
3d91c5d6 765[(set_attr "type" "fdivd")])
9c08d1fa 766
767(define_insn ""
768 [(set (match_operand:DF 0 "s_register_operand" "=f")
769 (div:DF (float_extend:DF
770 (match_operand:SF 1 "s_register_operand" "f"))
771 (float_extend:DF
772 (match_operand:SF 2 "s_register_operand" "f"))))]
773 ""
40dbec34 774 "dvf%?d\\t%0, %1, %2"
3d91c5d6 775[(set_attr "type" "fdivd")])
9c08d1fa 776
777(define_insn "divxf3"
778 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
779 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
780 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
781 "ENABLE_XF_PATTERNS"
e2348bcb 782 "@
40dbec34 783 dvf%?e\\t%0, %1, %2
784 rdf%?e\\t%0, %2, %1"
3d91c5d6 785[(set_attr "type" "fdivx")])
b11cae9e 786\f
787;; Modulo insns
788
789(define_insn "modsf3"
9c08d1fa 790 [(set (match_operand:SF 0 "s_register_operand" "=f")
791 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
c8f69309 792 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
b11cae9e 793 ""
40dbec34 794 "rmf%?s\\t%0, %1, %2"
3d91c5d6 795[(set_attr "type" "fdivs")])
b11cae9e 796
797(define_insn "moddf3"
9c08d1fa 798 [(set (match_operand:DF 0 "s_register_operand" "=f")
799 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
c8f69309 800 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
b11cae9e 801 ""
40dbec34 802 "rmf%?d\\t%0, %1, %2"
3d91c5d6 803[(set_attr "type" "fdivd")])
9c08d1fa 804
805(define_insn ""
806 [(set (match_operand:DF 0 "s_register_operand" "=f")
807 (mod:DF (float_extend:DF
808 (match_operand:SF 1 "s_register_operand" "f"))
809 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
810 ""
40dbec34 811 "rmf%?d\\t%0, %1, %2"
3d91c5d6 812[(set_attr "type" "fdivd")])
9c08d1fa 813
814(define_insn ""
815 [(set (match_operand:DF 0 "s_register_operand" "=f")
816 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
817 (float_extend:DF
818 (match_operand:SF 2 "s_register_operand" "f"))))]
819 ""
40dbec34 820 "rmf%?d\\t%0, %1, %2"
3d91c5d6 821[(set_attr "type" "fdivd")])
9c08d1fa 822
823(define_insn ""
824 [(set (match_operand:DF 0 "s_register_operand" "=f")
825 (mod:DF (float_extend:DF
826 (match_operand:SF 1 "s_register_operand" "f"))
827 (float_extend:DF
828 (match_operand:SF 2 "s_register_operand" "f"))))]
829 ""
40dbec34 830 "rmf%?d\\t%0, %1, %2"
3d91c5d6 831[(set_attr "type" "fdivd")])
9c08d1fa 832
833(define_insn "modxf3"
834 [(set (match_operand:XF 0 "s_register_operand" "=f")
835 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
836 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
837 "ENABLE_XF_PATTERNS"
40dbec34 838 "rmf%?e\\t%0, %1, %2"
3d91c5d6 839[(set_attr "type" "fdivx")])
b11cae9e 840\f
841;; Boolean and,ior,xor insns
842
843(define_insn "anddi3"
9c08d1fa 844 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
845 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
846 (match_operand:DI 2 "s_register_operand" "r,0")))]
b11cae9e 847 ""
40dbec34 848 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
094e994f 849[(set_attr "length" "8")])
b11cae9e 850
9c08d1fa 851(define_insn ""
852 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
853 (and:DI (zero_extend:DI
854 (match_operand:SI 2 "s_register_operand" "r,r"))
855 (match_operand:DI 1 "s_register_operand" "?r,0")))]
b11cae9e 856 ""
40dbec34 857 "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
094e994f 858[(set_attr "length" "8")])
b11cae9e 859
9c08d1fa 860(define_insn ""
861 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
862 (and:DI (sign_extend:DI
863 (match_operand:SI 2 "s_register_operand" "r,r"))
864 (match_operand:DI 1 "s_register_operand" "?r,0")))]
b11cae9e 865 ""
40dbec34 866 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
094e994f 867[(set_attr "length" "8")])
b11cae9e 868
87b22bf7 869(define_expand "andsi3"
870 [(set (match_operand:SI 0 "s_register_operand" "")
871 (and:SI (match_operand:SI 1 "s_register_operand" "")
872 (match_operand:SI 2 "reg_or_int_operand" "")))]
873 ""
874 "
875 if (GET_CODE (operands[2]) == CONST_INT)
876 {
877 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
878 operands[1],
879 (reload_in_progress || reload_completed
880 ? 0 : preserve_subexpressions_p ()));
881 DONE;
882 }
883")
884
885(define_insn ""
886 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
887 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
888 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
b11cae9e 889 ""
5565501b 890 "@
891 and%?\\t%0, %1, %2
87b22bf7 892 bic%?\\t%0, %1, #%B2
893 #"
894[(set_attr "length" "4,4,16")])
895
896(define_split
897 [(set (match_operand:SI 0 "s_register_operand" "")
898 (and:SI (match_operand:SI 1 "s_register_operand" "")
899 (match_operand:SI 2 "const_int_operand" "")))]
900 "! (const_ok_for_arm (INTVAL (operands[2]))
901 || const_ok_for_arm (~ INTVAL (operands[2])))"
902 [(clobber (const_int 0))]
903 "
904 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
905 operands[1], 0);
906 DONE;
907")
b11cae9e 908
9c08d1fa 909(define_insn ""
910 [(set (reg:CC_NOOV 24)
5565501b 911 (compare:CC_NOOV
912 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
913 (match_operand:SI 2 "arm_not_operand" "rI,K"))
914 (const_int 0)))
915 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 916 (and:SI (match_dup 1) (match_dup 2)))]
b11cae9e 917 ""
5565501b 918 "@
919 and%?s\\t%0, %1, %2
920 bic%?s\\t%0, %1, #%B2"
9c08d1fa 921[(set_attr "conds" "set")])
922
923(define_insn ""
924 [(set (reg:CC_NOOV 24)
5565501b 925 (compare:CC_NOOV
926 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
927 (match_operand:SI 1 "arm_not_operand" "rI,K"))
928 (const_int 0)))
929 (clobber (match_scratch:SI 3 "=X,r"))]
9c08d1fa 930 ""
5565501b 931 "@
932 tst%?\\t%0, %1
933 bic%?s\\t%3, %0, #%B1"
9c08d1fa 934[(set_attr "conds" "set")])
935
936(define_insn ""
937 [(set (reg:CC_NOOV 24)
938 (compare:CC_NOOV (zero_extract:SI
939 (match_operand:SI 0 "s_register_operand" "r")
940 (match_operand:SI 1 "immediate_operand" "n")
941 (match_operand:SI 2 "immediate_operand" "n"))
942 (const_int 0)))]
943 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
944 && INTVAL (operands[1]) > 0
945 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
946 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
947 "*
948{
949 unsigned int mask = 0;
950 int cnt = INTVAL (operands[1]);
951
952 while (cnt--)
953 mask = (mask << 1) | 1;
e2348bcb 954 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
40dbec34 955 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 956 return \"\";
9c08d1fa 957}
958"
959[(set_attr "conds" "set")])
960
961(define_insn ""
962 [(set (reg:CC_NOOV 24)
963 (compare:CC_NOOV (zero_extract:SI
964 (match_operand:QI 0 "memory_operand" "m")
965 (match_operand 1 "immediate_operand" "n")
966 (match_operand 2 "immediate_operand" "n"))
967 (const_int 0)))
968 (clobber (match_scratch:QI 3 "=r"))]
969 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
970 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
971 "*
972{
973 unsigned int mask = 0;
974 int cnt = INTVAL (operands[1]);
975
976 while (cnt--)
977 mask = (mask << 1) | 1;
e2348bcb 978 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
40dbec34 979 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
980 output_asm_insn (\"tst%?\\t%3, %1\", operands);
e2348bcb 981 return \"\";
9c08d1fa 982}
983"
984[(set_attr "conds" "set")
094e994f 985 (set_attr "length" "8")])
9c08d1fa 986
987;; constants for op 2 will never be given to these patterns.
988(define_insn ""
989 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
990 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
991 (match_operand:DI 1 "s_register_operand" "0,r")))]
992 ""
40dbec34 993 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
094e994f 994[(set_attr "length" "8")])
9c08d1fa 995
996(define_insn ""
997 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
998 (and:DI (not:DI (zero_extend:DI
999 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 1000 (match_operand:DI 1 "s_register_operand" "0,?r")))]
9c08d1fa 1001 ""
e2348bcb 1002 "@
40dbec34 1003 bic%?\\t%0, %1, %2
1004 bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
e2348bcb 1005[(set_attr "length" "4,8")])
9c08d1fa 1006
1007(define_insn ""
1008 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1009 (and:DI (not:DI (sign_extend:DI
1010 (match_operand:SI 2 "s_register_operand" "r,r")))
1011 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1012 ""
40dbec34 1013 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
094e994f 1014[(set_attr "length" "8")])
9c08d1fa 1015
1016(define_insn ""
1017 [(set (match_operand:SI 0 "s_register_operand" "=r")
1018 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1019 (match_operand:SI 1 "s_register_operand" "r")))]
1020 ""
40dbec34 1021 "bic%?\\t%0, %1, %2")
b11cae9e 1022
9c08d1fa 1023(define_insn ""
1024 [(set (reg:CC_NOOV 24)
e2348bcb 1025 (compare:CC_NOOV
1026 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1027 (match_operand:SI 1 "s_register_operand" "r"))
1028 (const_int 0)))
9c08d1fa 1029 (set (match_operand:SI 0 "s_register_operand" "=r")
1030 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1031 ""
40dbec34 1032 "bic%?s\\t%0, %1, %2"
9c08d1fa 1033[(set_attr "conds" "set")])
1034
1035(define_insn ""
1036 [(set (reg:CC_NOOV 24)
e2348bcb 1037 (compare:CC_NOOV
1038 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1039 (match_operand:SI 1 "s_register_operand" "r"))
1040 (const_int 0)))
9c08d1fa 1041 (clobber (match_scratch:SI 0 "=r"))]
1042 ""
40dbec34 1043 "bic%?s\\t%0, %1, %2"
9c08d1fa 1044[(set_attr "conds" "set")])
1045
1046(define_insn "iordi3"
1047 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1048 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1049 (match_operand:DI 2 "s_register_operand" "r")))]
1050 ""
40dbec34 1051 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
094e994f 1052[(set_attr "length" "8")])
9c08d1fa 1053
1054(define_insn ""
1055 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1056 (ior:DI (zero_extend:DI
1057 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 1058 (match_operand:DI 1 "s_register_operand" "0,?r")))]
9c08d1fa 1059 ""
e2348bcb 1060 "@
40dbec34 1061 orr%?\\t%0, %1, %2
1062 orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
e2348bcb 1063[(set_attr "length" "4,8")])
9c08d1fa 1064
1065(define_insn ""
1066 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1067 (ior:DI (sign_extend:DI
1068 (match_operand:SI 2 "s_register_operand" "r,r"))
1069 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1070 ""
40dbec34 1071 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
094e994f 1072[(set_attr "length" "8")])
9c08d1fa 1073
87b22bf7 1074(define_expand "iorsi3"
1075 [(set (match_operand:SI 0 "s_register_operand" "")
1076 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1077 (match_operand:SI 2 "reg_or_int_operand" "")))]
1078 ""
1079 "
1080 if (GET_CODE (operands[2]) == CONST_INT)
1081 {
1082 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1083 operands[1],
1084 (reload_in_progress || reload_completed
1085 ? 0 : preserve_subexpressions_p ()));
1086 DONE;
1087 }
1088")
1089
1090(define_insn ""
1091 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1092 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1093 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
9c08d1fa 1094 ""
87b22bf7 1095 "@
1096 orr%?\\t%0, %1, %2
1097 #"
1098[(set_attr "length" "4,16")])
9c08d1fa 1099
87b22bf7 1100(define_split
1101 [(set (match_operand:SI 0 "s_register_operand" "")
1102 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1103 (match_operand:SI 2 "const_int_operand" "")))]
1104 "! const_ok_for_arm (INTVAL (operands[2]))"
1105 [(clobber (const_int 0))]
1106 "
1107 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1108 operands[1], 0);
1109 DONE;
1110")
1111
9c08d1fa 1112(define_insn ""
1113 [(set (reg:CC_NOOV 24)
1114 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1115 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1116 (const_int 0)))
1117 (set (match_operand:SI 0 "s_register_operand" "=r")
1118 (ior:SI (match_dup 1) (match_dup 2)))]
1119 ""
40dbec34 1120 "orr%?s\\t%0, %1, %2"
9c08d1fa 1121[(set_attr "conds" "set")])
1122
1123(define_insn ""
1124 [(set (reg:CC_NOOV 24)
1125 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1126 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1127 (const_int 0)))
1128 (clobber (match_scratch:SI 0 "=r"))]
1129 ""
40dbec34 1130 "orr%?s\\t%0, %1, %2"
9c08d1fa 1131[(set_attr "conds" "set")])
1132
1133(define_insn "xordi3"
1134 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1135 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1136 (match_operand:DI 2 "s_register_operand" "r,0")))]
1137 ""
40dbec34 1138 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
094e994f 1139[(set_attr "length" "8")])
9c08d1fa 1140
1141(define_insn ""
1142 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1143 (xor:DI (zero_extend:DI
1144 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 1145 (match_operand:DI 1 "s_register_operand" "0,?r")))]
9c08d1fa 1146 ""
e2348bcb 1147 "@
40dbec34 1148 eor%?\\t%0, %1, %2
1149 eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
e2348bcb 1150[(set_attr "length" "4,8")])
9c08d1fa 1151
1152(define_insn ""
1153 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1154 (xor:DI (sign_extend:DI
1155 (match_operand:SI 2 "s_register_operand" "r,r"))
1156 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1157 ""
40dbec34 1158 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
094e994f 1159[(set_attr "length" "8")])
9c08d1fa 1160
b11cae9e 1161(define_insn "xorsi3"
9c08d1fa 1162 [(set (match_operand:SI 0 "s_register_operand" "=r")
1163 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1164 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
b11cae9e 1165 ""
40dbec34 1166 "eor%?\\t%0, %1, %2")
9c08d1fa 1167
1168(define_insn ""
1169 [(set (reg:CC_NOOV 24)
1170 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1171 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1172 (const_int 0)))
1173 (set (match_operand:SI 0 "s_register_operand" "=r")
1174 (xor:SI (match_dup 1) (match_dup 2)))]
1175 ""
40dbec34 1176 "eor%?s\\t%0, %1, %2"
9c08d1fa 1177[(set_attr "conds" "set")])
1178
1179(define_insn ""
1180 [(set (reg:CC_NOOV 24)
1181 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1182 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1183 (const_int 0)))]
1184 ""
40dbec34 1185 "teq%?\\t%0, %1"
9c08d1fa 1186[(set_attr "conds" "set")])
1187
1188;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1189;; (NOT D) we can sometimes merge the final NOT into one of the following
1190;; insns
1191
1192(define_split
1193 [(set (match_operand:SI 0 "s_register_operand" "=r")
1194 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1195 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1196 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1197 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1198 ""
1199 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1200 (not:SI (match_dup 3))))
1201 (set (match_dup 0) (not:SI (match_dup 4)))]
1202 ""
1203)
1204
1205(define_insn ""
1206 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1207 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1208 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1209 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1210 ""
40dbec34 1211 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
094e994f 1212[(set_attr "length" "8")])
9c08d1fa 1213
1214\f
1215
1216;; Minimum and maximum insns
1217
1218(define_insn "smaxsi3"
1219 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1220 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1221 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1222 (clobber (reg:CC 24))]
1223 ""
e2348bcb 1224 "@
1225 cmp\\t%1, %2\;movlt\\t%0, %2
1226 cmp\\t%1, %2\;movge\\t%0, %1
1227 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
9c08d1fa 1228[(set_attr "conds" "clob")
094e994f 1229 (set_attr "length" "8,8,12")])
9c08d1fa 1230
1231(define_insn "sminsi3"
1232 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1233 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1234 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1235 (clobber (reg:CC 24))]
1236 ""
e2348bcb 1237 "@
1238 cmp\\t%1, %2\;movge\\t%0, %2
1239 cmp\\t%1, %2\;movlt\\t%0, %1
1240 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
9c08d1fa 1241[(set_attr "conds" "clob")
094e994f 1242 (set_attr "length" "8,8,12")])
9c08d1fa 1243
1244(define_insn "umaxsi3"
1245 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1246 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1247 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1248 (clobber (reg:CC 24))]
1249 ""
e2348bcb 1250 "@
1251 cmp\\t%1, %2\;movcc\\t%0, %2
1252 cmp\\t%1, %2\;movcs\\t%0, %1
1253 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
9c08d1fa 1254[(set_attr "conds" "clob")
094e994f 1255 (set_attr "length" "8,8,12")])
9c08d1fa 1256
1257(define_insn "uminsi3"
1258 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1259 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1260 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1261 (clobber (reg:CC 24))]
1262 ""
e2348bcb 1263 "@
1264 cmp\\t%1, %2\;movcs\\t%0, %2
1265 cmp\\t%1, %2\;movcc\\t%0, %1
1266 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
9c08d1fa 1267[(set_attr "conds" "clob")
094e994f 1268 (set_attr "length" "8,8,12")])
9c08d1fa 1269
1270(define_insn ""
1271 [(set (match_operand:SI 0 "memory_operand" "=m")
1272 (match_operator:SI 3 "minmax_operator"
1273 [(match_operand:SI 1 "s_register_operand" "r")
1274 (match_operand:SI 2 "s_register_operand" "r")]))
1275 (clobber (reg:CC 24))]
1276 ""
1277 "*
1278 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1279 operands[2]);
e2348bcb 1280 output_asm_insn (\"cmp\\t%1, %2\", operands);
1281 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1282 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1283 return \"\";
9c08d1fa 1284"
1285[(set_attr "conds" "clob")
094e994f 1286 (set_attr "length" "12")
9c08d1fa 1287 (set_attr "type" "store1")])
1288
1289(define_insn ""
1290 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1291 (match_operator:SI 4 "shiftable_operator"
1292 [(match_operator:SI 5 "minmax_operator"
1293 [(match_operand:SI 2 "s_register_operand" "r,r")
1294 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1295 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1296 (clobber (reg:CC 24))]
1297 ""
1298 "*
1299{
9c08d1fa 1300 enum rtx_code code = GET_CODE (operands[4]);
9c08d1fa 1301
1302 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1303 operands[3]);
e2348bcb 1304 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 1305 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
9c08d1fa 1306 if (which_alternative != 0 || operands[3] != const0_rtx
1307 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
40dbec34 1308 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
9c08d1fa 1309 return \"\";
1310}
1311"
1312[(set_attr "conds" "clob")
094e994f 1313 (set_attr "length" "12")])
9c08d1fa 1314
b11cae9e 1315\f
1316;; Shift and rotation insns
1317
87b22bf7 1318(define_expand "ashlsi3"
1319 [(set (match_operand:SI 0 "s_register_operand" "")
1320 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1321 (match_operand:SI 2 "arm_rhs_operand" "")))]
b11cae9e 1322 ""
87b22bf7 1323 "
1324 if (GET_CODE (operands[2]) == CONST_INT
1325 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1326 {
1327 emit_insn (gen_movsi (operands[0], const0_rtx));
1328 DONE;
1329 }
1330")
b11cae9e 1331
87b22bf7 1332(define_expand "ashrsi3"
1333 [(set (match_operand:SI 0 "s_register_operand" "")
1334 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1335 (match_operand:SI 2 "arm_rhs_operand" "")))]
b11cae9e 1336 ""
87b22bf7 1337 "
1338 if (GET_CODE (operands[2]) == CONST_INT
1339 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1340 operands[2] = GEN_INT (31);
1341")
b11cae9e 1342
87b22bf7 1343(define_expand "lshrsi3"
1344 [(set (match_operand:SI 0 "s_register_operand" "")
1345 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1346 (match_operand:SI 2 "arm_rhs_operand" "")))]
b11cae9e 1347 ""
87b22bf7 1348 "
1349 if (GET_CODE (operands[2]) == CONST_INT
1350 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1351 {
1352 emit_insn (gen_movsi (operands[0], const0_rtx));
1353 DONE;
1354 }
1355")
b11cae9e 1356
87b22bf7 1357(define_expand "rotlsi3"
1358 [(set (match_operand:SI 0 "s_register_operand" "")
1359 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1360 (match_operand:SI 2 "reg_or_int_operand" "")))]
b11cae9e 1361 ""
87b22bf7 1362 "
1363 if (GET_CODE (operands[2]) == CONST_INT)
1364 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1365 else
b11cae9e 1366 {
87b22bf7 1367 rtx reg = gen_reg_rtx (SImode);
1368 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1369 operands[2] = reg;
b11cae9e 1370 }
1371")
9c08d1fa 1372
87b22bf7 1373(define_expand "rotrsi3"
1374 [(set (match_operand:SI 0 "s_register_operand" "")
1375 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1376 (match_operand:SI 2 "arm_rhs_operand" "")))]
1377 ""
1378 "
1379 if (GET_CODE (operands[2]) == CONST_INT
1380 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1381 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1382")
1383
1384(define_insn ""
1385 [(set (match_operand:SI 0 "s_register_operand" "=r")
1386 (match_operator:SI 3 "shift_operator"
1387 [(match_operand:SI 1 "s_register_operand" "r")
1388 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1389 ""
1390 "mov%?\\t%0, %1%S3")
1391
9c08d1fa 1392(define_insn ""
1393 [(set (reg:CC_NOOV 24)
87b22bf7 1394 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1395 [(match_operand:SI 1 "s_register_operand" "r")
1396 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9c08d1fa 1397 (const_int 0)))
1398 (set (match_operand:SI 0 "s_register_operand" "=r")
87b22bf7 1399 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
9c08d1fa 1400 ""
87b22bf7 1401 "mov%?s\\t%0, %1%S3"
9c08d1fa 1402[(set_attr "conds" "set")])
1403
1404(define_insn ""
1405 [(set (reg:CC_NOOV 24)
87b22bf7 1406 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1407 [(match_operand:SI 1 "s_register_operand" "r")
1408 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9c08d1fa 1409 (const_int 0)))
1410 (clobber (match_scratch:SI 0 "=r"))]
1411 ""
87b22bf7 1412 "mov%?s\\t%0, %1%S3"
9c08d1fa 1413[(set_attr "conds" "set")])
1414
1415(define_insn ""
1416 [(set (match_operand:SI 0 "s_register_operand" "=r")
87b22bf7 1417 (not:SI (match_operator:SI 3 "shift_operator"
1418 [(match_operand:SI 1 "s_register_operand" "r")
1419 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
9c08d1fa 1420 ""
87b22bf7 1421 "mvn%?\\t%0, %1%S3")
9c08d1fa 1422
1423(define_insn ""
1424 [(set (reg:CC_NOOV 24)
87b22bf7 1425 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1426 [(match_operand:SI 1 "s_register_operand" "r")
1427 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
9c08d1fa 1428 (const_int 0)))
1429 (set (match_operand:SI 0 "s_register_operand" "=r")
87b22bf7 1430 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
9c08d1fa 1431 ""
87b22bf7 1432 "mvn%?s\\t%0, %1%S3"
9c08d1fa 1433[(set_attr "conds" "set")])
1434
1435(define_insn ""
1436 [(set (reg:CC_NOOV 24)
87b22bf7 1437 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1438 [(match_operand:SI 1 "s_register_operand" "r")
1439 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
9c08d1fa 1440 (const_int 0)))
1441 (clobber (match_scratch:SI 0 "=r"))]
1442 ""
87b22bf7 1443 "mvn%?s\\t%0, %1%S3"
9c08d1fa 1444[(set_attr "conds" "set")])
1445
b11cae9e 1446\f
1447;; Unary arithmetic insns
1448
1449(define_insn "negdi2"
9c08d1fa 1450 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1451 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
b11cae9e 1452 ""
e2348bcb 1453 "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
9c08d1fa 1454[(set_attr "conds" "clob")
094e994f 1455 (set_attr "length" "8")])
b11cae9e 1456
1457(define_insn "negsi2"
9c08d1fa 1458 [(set (match_operand:SI 0 "s_register_operand" "=r")
1459 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
b11cae9e 1460 ""
40dbec34 1461 "rsb%?\\t%0, %1, #0")
b11cae9e 1462
1463(define_insn "negsf2"
9c08d1fa 1464 [(set (match_operand:SF 0 "s_register_operand" "=f")
1465 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
b11cae9e 1466 ""
40dbec34 1467 "mnf%?s\\t%0, %1"
3d91c5d6 1468[(set_attr "type" "ffarith")])
b11cae9e 1469
1470(define_insn "negdf2"
9c08d1fa 1471 [(set (match_operand:DF 0 "s_register_operand" "=f")
1472 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
b11cae9e 1473 ""
40dbec34 1474 "mnf%?d\\t%0, %1"
3d91c5d6 1475[(set_attr "type" "ffarith")])
9c08d1fa 1476
1477(define_insn ""
1478 [(set (match_operand:DF 0 "s_register_operand" "=f")
1479 (neg:DF (float_extend:DF
1480 (match_operand:SF 1 "s_register_operand" "f"))))]
1481 ""
40dbec34 1482 "mnf%?d\\t%0, %1"
3d91c5d6 1483[(set_attr "type" "ffarith")])
9c08d1fa 1484
1485(define_insn "negxf2"
1486 [(set (match_operand:XF 0 "s_register_operand" "=f")
1487 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1488 "ENABLE_XF_PATTERNS"
40dbec34 1489 "mnf%?e\\t%0, %1"
3d91c5d6 1490[(set_attr "type" "ffarith")])
9c08d1fa 1491
1492;; abssi2 doesn't really clobber the condition codes if a different register
1493;; is being set. To keep things simple, assume during rtl manipulations that
1494;; it does, but tell the final scan operator the truth. Similarly for
1495;; (neg (abs...))
1496
1497(define_insn "abssi2"
1498 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1499 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1500 (clobber (reg 24))]
1501 ""
e2348bcb 1502 "@
1503 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
40dbec34 1504 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
9c08d1fa 1505[(set_attr "conds" "clob,*")
094e994f 1506 (set_attr "length" "8")])
9c08d1fa 1507
1508(define_insn ""
1509 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1510 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1511 (clobber (reg 24))]
1512 ""
e2348bcb 1513 "@
1514 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
40dbec34 1515 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
9c08d1fa 1516[(set_attr "conds" "clob,*")
094e994f 1517 (set_attr "length" "8")])
b11cae9e 1518
1519(define_insn "abssf2"
9c08d1fa 1520 [(set (match_operand:SF 0 "s_register_operand" "=f")
1521 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
b11cae9e 1522 ""
40dbec34 1523 "abs%?s\\t%0, %1"
3d91c5d6 1524[(set_attr "type" "ffarith")])
b11cae9e 1525
1526(define_insn "absdf2"
9c08d1fa 1527 [(set (match_operand:DF 0 "s_register_operand" "=f")
1528 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
b11cae9e 1529 ""
40dbec34 1530 "abs%?d\\t%0, %1"
3d91c5d6 1531[(set_attr "type" "ffarith")])
9c08d1fa 1532
1533(define_insn ""
1534 [(set (match_operand:DF 0 "s_register_operand" "=f")
1535 (abs:DF (float_extend:DF
1536 (match_operand:SF 1 "s_register_operand" "f"))))]
1537 ""
40dbec34 1538 "abs%?d\\t%0, %1"
3d91c5d6 1539[(set_attr "type" "ffarith")])
9c08d1fa 1540
1541(define_insn "absxf2"
1542 [(set (match_operand:XF 0 "s_register_operand" "=f")
1543 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1544 "ENABLE_XF_PATTERNS"
40dbec34 1545 "abs%?e\\t%0, %1"
3d91c5d6 1546[(set_attr "type" "ffarith")])
b11cae9e 1547
1548(define_insn "sqrtsf2"
9c08d1fa 1549 [(set (match_operand:SF 0 "s_register_operand" "=f")
1550 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
b11cae9e 1551 ""
40dbec34 1552 "sqt%?s\\t%0, %1"
9c08d1fa 1553[(set_attr "type" "float_em")])
b11cae9e 1554
1555(define_insn "sqrtdf2"
9c08d1fa 1556 [(set (match_operand:DF 0 "s_register_operand" "=f")
1557 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
b11cae9e 1558 ""
40dbec34 1559 "sqt%?d\\t%0, %1"
9c08d1fa 1560[(set_attr "type" "float_em")])
1561
1562(define_insn ""
1563 [(set (match_operand:DF 0 "s_register_operand" "=f")
1564 (sqrt:DF (float_extend:DF
1565 (match_operand:SF 1 "s_register_operand" "f"))))]
1566 ""
40dbec34 1567 "sqt%?d\\t%0, %1"
9c08d1fa 1568[(set_attr "type" "float_em")])
1569
1570(define_insn "sqrtxf2"
1571 [(set (match_operand:XF 0 "s_register_operand" "=f")
1572 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1573 "ENABLE_XF_PATTERNS"
40dbec34 1574 "sqt%?e\\t%0, %1"
9c08d1fa 1575[(set_attr "type" "float_em")])
1576
1577(define_insn "sinsf2"
1578 [(set (match_operand:SF 0 "s_register_operand" "=f")
1579 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1580 ""
40dbec34 1581 "sin%?s\\t%0, %1"
9c08d1fa 1582[(set_attr "type" "float_em")])
1583
1584(define_insn "sindf2"
1585 [(set (match_operand:DF 0 "s_register_operand" "=f")
1586 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1587 ""
40dbec34 1588 "sin%?d\\t%0, %1"
9c08d1fa 1589[(set_attr "type" "float_em")])
1590
1591(define_insn ""
1592 [(set (match_operand:DF 0 "s_register_operand" "=f")
1593 (unspec:DF [(float_extend:DF
1594 (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1595 ""
40dbec34 1596 "sin%?d\\t%0, %1"
9c08d1fa 1597[(set_attr "type" "float_em")])
1598
1599(define_insn "sinxf2"
1600 [(set (match_operand:XF 0 "s_register_operand" "=f")
1601 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1602 "ENABLE_XF_PATTERNS"
40dbec34 1603 "sin%?e\\t%0, %1"
9c08d1fa 1604[(set_attr "type" "float_em")])
1605
1606(define_insn "cossf2"
1607 [(set (match_operand:SF 0 "s_register_operand" "=f")
1608 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1609 ""
40dbec34 1610 "cos%?s\\t%0, %1"
9c08d1fa 1611[(set_attr "type" "float_em")])
1612
1613(define_insn "cosdf2"
1614 [(set (match_operand:DF 0 "s_register_operand" "=f")
1615 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1616 ""
40dbec34 1617 "cos%?d\\t%0, %1"
9c08d1fa 1618[(set_attr "type" "float_em")])
1619
1620(define_insn ""
1621 [(set (match_operand:DF 0 "s_register_operand" "=f")
1622 (unspec:DF [(float_extend:DF
1623 (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1624 ""
40dbec34 1625 "cos%?d\\t%0, %1"
9c08d1fa 1626[(set_attr "type" "float_em")])
1627
1628(define_insn "cosxf2"
1629 [(set (match_operand:XF 0 "s_register_operand" "=f")
1630 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1631 "ENABLE_XF_PATTERNS"
40dbec34 1632 "cos%?e\\t%0, %1"
9c08d1fa 1633[(set_attr "type" "float_em")])
1634
1635(define_insn "one_cmpldi2"
1636 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1637 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1638 ""
40dbec34 1639 "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
094e994f 1640[(set_attr "length" "8")])
b11cae9e 1641
1642(define_insn "one_cmplsi2"
9c08d1fa 1643 [(set (match_operand:SI 0 "s_register_operand" "=r")
1644 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
b11cae9e 1645 ""
40dbec34 1646 "mvn%?\\t%0, %1")
9c08d1fa 1647
1648(define_insn ""
1649 [(set (reg:CC_NOOV 24)
1650 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1651 (const_int 0)))
1652 (set (match_operand:SI 0 "s_register_operand" "=r")
1653 (not:SI (match_dup 1)))]
1654 ""
40dbec34 1655 "mvn%?s\\t%0, %1"
9c08d1fa 1656[(set_attr "conds" "set")])
1657
1658(define_insn ""
1659 [(set (reg:CC_NOOV 24)
1660 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1661 (const_int 0)))
1662 (clobber (match_scratch:SI 0 "=r"))]
1663 ""
40dbec34 1664 "mvn%?s\\t%0, %1"
9c08d1fa 1665[(set_attr "conds" "set")])
b11cae9e 1666\f
1667;; Fixed <--> Floating conversion insns
1668
1669(define_insn "floatsisf2"
9c08d1fa 1670 [(set (match_operand:SF 0 "s_register_operand" "=f")
1671 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
b11cae9e 1672 ""
40dbec34 1673 "flt%?s\\t%0, %1"
9c08d1fa 1674[(set_attr "type" "r_2_f")])
b11cae9e 1675
1676(define_insn "floatsidf2"
9c08d1fa 1677 [(set (match_operand:DF 0 "s_register_operand" "=f")
1678 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
b11cae9e 1679 ""
40dbec34 1680 "flt%?d\\t%0, %1"
9c08d1fa 1681[(set_attr "type" "r_2_f")])
1682
1683(define_insn "floatsixf2"
1684 [(set (match_operand:XF 0 "s_register_operand" "=f")
1685 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1686 "ENABLE_XF_PATTERNS"
40dbec34 1687 "flt%?e\\t%0, %1"
9c08d1fa 1688[(set_attr "type" "r_2_f")])
1689
1690(define_insn "fix_truncsfsi2"
1691 [(set (match_operand:SI 0 "s_register_operand" "=r")
1692 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
1693 ""
40dbec34 1694 "fix%?z\\t%0, %1"
9c08d1fa 1695[(set_attr "type" "f_2_r")])
1696
1697(define_insn "fix_truncdfsi2"
1698 [(set (match_operand:SI 0 "s_register_operand" "=r")
1699 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
1700 ""
40dbec34 1701 "fix%?z\\t%0, %1"
9c08d1fa 1702[(set_attr "type" "f_2_r")])
1703
1704(define_insn "fix_truncxfsi2"
1705 [(set (match_operand:SI 0 "s_register_operand" "=r")
1706 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1707 "ENABLE_XF_PATTERNS"
40dbec34 1708 "fix%?z\\t%0, %1"
9c08d1fa 1709[(set_attr "type" "f_2_r")])
b11cae9e 1710
f544c6d2 1711;; Truncation insns
b11cae9e 1712
1713(define_insn "truncdfsf2"
9c08d1fa 1714 [(set (match_operand:SF 0 "s_register_operand" "=f")
c8f69309 1715 (float_truncate:SF
9c08d1fa 1716 (match_operand:DF 1 "s_register_operand" "f")))]
b11cae9e 1717 ""
40dbec34 1718 "mvf%?s\\t%0, %1"
3d91c5d6 1719[(set_attr "type" "ffarith")])
9c08d1fa 1720
1721(define_insn "truncxfsf2"
1722 [(set (match_operand:SF 0 "s_register_operand" "=f")
1723 (float_truncate:SF
1724 (match_operand:XF 1 "s_register_operand" "f")))]
1725 "ENABLE_XF_PATTERNS"
40dbec34 1726 "mvf%?s\\t%0, %1"
3d91c5d6 1727[(set_attr "type" "ffarith")])
9c08d1fa 1728
1729(define_insn "truncxfdf2"
1730 [(set (match_operand:DF 0 "s_register_operand" "=f")
1731 (float_truncate:DF
1732 (match_operand:XF 1 "s_register_operand" "f")))]
1733 "ENABLE_XF_PATTERNS"
40dbec34 1734 "mvf%?d\\t%0, %1"
3d91c5d6 1735[(set_attr "type" "ffarith")])
b11cae9e 1736\f
9c08d1fa 1737;; Zero and sign extension instructions.
b11cae9e 1738
9c08d1fa 1739(define_insn "zero_extendsidi2"
1740 [(set (match_operand:DI 0 "s_register_operand" "=r")
1741 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
b11cae9e 1742 ""
9c08d1fa 1743 "*
1744 if (REGNO (operands[1]) != REGNO (operands[0]))
40dbec34 1745 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1746 return \"mov%?\\t%R0, #0\";
9c08d1fa 1747"
094e994f 1748[(set_attr "length" "8")])
9c08d1fa 1749
1750(define_insn "zero_extendqidi2"
1751 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
1752 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1753 ""
e2348bcb 1754 "@
40dbec34 1755 and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
1756 ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
094e994f 1757[(set_attr "length" "8")
9c08d1fa 1758 (set_attr "type" "*,load")])
1759
1760(define_insn "extendsidi2"
1761 [(set (match_operand:DI 0 "s_register_operand" "=r")
1762 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1763 ""
1764 "*
1765 if (REGNO (operands[1]) != REGNO (operands[0]))
40dbec34 1766 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1767 return \"mov%?\\t%R0, %0, asr #31\";
9c08d1fa 1768"
094e994f 1769[(set_attr "length" "8")])
9c08d1fa 1770
1771(define_expand "zero_extendhisi2"
25f7a26e 1772 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
87b22bf7 1773 (const_int 16)))
9c08d1fa 1774 (set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 1775 (lshiftrt:SI (match_dup 2) (const_int 16)))]
9c08d1fa 1776 ""
1777 "
25f7a26e 1778{
1779 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1780 {
1781 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
1782 DONE;
1783 }
1784 if (! s_register_operand (operands[1], HImode))
1785 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1786 operands[1] = gen_lowpart (SImode, operands[1]);
87b22bf7 1787 operands[2] = gen_reg_rtx (SImode);
1788}")
9c08d1fa 1789
87b22bf7 1790(define_expand "zero_extendqisi2"
9c08d1fa 1791 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
c8f69309 1792 (zero_extend:SI
b11cae9e 1793 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1794 ""
87b22bf7 1795 "
1796 if (GET_CODE (operands[1]) != MEM)
1797 {
1798 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
1799 GEN_INT (255)));
1800 DONE;
1801 }
1802")
9c08d1fa 1803
1804(define_insn ""
87b22bf7 1805 [(set (match_operand:SI 0 "s_register_operand" "=r")
1806 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
9c08d1fa 1807 ""
87b22bf7 1808 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1809[(set_attr "type" "load")])
1810
1811(define_split
1812 [(set (match_operand:SI 0 "s_register_operand" "")
1813 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
1814 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1815 "GET_CODE (operands[1]) != MEM"
1816 [(set (match_dup 2) (match_dup 1))
1817 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
1818 "")
9c08d1fa 1819
1820(define_insn ""
1821 [(set (reg:CC_NOOV 24)
87b22bf7 1822 (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1823 (const_int 0)))]
9c08d1fa 1824 ""
87b22bf7 1825 "tst\\t%0, #255"
9c08d1fa 1826[(set_attr "conds" "set")])
b11cae9e 1827
b11cae9e 1828(define_expand "extendhisi2"
c8f69309 1829 [(set (match_dup 2)
25f7a26e 1830 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
b11cae9e 1831 (const_int 16)))
9c08d1fa 1832 (set (match_operand:SI 0 "s_register_operand" "")
c8f69309 1833 (ashiftrt:SI (match_dup 2)
1834 (const_int 16)))]
b11cae9e 1835 ""
1836 "
25f7a26e 1837{
1838 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1839 {
1840 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
1841 DONE;
1842 }
1843 if (! s_register_operand (operands[1], HImode))
1844 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1845 operands[1] = gen_lowpart (SImode, operands[1]);
1846 operands[2] = gen_reg_rtx (SImode);
1847}")
1848
1849(define_expand "extendhisi2_mem"
1850 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
1851 (set (match_dup 3)
1852 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
1853 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
1854 (set (match_operand:SI 0 "" "")
1855 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
1856 ""
1857 "
1858 operands[0] = gen_lowpart (SImode, operands[0]);
1859 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1860 operands[2] = gen_reg_rtx (SImode);
1861 operands[3] = gen_reg_rtx (SImode);
1862 operands[6] = gen_reg_rtx (SImode);
1863
1864 if (BYTES_BIG_ENDIAN)
1865 {
1866 operands[4] = operands[2];
1867 operands[5] = operands[3];
1868 }
1869 else
1870 {
1871 operands[4] = operands[3];
1872 operands[5] = operands[2];
1873 }
1874")
b11cae9e 1875
c8f69309 1876(define_expand "extendqihi2"
1877 [(set (match_dup 2)
9c08d1fa 1878 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
c8f69309 1879 (const_int 24)))
9c08d1fa 1880 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 1881 (ashiftrt:SI (match_dup 2)
1882 (const_int 24)))]
b11cae9e 1883 ""
c8f69309 1884 "
1885{ operands[0] = gen_lowpart (SImode, operands[0]);
1886 operands[1] = gen_lowpart (SImode, operands[1]);
1887 operands[2] = gen_reg_rtx (SImode); }")
b11cae9e 1888
1889(define_expand "extendqisi2"
c8f69309 1890 [(set (match_dup 2)
9c08d1fa 1891 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
b11cae9e 1892 (const_int 24)))
9c08d1fa 1893 (set (match_operand:SI 0 "s_register_operand" "")
c8f69309 1894 (ashiftrt:SI (match_dup 2)
1895 (const_int 24)))]
b11cae9e 1896 ""
1897 "
c8f69309 1898{ operands[1] = gen_lowpart (SImode, operands[1]);
1899 operands[2] = gen_reg_rtx (SImode); }")
b11cae9e 1900
1901(define_insn "extendsfdf2"
9c08d1fa 1902 [(set (match_operand:DF 0 "s_register_operand" "=f")
1903 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
b11cae9e 1904 ""
40dbec34 1905 "mvf%?d\\t%0, %1"
3d91c5d6 1906[(set_attr "type" "ffarith")])
9c08d1fa 1907
1908(define_insn "extendsfxf2"
1909 [(set (match_operand:XF 0 "s_register_operand" "=f")
1910 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
1911 "ENABLE_XF_PATTERNS"
3d91c5d6 1912 "mvf%?e\\t%0, %1"
1913[(set_attr "type" "ffarith")])
9c08d1fa 1914
1915(define_insn "extenddfxf2"
1916 [(set (match_operand:XF 0 "s_register_operand" "=f")
1917 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
1918 "ENABLE_XF_PATTERNS"
40dbec34 1919 "mvf%?e\\t%0, %1"
3d91c5d6 1920[(set_attr "type" "ffarith")])
9c08d1fa 1921
b11cae9e 1922\f
1923;; Move insns (including loads and stores)
1924
1925;; XXX Just some ideas about movti.
9c08d1fa 1926;; I don't think these are a good idea on the arm, there just aren't enough
1927;; registers
b11cae9e 1928;;(define_expand "loadti"
9c08d1fa 1929;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 1930;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
1931;; "" "")
1932
1933;;(define_expand "storeti"
1934;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 1935;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 1936;; "" "")
1937
1938;;(define_expand "movti"
1939;; [(set (match_operand:TI 0 "general_operand" "")
1940;; (match_operand:TI 1 "general_operand" ""))]
1941;; ""
1942;; "
1943;;{
1944;; rtx insn;
1945;;
1946;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1947;; operands[1] = copy_to_reg (operands[1]);
1948;; if (GET_CODE (operands[0]) == MEM)
1949;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
1950;; else if (GET_CODE (operands[1]) == MEM)
1951;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
1952;; else
1953;; FAIL;
1954;;
1955;; emit_insn (insn);
1956;; DONE;
1957;;}")
1958
1959;; Recognise garbage generated above.
1960
1961;;(define_insn ""
1962;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
1963;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
1964;; ""
1965;; "*
1966;; {
1967;; register mem = (which_alternative < 3);
1968;; register char *template;
1969;;
1970;; operands[mem] = XEXP (operands[mem], 0);
1971;; switch (which_alternative)
1972;; {
1973;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
1974;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
1975;; case 2: template = \"ldmia\\t%1, %M0\"; break;
1976;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
1977;; case 4: template = \"stmia\\t%0!, %M1\"; break;
1978;; case 5: template = \"stmia\\t%0, %M1\"; break;
1979;; }
e2348bcb 1980;; output_asm_insn (template, operands);
1981;; return \"\";
b11cae9e 1982;; }")
1983
1984
1985(define_insn "movdi"
9c08d1fa 1986 [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
5565501b 1987 (match_operand:DI 1 "di_operand" "rIK,n,o<>,r,F"))]
b11cae9e 1988 ""
1989 "*
1990 return (output_move_double (operands));
9c08d1fa 1991"
094e994f 1992[(set_attr "length" "8,32,8,8,32")
9c08d1fa 1993 (set_attr "type" "*,*,load,store2,*")])
b11cae9e 1994
9c08d1fa 1995(define_expand "movsi"
1996 [(set (match_operand:SI 0 "general_operand" "")
1997 (match_operand:SI 1 "general_operand" ""))]
b11cae9e 1998 ""
9c08d1fa 1999 "
2000 /* Everything except mem = const or mem = mem can be done easily */
2001 if (GET_CODE (operands[0]) == MEM)
2002 operands[1] = force_reg (SImode, operands[1]);
2003 if (GET_CODE (operands[1]) == CONST_INT
2004 && !(const_ok_for_arm (INTVAL (operands[1]))
2005 || const_ok_for_arm (~INTVAL (operands[1]))))
2006 {
87b22bf7 2007 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2008 NULL_RTX,
2009 (reload_in_progress || reload_completed ? 0
2010 : preserve_subexpressions_p ()));
9c08d1fa 2011 DONE;
2012 }
2013")
2014
2015(define_insn ""
87b22bf7 2016 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r,r")
2017 (match_operand:SI 1 "general_operand" "R,m,K,rI,r,S,?n"))]
9c08d1fa 2018 "(register_operand (operands[0], SImode)
9c08d1fa 2019 && (GET_CODE (operands[1]) != SYMBOL_REF
2020 || CONSTANT_ADDRESS_P (operands[1])))
2021 || register_operand (operands[1], SImode)"
b11cae9e 2022 "*
2023 switch (which_alternative)
2024 {
e2348bcb 2025 case 0:
2026 /* NB Calling get_attr_length may cause the insn to be re-extracted... */
2027 if (get_attr_length (insn) == 8)
9c08d1fa 2028 {
e2348bcb 2029 /* ... so modify the operands here. */
2030 operands[1] = XEXP (operands[1], 0);
899850b0 2031 output_asm_insn (\"sub%?\\t%0, %|pc, #(8 + . - %a1) & ~4095\",
40dbec34 2032 operands);
2033 output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
e2348bcb 2034 operands);
9c08d1fa 2035 }
e2348bcb 2036 else
2037 {
2038 /* ... and here. */
2039 operands[1] = XEXP (operands[1], 0);
899850b0 2040 output_asm_insn (\"ldr%?\\t%0, [%|pc, %1 - . - 8]\", operands);
e2348bcb 2041 }
2042 return \"\";
2043
2044 case 1:
b11cae9e 2045 if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
c8f69309 2046 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
e2348bcb 2047 abort ();
40dbec34 2048 return \"ldr%?\\t%0, %1\";
e2348bcb 2049
b11cae9e 2050 case 3:
40dbec34 2051 return \"mov%?\\t%0, %1\";
e2348bcb 2052 case 2:
5565501b 2053 return \"mvn%?\\t%0, #%B1\";
9c08d1fa 2054 case 4:
40dbec34 2055 return \"str%?\\t%1, %0\";
e2348bcb 2056 case 5:
2057 return output_load_symbol (insn, operands);
87b22bf7 2058 case 6:
2059 return \"#\";
b11cae9e 2060 }
9c08d1fa 2061"
e2348bcb 2062[(set (attr "length")
2063 (cond [(eq_attr "alternative" "0")
2064 (if_then_else
2065 (gt (minus
2066 (pc)
2067 (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
2068 (const_int 4087))
2069 (const_int 8)
2070 (const_int 4))
87b22bf7 2071 (ior (eq_attr "alternative" "5")
2072 (eq_attr "alternative" "6")) (const_int 16)]
e2348bcb 2073 (const_int 4)))
87b22bf7 2074 (set_attr "type" "load,load,*,*,store1,*,*")])
2075
2076(define_split
2077 [(set (match_operand:SI 0 "s_register_operand" "")
2078 (match_operand:SI 1 "const_int_operand" ""))]
2079 "! (const_ok_for_arm (INTVAL (operands[1]))
2080 || const_ok_for_arm (~INTVAL (operands[1])))"
2081 [(clobber (const_int 0))]
2082 "
2083 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2084 NULL_RTX, 0);
2085 DONE;
2086")
9c08d1fa 2087
2088;; If copying one reg to another we can set the condition codes according to
2089;; its value. Such a move is common after a return from subroutine and the
2090;; result is being tested against zero.
2091
2092(define_insn ""
e2348bcb 2093 [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
9c08d1fa 2094 (const_int 0)))
e2348bcb 2095 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
9c08d1fa 2096 ""
e2348bcb 2097 "@
40dbec34 2098 cmp%?\\t%0, #0
2099 sub%?s\\t%0, %1, #0"
9c08d1fa 2100[(set_attr "conds" "set")])
b11cae9e 2101
b11cae9e 2102;; Subroutine to store a half word from a register into memory.
2103;; Operand 0 is the source register (HImode)
c8f69309 2104;; Operand 1 is the destination address in a register (SImode)
b11cae9e 2105
9c08d1fa 2106;; In both this routine and the next, we must be careful not to spill
2107;; a memory address of reg+large_const into a seperate PLUS insn, since this
2108;; can generate unrecognizable rtl.
2109
b11cae9e 2110(define_expand "storehi"
c8f69309 2111 [;; store the low byte
d75350ce 2112 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
b11cae9e 2113 ;; extract the high byte
c8f69309 2114 (set (match_dup 2)
2115 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 2116 ;; store the high byte
9c08d1fa 2117 (set (mem:QI (match_dup 4))
c8f69309 2118 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
b11cae9e 2119 ""
2120 "
9c08d1fa 2121{
2122 enum rtx_code code = GET_CODE (operands[1]);
2123
2124 if ((code == PLUS || code == MINUS)
2125 && (GET_CODE (XEXP (operands[1], 1)) == REG
2126 || GET_CODE (XEXP (operands[1], 0)) != REG))
2127 operands[1] = force_reg (SImode, operands[1]);
2128 operands[4] = plus_constant (operands[1], 1);
2129 operands[3] = gen_lowpart (QImode, operands[0]);
f544c6d2 2130 operands[0] = gen_lowpart (SImode, operands[0]);
9c08d1fa 2131 operands[2] = gen_reg_rtx (SImode);
2132}
2133")
b11cae9e 2134
c7597b5d 2135(define_expand "storehi_bigend"
2136 [(set (mem:QI (match_dup 4)) (match_dup 3))
2137 (set (match_dup 2)
2138 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2139 (set (mem:QI (match_operand 1 "" ""))
2140 (subreg:QI (match_dup 2) 0))]
b11cae9e 2141 ""
2142 "
9c08d1fa 2143{
9c08d1fa 2144 enum rtx_code code = GET_CODE (operands[1]);
9c08d1fa 2145 if ((code == PLUS || code == MINUS)
2146 && (GET_CODE (XEXP (operands[1], 1)) == REG
2147 || GET_CODE (XEXP (operands[1], 0)) != REG))
c7597b5d 2148 operands[1] = force_reg (SImode, operands[1]);
9c08d1fa 2149
c7597b5d 2150 operands[4] = plus_constant (operands[1], 1);
2151 operands[3] = gen_lowpart (QImode, operands[0]);
2152 operands[0] = gen_lowpart (SImode, operands[0]);
2153 operands[2] = gen_reg_rtx (SImode);
2154}
2155")
2156
2157;; Subroutine to store a half word integer constant into memory.
2158(define_expand "storeinthi"
2159 [(set (mem:QI (match_operand:SI 0 "" ""))
2160 (subreg:QI (match_operand 1 "" "") 0))
2161 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2162 ""
2163 "
2164{
2165 HOST_WIDE_INT value = INTVAL (operands[1]);
2166 enum rtx_code code = GET_CODE (operands[0]);
2167
2168 if ((code == PLUS || code == MINUS)
2169 && (GET_CODE (XEXP (operands[0], 1)) == REG
2170 || GET_CODE (XEXP (operands[0], 0)) != REG))
2171 operands[0] = force_reg (SImode, operands[0]);
2172
2173 operands[1] = gen_reg_rtx (SImode);
2174 if (BYTES_BIG_ENDIAN)
2175 {
2176 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2177 if ((value & 255) == ((value >> 8) & 255))
2178 operands[2] = operands[1];
2179 else
2180 {
2181 operands[2] = gen_reg_rtx (SImode);
2182 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2183 }
2184 }
2185 else
2186 {
2187 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2188 if ((value & 255) == ((value >> 8) & 255))
2189 operands[2] = operands[1];
2190 else
2191 {
2192 operands[2] = gen_reg_rtx (SImode);
2193 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2194 }
2195 }
2196
2197 operands[3] = plus_constant (operands[0], 1);
9c08d1fa 2198}
b11cae9e 2199")
2200
2201(define_expand "movhi"
2202 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 2203 (match_operand:HI 1 "general_operand" ""))]
b11cae9e 2204 ""
2205 "
2206{
2207 rtx insn;
2208
c7597b5d 2209 if (! (reload_in_progress || reload_completed))
b11cae9e 2210 {
2211 if (GET_CODE (operands[0]) == MEM)
2212 {
b11cae9e 2213 if (GET_CODE (operands[1]) == CONST_INT)
c7597b5d 2214 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
b11cae9e 2215 else
2216 {
c8f69309 2217 if (GET_CODE (operands[1]) == MEM)
9c08d1fa 2218 operands[1] = force_reg (HImode, operands[1]);
c7597b5d 2219 if (BYTES_BIG_ENDIAN)
2220 emit_insn (gen_storehi_bigend (operands[1],
2221 XEXP (operands[0], 0)));
2222 else
2223 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
b11cae9e 2224 }
c7597b5d 2225 DONE;
b11cae9e 2226 }
c7597b5d 2227 /* Sign extend a constant, and keep it in an SImode reg. */
2228 else if (GET_CODE (operands[1]) == CONST_INT)
b11cae9e 2229 {
c7597b5d 2230 rtx reg = gen_reg_rtx (SImode);
2231 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
9c08d1fa 2232
c7597b5d 2233 /* If the constant is already valid, leave it alone. */
2234 if (! const_ok_for_arm (val))
9c08d1fa 2235 {
c7597b5d 2236 /* If setting all the top bits will make the constant
2237 loadable in a single instruction, then set them.
2238 Otherwise, sign extend the number. */
2239
2240 if (const_ok_for_arm (~ (val | ~0xffff)))
2241 val |= ~0xffff;
2242 else if (val & 0x8000)
2243 val |= ~0xffff;
9c08d1fa 2244 }
c7597b5d 2245
2246 emit_insn (gen_movsi (reg, GEN_INT (val)));
2247 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2248 }
25f7a26e 2249 else if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2250 {
2251 rtx reg = gen_reg_rtx (SImode);
2252 emit_insn (gen_movhi_bytes (reg, operands[1]));
2253 operands[1] = gen_lowpart (HImode, reg);
2254 }
c7597b5d 2255 else if (BYTES_BIG_ENDIAN && GET_CODE (operands[1]) == MEM)
2256 {
2257 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2258 DONE;
b11cae9e 2259 }
b11cae9e 2260 }
c7597b5d 2261}
2262")
b11cae9e 2263
25f7a26e 2264(define_expand "movhi_bytes"
2265 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2266 (set (match_dup 3)
2267 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2268 (set (match_operand:SI 0 "" "")
2269 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
2270 ""
2271 "
2272 operands[0] = gen_lowpart (SImode, operands[0]);
2273 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2274 operands[2] = gen_reg_rtx (SImode);
2275 operands[3] = gen_reg_rtx (SImode);
2276
2277 if (BYTES_BIG_ENDIAN)
2278 {
2279 operands[4] = operands[2];
2280 operands[5] = operands[3];
2281 }
2282 else
2283 {
2284 operands[4] = operands[3];
2285 operands[5] = operands[2];
2286 }
2287")
2288
c7597b5d 2289(define_expand "movhi_bigend"
2290 [(set (match_dup 2)
2291 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2292 (const_int 16)))
2293 (set (match_dup 3)
2294 (ashiftrt:SI (match_dup 2) (const_int 16)))
2295 (set (match_operand:HI 0 "s_register_operand" "")
2296 (subreg:HI (match_dup 3) 0))]
2297 ""
2298 "
2299 operands[2] = gen_reg_rtx (SImode);
2300 operands[3] = gen_reg_rtx (SImode);
2301")
b11cae9e 2302
2303;; Pattern to recognise insn generated default case above
2304
2305(define_insn ""
c7597b5d 2306 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2307 (match_operand:HI 1 "general_operand" "rI,K,m"))]
25f7a26e 2308 "! BYTES_BIG_ENDIAN
2309 && ! TARGET_SHORT_BY_BYTES
c7597b5d 2310 && (GET_CODE (operands[1]) != CONST_INT
2311 || const_ok_for_arm (INTVAL (operands[1]))
2312 || const_ok_for_arm (~INTVAL (operands[1])))"
5565501b 2313 "@
2314 mov%?\\t%0, %1\\t%@ movhi
2315 mvn%?\\t%0, #%B1\\t%@ movhi
c7597b5d 2316 ldr%?\\t%0, %1\\t%@ movhi"
2317[(set_attr "type" "*,*,load")])
2318
2319(define_insn ""
2320 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2321 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2322 "BYTES_BIG_ENDIAN
25f7a26e 2323 && ! TARGET_SHORT_BY_BYTES
c7597b5d 2324 && (GET_CODE (operands[1]) != CONST_INT
2325 || const_ok_for_arm (INTVAL (operands[1]))
2326 || const_ok_for_arm (~INTVAL (operands[1])))"
2327 "@
2328 mov%?\\t%0, %1\\t%@ movhi
2329 mvn%?\\t%0, #%B1\\t%@ movhi
2330 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2331[(set_attr "type" "*,*,load")
2332 (set_attr "length" "4,4,8")])
2333
2334(define_insn ""
2335 [(set (match_operand:SI 0 "s_register_operand" "=r")
2336 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2337 (const_int 16)))]
25f7a26e 2338 "BYTES_BIG_ENDIAN
2339 && ! TARGET_SHORT_BY_BYTES"
c7597b5d 2340 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2341[(set_attr "type" "load")])
9c08d1fa 2342
25f7a26e 2343(define_insn ""
2344 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
2345 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
2346 "TARGET_SHORT_BY_BYTES"
2347 "@
2348 mov%?\\t%0, %1\\t%@ movhi
2349 mvn%?\\t%0, #%B1\\t%@ movhi")
2350
2351
d3373b54 2352(define_expand "reload_outhi"
2353 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2354 (match_operand:HI 1 "s_register_operand" "r")
2355 (match_operand:SI 2 "s_register_operand" "=&r")])]
2356 ""
2357 "
2358 arm_reload_out_hi (operands);
2359 DONE;
2360")
2361
25f7a26e 2362(define_expand "reload_inhi"
2363 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
2364 (match_operand:HI 1 "reload_memory_operand" "o")
2365 (match_operand:SI 2 "s_register_operand" "=&r")])]
2366 "TARGET_SHORT_BY_BYTES"
2367 "
2368 arm_reload_in_hi (operands);
2369 DONE;
2370")
2371
9c08d1fa 2372(define_expand "movqi"
2373 [(set (match_operand:QI 0 "general_operand" "")
2374 (match_operand:QI 1 "general_operand" ""))]
2375 ""
2376 "
2377 /* Everything except mem = const or mem = mem can be done easily */
2378
2379 if (!(reload_in_progress || reload_completed))
2380 {
9c08d1fa 2381 if (GET_CODE (operands[1]) == CONST_INT)
2382 {
c7597b5d 2383 rtx reg = gen_reg_rtx (SImode);
2384
2385 emit_insn (gen_movsi (reg, operands[1]));
9c08d1fa 2386 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2387 }
87b22bf7 2388 if (GET_CODE (operands[0]) == MEM)
2389 operands[1] = force_reg (QImode, operands[1]);
b11cae9e 2390 }
2391")
2392
9c08d1fa 2393
2394(define_insn ""
b11cae9e 2395 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
5565501b 2396 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
9c08d1fa 2397 "register_operand (operands[0], QImode)
2398 || register_operand (operands[1], QImode)"
5565501b 2399 "@
2400 mov%?\\t%0, %1
2401 mvn%?\\t%0, #%B1
2402 ldr%?b\\t%0, %1
2403 str%?b\\t%1, %0"
9c08d1fa 2404[(set_attr "type" "*,*,load,store1")])
b11cae9e 2405
87b22bf7 2406(define_expand "movsf"
2407 [(set (match_operand:SF 0 "general_operand" "")
2408 (match_operand:SF 1 "general_operand" ""))]
2409 ""
2410 "
2411 if (GET_CODE (operands[1]) == CONST_DOUBLE
2412 && ((GET_CODE (operands[0]) == REG
2413 && REGNO (operands[0]) < 16)
2414 || ! (const_double_rtx_ok_for_fpu (operands[1])
2415 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2416 {
2417 extern int optimize;
2418 rtx mem = force_const_mem (SFmode, operands[1]);
3ab84030 2419 rtx addr;
2420
2421 if (reload_in_progress || reload_completed)
2422 addr = gen_rtx (REG, SImode, REGNO (operands[0]));
2423 else
2424 addr = gen_reg_rtx (SImode);
87b22bf7 2425 if (optimize == 0)
2426 {
2427 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2428 emit_insn (gen_movsi (addr, ptr));
2429 }
2430 else
2431 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2432 operands[1] = gen_rtx (MEM, SFmode, addr);
2433 }
2434 if (GET_CODE (operands[0]) == MEM)
2435 operands[1] = force_reg (SFmode, operands[1]);
2436")
2437
2438(define_insn ""
9c08d1fa 2439 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2440 (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
87b22bf7 2441 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode)"
5565501b 2442 "@
2443 mvf%?s\\t%0, %1
2444 mnf%?s\\t%0, #%N1
2445 ldf%?s\\t%0, %1
2446 stf%?s\\t%1, %0
899850b0 2447 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2448 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
5565501b 2449 mov%?\\t%0, %1
2450 ldr%?\\t%0, %1\\t%@ float
2451 str%?\\t%1, %0\\t%@ float"
094e994f 2452[(set_attr "length" "4,4,4,4,8,8,4,4,4")
3d91c5d6 2453 (set_attr "type"
2454 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
9c08d1fa 2455
2456(define_expand "movdf"
87b22bf7 2457 [(set (match_operand:DF 0 "general_operand" "")
2458 (match_operand:DF 1 "general_operand" ""))]
9c08d1fa 2459 ""
2460 "
87b22bf7 2461 if (GET_CODE (operands[1]) == CONST_DOUBLE
2462 && ((GET_CODE (operands[0]) == REG
2463 && REGNO (operands[0]) < 16)
2464 || ! (const_double_rtx_ok_for_fpu (operands[1])
2465 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2466 {
2467 extern int optimize;
2468 rtx mem = force_const_mem (DFmode, operands[1]);
3ab84030 2469 rtx addr;
2470
2471 if (reload_in_progress || reload_completed)
2472 addr = gen_rtx (REG, SImode, REGNO (operands[0]));
2473 else
2474 addr = gen_reg_rtx (SImode);
87b22bf7 2475 if (optimize == 0)
2476 {
2477 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2478 emit_insn (gen_movsi (addr, ptr));
2479 }
2480 else
2481 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2482 operands[1] = gen_rtx (MEM, DFmode, addr);
2483 }
9c08d1fa 2484 if (GET_CODE (operands[0]) == MEM)
2485 operands[1] = force_reg (DFmode, operands[1]);
b11cae9e 2486")
2487
9c08d1fa 2488;; Reloading a df mode value stored in integer regs to memory can require a
2489;; scratch reg.
2490(define_expand "reload_outdf"
87b22bf7 2491 [(match_operand:DF 0 "reload_memory_operand" "=o")
2492 (match_operand:DF 1 "s_register_operand" "r")
2493 (match_operand:SI 2 "s_register_operand" "=&r")]
b11cae9e 2494 ""
87b22bf7 2495 "
443a31dc 2496 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2497 operands[2] = XEXP (operands[0], 0);
2498 else
2499 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2500 XEXP (XEXP (operands[0], 0), 1)));
87b22bf7 2501 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2502 operands[1]));
2503 DONE;
2504")
9c08d1fa 2505
2506(define_insn ""
87b22bf7 2507 [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
9c08d1fa 2508 (match_operand:DF 1 "general_operand"
87b22bf7 2509 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
9c08d1fa 2510 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2511 "*
2512{
9c08d1fa 2513 rtx ops[3];
2514
2515 switch (which_alternative)
2516 {
2517 case 0:
40dbec34 2518 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
e2348bcb 2519
9c08d1fa 2520 case 1:
40dbec34 2521 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
e2348bcb 2522
9c08d1fa 2523 case 2:
2524 ops[0] = operands[0];
2525 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2526 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2527 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
40dbec34 2528 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
9c08d1fa 2529 else
40dbec34 2530 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2531 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
9c08d1fa 2532
e2348bcb 2533 case 3:
9c08d1fa 2534 case 4:
40dbec34 2535 return \"mvf%?d\\t%0, %1\";
e2348bcb 2536
87b22bf7 2537 case 5: return \"mnf%?d\\t%0, #%N1\";
2538 case 6: return \"ldf%?d\\t%0, %1\";
2539 case 7: return \"stf%?d\\t%1, %0\";
2540 case 8: return output_mov_double_fpu_from_arm (operands);
2541 case 9: return output_mov_double_arm_from_fpu (operands);
2542 case 10: return output_move_double (operands);
9c08d1fa 2543 }
2544}
2545"
87b22bf7 2546[(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
9c08d1fa 2547 (set_attr "type"
3d91c5d6 2548"load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
9c08d1fa 2549
87b22bf7 2550(define_expand "movxf"
2551 [(set (match_operand:XF 0 "general_operand" "")
2552 (match_operand:XF 1 "general_operand" ""))]
2553 "ENABLE_XF_PATTERNS"
2554 "")
2555
2556;; Even when the XFmode patterns aren't enabled, we enable this after
2557;; reloading so that we can push floating point registers in the prologue.
2558
2559(define_insn ""
9c08d1fa 2560 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2561 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
87b22bf7 2562 "ENABLE_XF_PATTERNS || reload_completed"
b11cae9e 2563 "*
2564 switch (which_alternative)
2565 {
40dbec34 2566 case 0: return \"mvf%?e\\t%0, %1\";
5565501b 2567 case 1: return \"mnf%?e\\t%0, #%N1\";
40dbec34 2568 case 2: return \"ldf%?e\\t%0, %1\";
2569 case 3: return \"stf%?e\\t%1, %0\";
9c08d1fa 2570 case 4: return output_mov_long_double_fpu_from_arm (operands);
2571 case 5: return output_mov_long_double_arm_from_fpu (operands);
2572 case 6: return output_mov_long_double_arm_from_arm (operands);
b11cae9e 2573 }
9c08d1fa 2574"
094e994f 2575[(set_attr "length" "4,4,4,4,8,8,12")
3d91c5d6 2576 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
b11cae9e 2577\f
b11cae9e 2578
9c08d1fa 2579;; load- and store-multiple insns
2580;; The arm can load/store any set of registers, provided that they are in
2581;; ascending order; but that is beyond GCC so stick with what it knows.
b11cae9e 2582
9c08d1fa 2583(define_expand "load_multiple"
2584 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2585 (match_operand:SI 1 "" ""))
2586 (use (match_operand:SI 2 "" ""))])]
b11cae9e 2587 ""
9c08d1fa 2588 "
2589 /* Support only fixed point registers */
2590 if (GET_CODE (operands[2]) != CONST_INT
2591 || INTVAL (operands[2]) > 14
2592 || INTVAL (operands[2]) < 2
2593 || GET_CODE (operands[1]) != MEM
2594 || GET_CODE (operands[0]) != REG
2595 || REGNO (operands[0]) > 14
2596 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2597 FAIL;
2598
2599 operands[3]
2600 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2601 force_reg (SImode, XEXP (operands[1], 0)),
2602 TRUE, FALSE);
b11cae9e 2603")
2604
9c08d1fa 2605;; Load multiple with write-back
2606
b11cae9e 2607(define_insn ""
9c08d1fa 2608 [(match_parallel 0 "load_multiple_operation"
2609 [(set (match_operand:SI 1 "s_register_operand" "+r")
2610 (plus:SI (match_dup 1)
2611 (match_operand:SI 2 "immediate_operand" "n")))
2612 (set (match_operand:SI 3 "s_register_operand" "=r")
2613 (mem:SI (match_dup 1)))])]
2614 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
b11cae9e 2615 "*
9c08d1fa 2616{
2617 rtx ops[3];
2618 int count = XVECLEN (operands[0], 0);
b11cae9e 2619
9c08d1fa 2620 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2621 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2622 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
b11cae9e 2623
40dbec34 2624 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
e2348bcb 2625 return \"\";
9c08d1fa 2626}
2627"
2628[(set_attr "type" "load")])
b11cae9e 2629
9c08d1fa 2630;; Ordinary load multiple
b11cae9e 2631
9c08d1fa 2632(define_insn ""
2633 [(match_parallel 0 "load_multiple_operation"
2634 [(set (match_operand:SI 1 "s_register_operand" "=r")
2635 (match_operand:SI 2 "indirect_operand" "Q"))])]
b11cae9e 2636 ""
2637 "*
9c08d1fa 2638{
2639 rtx ops[3];
2640 int count = XVECLEN (operands[0], 0);
2641
2642 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2643 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2644 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2645
40dbec34 2646 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
e2348bcb 2647 return \"\";
9c08d1fa 2648}
2649"
2650[(set_attr "type" "load")])
2651
2652(define_expand "store_multiple"
2653 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2654 (match_operand:SI 1 "" ""))
2655 (use (match_operand:SI 2 "" ""))])]
b11cae9e 2656 ""
9c08d1fa 2657 "
2658 /* Support only fixed point registers */
2659 if (GET_CODE (operands[2]) != CONST_INT
2660 || INTVAL (operands[2]) > 14
2661 || INTVAL (operands[2]) < 2
2662 || GET_CODE (operands[1]) != REG
2663 || GET_CODE (operands[0]) != MEM
2664 || REGNO (operands[1]) > 14
2665 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2666 FAIL;
2667
2668 operands[3]
2669 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2670 force_reg (SImode, XEXP (operands[0], 0)),
2671 TRUE, FALSE);
b11cae9e 2672")
2673
9c08d1fa 2674;; Store multiple with write-back
2675
2676(define_insn ""
2677 [(match_parallel 0 "store_multiple_operation"
2678 [(set (match_operand:SI 1 "s_register_operand" "+r")
2679 (plus:SI (match_dup 1)
2680 (match_operand:SI 2 "immediate_operand" "n")))
2681 (set (mem:SI (match_dup 1))
2682 (match_operand:SI 3 "s_register_operand" "r"))])]
2683 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
b11cae9e 2684 "*
9c08d1fa 2685{
2686 rtx ops[3];
2687 int count = XVECLEN (operands[0], 0);
b11cae9e 2688
9c08d1fa 2689 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2690 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2691 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2692
40dbec34 2693 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
e2348bcb 2694 return \"\";
9c08d1fa 2695}
2696"
2697[(set (attr "type")
2698 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2699 (const_string "store2")
2700 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2701 (const_string "store3")]
2702 (const_string "store4")))])
2703
2704;; Ordinary store multiple
2705
2706(define_insn ""
2707 [(match_parallel 0 "store_multiple_operation"
2708 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2709 (match_operand:SI 1 "s_register_operand" "r"))])]
b11cae9e 2710 ""
2711 "*
9c08d1fa 2712{
2713 rtx ops[3];
2714 int count = XVECLEN (operands[0], 0);
2715
2716 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2717 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2718 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2719
40dbec34 2720 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
e2348bcb 2721 return \"\";
9c08d1fa 2722}
2723"
2724[(set (attr "type")
2725 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2726 (const_string "store2")
2727 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2728 (const_string "store3")]
2729 (const_string "store4")))])
2730
2731;; Move a block of memory if it is word aligned and MORE than 2 words long.
2732;; We could let this apply for blocks of less than this, but it clobbers so
2733;; many registers that there is then probably a better way.
2734
34191dd1 2735(define_expand "movstrqi"
2736 [(match_operand:BLK 0 "general_operand" "")
2737 (match_operand:BLK 1 "general_operand" "")
2738 (match_operand:SI 2 "const_int_operand" "")
2739 (match_operand:SI 3 "const_int_operand" "")]
9c08d1fa 2740 ""
2741 "
34191dd1 2742 if (arm_gen_movstrqi (operands))
2743 DONE;
2744 FAIL;
b11cae9e 2745")
9c08d1fa 2746\f
b11cae9e 2747
9c08d1fa 2748;; Comparison and test insns
2749
2750(define_expand "cmpsi"
2751 [(set (reg:CC 24)
2752 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2753 (match_operand:SI 1 "arm_add_operand" "")))]
b11cae9e 2754 ""
9c08d1fa 2755 "
2756{
2757 arm_compare_op0 = operands[0];
2758 arm_compare_op1 = operands[1];
2759 arm_compare_fp = 0;
2760 DONE;
2761}
b11cae9e 2762")
2763
9c08d1fa 2764(define_expand "cmpsf"
2765 [(set (reg:CC 24)
2766 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2767 (match_operand:SF 1 "fpu_rhs_operand" "")))]
b11cae9e 2768 ""
9c08d1fa 2769 "
2770{
2771 arm_compare_op0 = operands[0];
2772 arm_compare_op1 = operands[1];
2773 arm_compare_fp = 1;
2774 DONE;
2775}
b11cae9e 2776")
2777
9c08d1fa 2778(define_expand "cmpdf"
2779 [(set (reg:CC 24)
2780 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2781 (match_operand:DF 1 "fpu_rhs_operand" "")))]
b11cae9e 2782 ""
9c08d1fa 2783 "
2784{
2785 arm_compare_op0 = operands[0];
2786 arm_compare_op1 = operands[1];
2787 arm_compare_fp = 1;
2788 DONE;
2789}
b11cae9e 2790")
2791
9c08d1fa 2792(define_expand "cmpxf"
2793 [(set (reg:CC 24)
2794 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2795 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2796 "ENABLE_XF_PATTERNS"
2797 "
2798{
2799 arm_compare_op0 = operands[0];
2800 arm_compare_op1 = operands[1];
2801 arm_compare_fp = 1;
2802 DONE;
2803}
b11cae9e 2804")
2805
9c08d1fa 2806(define_insn ""
2807 [(set (match_operand 0 "cc_register" "")
5565501b 2808 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2809 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
b11cae9e 2810 ""
5565501b 2811 "@
2812 cmp%?\\t%1, %2
2813 cmn%?\\t%1, #%n2"
9c08d1fa 2814[(set_attr "conds" "set")])
b11cae9e 2815
2816(define_insn ""
9c08d1fa 2817 [(set (match_operand 0 "cc_register" "")
2818 (compare (match_operand:SI 1 "s_register_operand" "r")
2819 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
b11cae9e 2820 ""
40dbec34 2821 "cmn%?\\t%1, %2"
9c08d1fa 2822[(set_attr "conds" "set")])
b11cae9e 2823
2824(define_insn ""
9c08d1fa 2825 [(set (match_operand 0 "cc_register" "")
2826 (compare (match_operand:SI 1 "s_register_operand" "r")
2827 (match_operator:SI 2 "shift_operator"
2828 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 2829 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
b11cae9e 2830 ""
87b22bf7 2831 "cmp%?\\t%1, %3%S2"
9c08d1fa 2832[(set_attr "conds" "set")])
b11cae9e 2833
2834(define_insn ""
9c08d1fa 2835 [(set (match_operand 0 "cc_register" "")
2836 (compare (match_operand:SI 1 "s_register_operand" "r")
2837 (neg:SI (match_operator:SI 2 "shift_operator"
2838 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 2839 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
b11cae9e 2840 ""
87b22bf7 2841 "cmn%?\\t%1, %3%S2"
9c08d1fa 2842[(set_attr "conds" "set")])
b11cae9e 2843
2844(define_insn ""
9c08d1fa 2845 [(set (reg:CCFP 24)
2846 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2847 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
b11cae9e 2848 ""
5565501b 2849 "@
2850 cmf%?\\t%0, %1
2851 cnf%?\\t%0, #%N1"
9c08d1fa 2852[(set_attr "conds" "set")
2853 (set_attr "type" "f_2_r")])
b11cae9e 2854
2855(define_insn ""
9c08d1fa 2856 [(set (reg:CCFP 24)
2857 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2858 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
b11cae9e 2859 ""
5565501b 2860 "@
2861 cmf%?\\t%0, %1
2862 cnf%?\\t%0, #%N1"
9c08d1fa 2863[(set_attr "conds" "set")
2864 (set_attr "type" "f_2_r")])
b11cae9e 2865
2866(define_insn ""
9c08d1fa 2867 [(set (reg:CCFP 24)
2868 (compare:CCFP (float_extend:DF
2869 (match_operand:SF 0 "s_register_operand" "f,f"))
2870 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
b11cae9e 2871 ""
5565501b 2872 "@
2873 cmf%?\\t%0, %1
2874 cnf%?\\t%0, #%N1"
9c08d1fa 2875[(set_attr "conds" "set")
2876 (set_attr "type" "f_2_r")])
b11cae9e 2877
2878(define_insn ""
9c08d1fa 2879 [(set (reg:CCFP 24)
2880 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2881 (float_extend:DF
2882 (match_operand:SF 1 "s_register_operand" "f"))))]
b11cae9e 2883 ""
40dbec34 2884 "cmf%?\\t%0, %1"
9c08d1fa 2885[(set_attr "conds" "set")
2886 (set_attr "type" "f_2_r")])
b11cae9e 2887
2888(define_insn ""
9c08d1fa 2889 [(set (reg:CCFP 24)
2890 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2891 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2892 "ENABLE_XF_PATTERNS"
5565501b 2893 "@
2894 cmf%?\\t%0, %1
2895 cnf%?\\t%0, #%N1"
9c08d1fa 2896[(set_attr "conds" "set")
2897 (set_attr "type" "f_2_r")])
b11cae9e 2898
2899(define_insn ""
9c08d1fa 2900 [(set (reg:CCFPE 24)
2901 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2902 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
b11cae9e 2903 ""
5565501b 2904 "@
4d61e570 2905 cmf%?e\\t%0, %1
2906 cnf%?e\\t%0, #%N1"
9c08d1fa 2907[(set_attr "conds" "set")
2908 (set_attr "type" "f_2_r")])
b11cae9e 2909
9c08d1fa 2910(define_insn ""
2911 [(set (reg:CCFPE 24)
2912 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2913 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
b11cae9e 2914 ""
5565501b 2915 "@
2916 cmf%?e\\t%0, %1
2917 cnf%?e\\t%0, #%N1"
9c08d1fa 2918[(set_attr "conds" "set")
2919 (set_attr "type" "f_2_r")])
2920
2921(define_insn ""
2922 [(set (reg:CCFPE 24)
2923 (compare:CCFPE (float_extend:DF
2924 (match_operand:SF 0 "s_register_operand" "f,f"))
2925 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
b11cae9e 2926 ""
5565501b 2927 "@
2928 cmf%?e\\t%0, %1
2929 cnf%?e\\t%0, #%N1"
9c08d1fa 2930[(set_attr "conds" "set")
2931 (set_attr "type" "f_2_r")])
b11cae9e 2932
2933(define_insn ""
9c08d1fa 2934 [(set (reg:CCFPE 24)
2935 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2936 (float_extend:DF
2937 (match_operand:SF 1 "s_register_operand" "f"))))]
2938 ""
40dbec34 2939 "cmf%?e\\t%0, %1"
9c08d1fa 2940[(set_attr "conds" "set")
2941 (set_attr "type" "f_2_r")])
b11cae9e 2942
2943(define_insn ""
9c08d1fa 2944 [(set (reg:CCFPE 24)
2945 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2946 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2947 "ENABLE_XF_PATTERNS"
5565501b 2948 "@
2949 cmf%?e\\t%0, %1
2950 cnf%?e\\t%0, #%N1"
9c08d1fa 2951[(set_attr "conds" "set")
2952 (set_attr "type" "f_2_r")])
5c951228 2953
9c08d1fa 2954; This insn allows redundant compares to be removed by cse, nothing should
2955; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2956; is deleted later on. The match_dup will match the mode here, so that
2957; mode changes of the condition codes aren't lost by this even though we don't
2958; specify what they are.
2959
2960(define_insn ""
2961 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2962 ""
40dbec34 2963 "\\t%@ deleted compare"
9c08d1fa 2964[(set_attr "conds" "set")
2965 (set_attr "length" "0")])
2966
2967\f
2968;; Conditional branch insns
2969
2970(define_expand "beq"
2971 [(set (pc)
2972 (if_then_else (eq (match_dup 1) (const_int 0))
2973 (label_ref (match_operand 0 "" ""))
2974 (pc)))]
5c951228 2975 ""
2976 "
2977{
9c08d1fa 2978 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2979 arm_compare_fp);
2980}
2981")
5c951228 2982
9c08d1fa 2983(define_expand "bne"
2984 [(set (pc)
2985 (if_then_else (ne (match_dup 1) (const_int 0))
2986 (label_ref (match_operand 0 "" ""))
2987 (pc)))]
2988 ""
2989 "
2990{
2991 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
2992 arm_compare_fp);
2993}
2994")
5c951228 2995
9c08d1fa 2996(define_expand "bgt"
2997 [(set (pc)
2998 (if_then_else (gt (match_dup 1) (const_int 0))
2999 (label_ref (match_operand 0 "" ""))
3000 (pc)))]
3001 ""
3002 "
3003{
3004 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3005 arm_compare_fp);
3006}
3007")
5c951228 3008
9c08d1fa 3009(define_expand "ble"
3010 [(set (pc)
3011 (if_then_else (le (match_dup 1) (const_int 0))
3012 (label_ref (match_operand 0 "" ""))
3013 (pc)))]
3014 ""
3015 "
3016{
3017 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3018 arm_compare_fp);
3019}
3020")
5c951228 3021
9c08d1fa 3022(define_expand "bge"
3023 [(set (pc)
3024 (if_then_else (ge (match_dup 1) (const_int 0))
3025 (label_ref (match_operand 0 "" ""))
3026 (pc)))]
3027 ""
3028 "
3029{
3030 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3031 arm_compare_fp);
3032}
3033")
5c951228 3034
9c08d1fa 3035(define_expand "blt"
3036 [(set (pc)
3037 (if_then_else (lt (match_dup 1) (const_int 0))
3038 (label_ref (match_operand 0 "" ""))
3039 (pc)))]
3040 ""
3041 "
3042{
3043 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3044 arm_compare_fp);
3045}
3046")
5c951228 3047
9c08d1fa 3048(define_expand "bgtu"
3049 [(set (pc)
3050 (if_then_else (gtu (match_dup 1) (const_int 0))
3051 (label_ref (match_operand 0 "" ""))
3052 (pc)))]
5c951228 3053 ""
9c08d1fa 3054 "
3055{
3056 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3057 arm_compare_fp);
3058}
3059")
5c951228 3060
9c08d1fa 3061(define_expand "bleu"
b11cae9e 3062 [(set (pc)
9c08d1fa 3063 (if_then_else (leu (match_dup 1) (const_int 0))
3064 (label_ref (match_operand 0 "" ""))
3065 (pc)))]
b11cae9e 3066 ""
9c08d1fa 3067 "
3068{
3069 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3070 arm_compare_fp);
3071}
b11cae9e 3072")
3073
9c08d1fa 3074(define_expand "bgeu"
b11cae9e 3075 [(set (pc)
9c08d1fa 3076 (if_then_else (geu (match_dup 1) (const_int 0))
3077 (label_ref (match_operand 0 "" ""))
3078 (pc)))]
b11cae9e 3079 ""
9c08d1fa 3080 "
3081{
3082 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3083 arm_compare_fp);
3084}
b11cae9e 3085")
b11cae9e 3086
9c08d1fa 3087(define_expand "bltu"
3088 [(set (pc)
3089 (if_then_else (ltu (match_dup 1) (const_int 0))
3090 (label_ref (match_operand 0 "" ""))
3091 (pc)))]
b11cae9e 3092 ""
9c08d1fa 3093 "
3094{
3095 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3096 arm_compare_fp);
3097}
b11cae9e 3098")
b11cae9e 3099
9c08d1fa 3100;; patterns to match conditional branch insns
3101
3102(define_insn ""
3103 [(set (pc)
3104 (if_then_else (match_operator 1 "comparison_operator"
3105 [(reg 24) (const_int 0)])
3106 (label_ref (match_operand 0 "" ""))
3107 (pc)))]
d75350ce 3108 ""
3109 "*
9c08d1fa 3110{
3111 extern int arm_ccfsm_state;
d75350ce 3112
9c08d1fa 3113 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3114 {
3115 arm_ccfsm_state += 2;
3116 return \"\";
3117 }
e2348bcb 3118 return \"b%d1\\t%l0\";
9c08d1fa 3119}"
3120[(set_attr "conds" "use")])
d75350ce 3121
3122(define_insn ""
9c08d1fa 3123 [(set (pc)
3124 (if_then_else (match_operator 1 "comparison_operator"
3125 [(reg 24) (const_int 0)])
3126 (pc)
3127 (label_ref (match_operand 0 "" ""))))]
87b22bf7 3128 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
d75350ce 3129 "*
3130{
9c08d1fa 3131 extern int arm_ccfsm_state;
3132
3133 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3134 {
3135 arm_ccfsm_state += 2;
3136 return \"\";
3137 }
e2348bcb 3138 return \"b%D1\\t%l0\";
9c08d1fa 3139}"
3140[(set_attr "conds" "use")])
b11cae9e 3141\f
9c08d1fa 3142
3143; scc insns
3144
3145(define_expand "seq"
3146 [(set (match_operand:SI 0 "s_register_operand" "=r")
3147 (eq:SI (match_dup 1) (const_int 0)))]
3148 ""
3149 "
3150{
3151 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3152 arm_compare_fp);
3153}
3154")
3155
3156(define_expand "sne"
3157 [(set (match_operand:SI 0 "s_register_operand" "=r")
3158 (ne:SI (match_dup 1) (const_int 0)))]
3159 ""
3160 "
3161{
3162 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3163 arm_compare_fp);
3164}
3165")
3166
3167(define_expand "sgt"
3168 [(set (match_operand:SI 0 "s_register_operand" "=r")
3169 (gt:SI (match_dup 1) (const_int 0)))]
3170 ""
3171 "
3172{
3173 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3174 arm_compare_fp);
3175}
3176")
3177
3178(define_expand "sle"
3179 [(set (match_operand:SI 0 "s_register_operand" "=r")
3180 (le:SI (match_dup 1) (const_int 0)))]
3181 ""
3182 "
3183{
3184 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3185 arm_compare_fp);
3186}
3187")
3188
3189(define_expand "sge"
3190 [(set (match_operand:SI 0 "s_register_operand" "=r")
3191 (ge:SI (match_dup 1) (const_int 0)))]
3192 ""
3193 "
3194{
3195 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3196 arm_compare_fp);
3197}
3198")
3199
3200(define_expand "slt"
3201 [(set (match_operand:SI 0 "s_register_operand" "=r")
3202 (lt:SI (match_dup 1) (const_int 0)))]
3203 ""
3204 "
3205{
3206 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3207 arm_compare_fp);
3208}
3209")
3210
3211(define_expand "sgtu"
3212 [(set (match_operand:SI 0 "s_register_operand" "=r")
3213 (gtu:SI (match_dup 1) (const_int 0)))]
3214 ""
3215 "
3216{
3217 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3218 arm_compare_fp);
3219}
3220")
3221
3222(define_expand "sleu"
3223 [(set (match_operand:SI 0 "s_register_operand" "=r")
3224 (leu:SI (match_dup 1) (const_int 0)))]
3225 ""
3226 "
3227{
3228 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3229 arm_compare_fp);
3230}
3231")
3232
3233(define_expand "sgeu"
3234 [(set (match_operand:SI 0 "s_register_operand" "=r")
3235 (geu:SI (match_dup 1) (const_int 0)))]
3236 ""
3237 "
3238{
3239 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3240 arm_compare_fp);
3241}
3242")
3243
3244(define_expand "sltu"
3245 [(set (match_operand:SI 0 "s_register_operand" "=r")
3246 (ltu:SI (match_dup 1) (const_int 0)))]
3247 ""
3248 "
3249{
3250 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3251 arm_compare_fp);
3252}
3253")
3254
3255(define_insn ""
3256 [(set (match_operand:SI 0 "s_register_operand" "=r")
3257 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3258 ""
4d61e570 3259 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
9c08d1fa 3260[(set_attr "conds" "use")
094e994f 3261 (set_attr "length" "8")])
9c08d1fa 3262
3263(define_insn ""
3264 [(set (match_operand:SI 0 "s_register_operand" "=r")
3265 (neg:SI (match_operator:SI 1 "comparison_operator"
3266 [(reg 24) (const_int 0)])))]
3267 ""
4d61e570 3268 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
9c08d1fa 3269[(set_attr "conds" "use")
094e994f 3270 (set_attr "length" "8")])
9c08d1fa 3271
3272(define_insn ""
3273 [(set (match_operand:SI 0 "s_register_operand" "=r")
3274 (not:SI (match_operator:SI 1 "comparison_operator"
3275 [(reg 24) (const_int 0)])))]
3276 ""
4d61e570 3277 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
9c08d1fa 3278[(set_attr "conds" "use")
094e994f 3279 (set_attr "length" "8")])
9c08d1fa 3280
3281\f
3282;; Jump and linkage insns
3283
3284(define_insn "jump"
3285 [(set (pc)
3286 (label_ref (match_operand 0 "" "")))]
3287 ""
3288 "*
3289{
3290 extern int arm_ccfsm_state;
3291
3292 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3293 {
3294 arm_ccfsm_state += 2;
3295 return \"\";
3296 }
40dbec34 3297 return \"b%?\\t%l0\";
9c08d1fa 3298}")
3299
d3373b54 3300(define_expand "call"
3301 [(parallel [(call (match_operand 0 "memory_operand" "")
3302 (match_operand 1 "general_operand" ""))
3303 (clobber (reg:SI 14))])]
3304 ""
3305 "")
3306
3307(define_insn ""
3308 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3309 (match_operand 1 "" "g"))
9c08d1fa 3310 (clobber (reg:SI 14))]
3311 ""
3312 "*
5565501b 3313 return output_call (operands);
9c08d1fa 3314"
3315[(set (attr "conds")
3316 (if_then_else (eq_attr "cpu" "arm6")
3317 (const_string "clob")
3318 (const_string "nocond")))
3319;; length is worst case, normally it is only two
094e994f 3320 (set_attr "length" "12")
9c08d1fa 3321 (set_attr "type" "call")])
3322
3323(define_insn ""
3324 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3325 (match_operand 1 "general_operand" "g"))
3326 (clobber (reg:SI 14))]
3327 ""
3328 "*
5565501b 3329 return output_call_mem (operands);
9c08d1fa 3330"
3331[(set (attr "conds")
3332 (if_then_else (eq_attr "cpu" "arm6")
3333 (const_string "clob")
3334 (const_string "nocond")))
094e994f 3335 (set_attr "length" "12")
9c08d1fa 3336 (set_attr "type" "call")])
3337
d3373b54 3338(define_expand "call_value"
3339 [(parallel [(set (match_operand 0 "" "=rf")
3340 (call (match_operand 1 "memory_operand" "m")
3341 (match_operand 2 "general_operand" "g")))
3342 (clobber (reg:SI 14))])]
3343 ""
3344 "")
3345
3346(define_insn ""
9c08d1fa 3347 [(set (match_operand 0 "" "=rf")
d3373b54 3348 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3349 (match_operand 2 "general_operand" "g")))
9c08d1fa 3350 (clobber (reg:SI 14))]
3351 ""
3352 "*
5565501b 3353 return output_call (&operands[1]);
9c08d1fa 3354"
3355[(set (attr "conds")
3356 (if_then_else (eq_attr "cpu" "arm6")
3357 (const_string "clob")
3358 (const_string "nocond")))
094e994f 3359 (set_attr "length" "12")
9c08d1fa 3360 (set_attr "type" "call")])
3361
3362(define_insn ""
3363 [(set (match_operand 0 "" "=rf")
3364 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3365 (match_operand 2 "general_operand" "g")))
3366 (clobber (reg:SI 14))]
3367 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3368 "*
5565501b 3369 return output_call_mem (&operands[1]);
9c08d1fa 3370"
3371[(set (attr "conds")
3372 (if_then_else (eq_attr "cpu" "arm6")
3373 (const_string "clob")
3374 (const_string "nocond")))
094e994f 3375 (set_attr "length" "12")
9c08d1fa 3376 (set_attr "type" "call")])
3377
3378;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3379;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3380
3381(define_insn ""
3382 [(call (mem:SI (match_operand:SI 0 "" "i"))
3383 (match_operand:SI 1 "general_operand" "g"))
3384 (clobber (reg:SI 14))]
3385 "GET_CODE (operands[0]) == SYMBOL_REF"
40dbec34 3386 "bl%?\\t%a0"
9c08d1fa 3387[(set (attr "conds")
3388 (if_then_else (eq_attr "cpu" "arm6")
3389 (const_string "clob")
3390 (const_string "nocond")))
3391 (set_attr "type" "call")])
3392
3393(define_insn ""
3394 [(set (match_operand 0 "s_register_operand" "=rf")
3395 (call (mem:SI (match_operand:SI 1 "" "i"))
3396 (match_operand:SI 2 "general_operand" "g")))
3397 (clobber (reg:SI 14))]
3398 "GET_CODE(operands[1]) == SYMBOL_REF"
40dbec34 3399 "bl%?\\t%a1"
9c08d1fa 3400[(set (attr "conds")
3401 (if_then_else (eq_attr "cpu" "arm6")
3402 (const_string "clob")
3403 (const_string "nocond")))
3404 (set_attr "type" "call")])
3405
3406;; Often the return insn will be the same as loading from memory, so set attr
3407(define_insn "return"
3408 [(return)]
3409 "USE_RETURN_INSN"
3410 "*
3411{
3412 extern int arm_ccfsm_state;
3413
3414 if (arm_ccfsm_state == 2)
3415 {
3416 arm_ccfsm_state += 2;
3417 return \"\";
3418 }
3419 return output_return_instruction (NULL, TRUE);
3420}"
3421[(set_attr "type" "load")])
3422
3423(define_insn ""
3424 [(set (pc)
3425 (if_then_else (match_operator 0 "comparison_operator"
3426 [(reg 24) (const_int 0)])
3427 (return)
3428 (pc)))]
3429 "USE_RETURN_INSN"
3430 "*
3431{
3432 extern int arm_ccfsm_state;
3433
3434 if (arm_ccfsm_state == 2)
3435 {
3436 arm_ccfsm_state += 2;
3437 return \"\";
3438 }
3439 return output_return_instruction (operands[0], TRUE);
3440}"
3441[(set_attr "conds" "use")
3442 (set_attr "type" "load")])
3443
3444(define_insn ""
3445 [(set (pc)
3446 (if_then_else (match_operator 0 "comparison_operator"
3447 [(reg 24) (const_int 0)])
3448 (pc)
3449 (return)))]
3450 "USE_RETURN_INSN"
3451 "*
3452{
3453 extern int arm_ccfsm_state;
3454
3455 if (arm_ccfsm_state == 2)
3456 {
3457 arm_ccfsm_state += 2;
3458 return \"\";
3459 }
3460 return output_return_instruction
3461 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3462 GET_MODE (operands[0]), XEXP (operands[0], 0),
3463 XEXP (operands[0], 1)),
3464 TRUE);
3465}"
3466[(set_attr "conds" "use")
3467 (set_attr "type" "load")])
3468
3469;; Call subroutine returning any type.
3470
3471(define_expand "untyped_call"
3472 [(parallel [(call (match_operand 0 "" "")
3473 (const_int 0))
3474 (match_operand 1 "" "")
3475 (match_operand 2 "" "")])]
3476 ""
3477 "
3478{
3479 int i;
3480
3481 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3482
3483 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3484 {
3485 rtx set = XVECEXP (operands[2], 0, i);
3486 emit_move_insn (SET_DEST (set), SET_SRC (set));
3487 }
3488
3489 /* The optimizer does not know that the call sets the function value
3490 registers we stored in the result block. We avoid problems by
3491 claiming that all hard registers are used and clobbered at this
3492 point. */
3493 emit_insn (gen_blockage ());
3494
3495 DONE;
3496}")
3497
3498;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3499;; all of memory. This blocks insns from being moved across this point.
3500
3501(define_insn "blockage"
3502 [(unspec_volatile [(const_int 0)] 0)]
3503 ""
3504 ""
3505[(set_attr "length" "0")
3506 (set_attr "type" "block")])
3507
3508(define_insn "tablejump"
3509 [(set (pc)
3510 (match_operand:SI 0 "s_register_operand" "r"))
3511 (use (label_ref (match_operand 1 "" "")))]
3512 ""
899850b0 3513 "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
9c08d1fa 3514
3515(define_insn ""
3516 [(set (pc)
3517 (match_operand:SI 0 "memory_operand" "m"))
3518 (use (label_ref (match_operand 1 "" "")))]
3519 ""
899850b0 3520 "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
9c08d1fa 3521[(set_attr "type" "load")])
3522
3523(define_insn "indirect_jump"
3524 [(set (pc)
3525 (match_operand:SI 0 "s_register_operand" "r"))]
3526 ""
899850b0 3527 "mov%?\\t%|pc, %0\\t%@ indirect jump")
9c08d1fa 3528
3529(define_insn ""
3530 [(set (pc)
3531 (match_operand:SI 0 "memory_operand" "m"))]
3532 ""
899850b0 3533 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
9c08d1fa 3534[(set_attr "type" "load")])
3535\f
3536;; Misc insns
3537
3538(define_insn "nop"
3539 [(const_int 0)]
3540 ""
40dbec34 3541 "mov%?\\tr0, r0\\t%@ nop")
9c08d1fa 3542\f
3543;; Patterns to allow combination of arithmetic, cond code and shifts
3544
3545(define_insn ""
3546 [(set (match_operand:SI 0 "s_register_operand" "=r")
3547 (match_operator:SI 1 "shiftable_operator"
3548 [(match_operator:SI 3 "shift_operator"
3549 [(match_operand:SI 4 "s_register_operand" "r")
87b22bf7 3550 (match_operand:SI 5 "reg_or_int_operand" "rI")])
9c08d1fa 3551 (match_operand:SI 2 "s_register_operand" "r")]))]
3552 ""
87b22bf7 3553 "%i1%?\\t%0, %2, %4%S3")
9c08d1fa 3554
3555(define_insn ""
3556 [(set (reg:CC_NOOV 24)
3557 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3558 [(match_operator:SI 3 "shift_operator"
3559 [(match_operand:SI 4 "s_register_operand" "r")
87b22bf7 3560 (match_operand:SI 5 "reg_or_int_operand" "rI")])
9c08d1fa 3561 (match_operand:SI 2 "s_register_operand" "r")])
3562 (const_int 0)))
3563 (set (match_operand:SI 0 "s_register_operand" "=r")
3564 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3565 (match_dup 2)]))]
3566 ""
87b22bf7 3567 "%i1%?s\\t%0, %2, %4%S3"
9c08d1fa 3568[(set_attr "conds" "set")])
3569
3570(define_insn ""
3571 [(set (reg:CC_NOOV 24)
3572 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3573 [(match_operator:SI 3 "shift_operator"
3574 [(match_operand:SI 4 "s_register_operand" "r")
87b22bf7 3575 (match_operand:SI 5 "reg_or_int_operand" "rI")])
9c08d1fa 3576 (match_operand:SI 2 "s_register_operand" "r")])
3577 (const_int 0)))
3578 (clobber (match_scratch:SI 0 "=r"))]
3579 ""
87b22bf7 3580 "%i1%?s\\t%0, %2, %4%S3"
9c08d1fa 3581[(set_attr "conds" "set")])
3582
3583(define_insn ""
3584 [(set (match_operand:SI 0 "s_register_operand" "=r")
3585 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3586 (match_operator:SI 2 "shift_operator"
3587 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 3588 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
9c08d1fa 3589 ""
87b22bf7 3590 "sub%?\\t%0, %1, %3%S2")
9c08d1fa 3591
3592(define_insn ""
3593 [(set (reg:CC_NOOV 24)
40dbec34 3594 (compare:CC_NOOV
3595 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3596 (match_operator:SI 2 "shift_operator"
3597 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 3598 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
40dbec34 3599 (const_int 0)))
9c08d1fa 3600 (set (match_operand:SI 0 "s_register_operand" "=r")
3601 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3602 (match_dup 4)])))]
3603 ""
87b22bf7 3604 "sub%?s\\t%0, %1, %3%S2"
9c08d1fa 3605[(set_attr "conds" "set")])
3606
3607(define_insn ""
3608 [(set (reg:CC_NOOV 24)
40dbec34 3609 (compare:CC_NOOV
3610 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3611 (match_operator:SI 2 "shift_operator"
3612 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 3613 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
40dbec34 3614 (const_int 0)))
9c08d1fa 3615 (clobber (match_scratch:SI 0 "=r"))]
3616 ""
87b22bf7 3617 "sub%?s\\t%0, %1, %3%S2"
9c08d1fa 3618[(set_attr "conds" "set")])
3619
3620;; These variants of the above insns can occur if the first operand is the
3621;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3622;; seem to be a way around it. Most of the predicates have to be null
3623;; because the format can be generated part way through reload, so
3624;; if we don't match it as soon as it becomes available, reload doesn't know
3625;; how to reload pseudos that haven't got hard registers; the constraints will
3626;; sort everything out.
3627
3628(define_insn ""
3629 [(set (match_operand:SI 0 "" "=&r")
3630 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3631 [(match_operand:SI 3 "" "r")
87b22bf7 3632 (match_operand:SI 4 "" "rM")])
9c08d1fa 3633 (match_operand:SI 2 "" "r"))
3634 (match_operand:SI 1 "const_int_operand" "n")))]
3635 "reload_in_progress"
3636 "*
87b22bf7 3637 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
9c08d1fa 3638 operands[2] = operands[1];
3639 operands[1] = operands[0];
3640 return output_add_immediate (operands);
40dbec34 3641"
9c08d1fa 3642; we have no idea how long the add_immediate is, it could be up to 4.
094e994f 3643[(set_attr "length" "20")])
9c08d1fa 3644
3645(define_insn ""
3646 [(set (reg:CC_NOOV 24)
3647 (compare:CC_NOOV (plus:SI
3648 (plus:SI
3649 (match_operator:SI 5 "shift_operator"
3650 [(match_operand:SI 3 "" "r")
87b22bf7 3651 (match_operand:SI 4 "" "rM")])
9c08d1fa 3652 (match_operand:SI 1 "" "r"))
3653 (match_operand:SI 2 "const_int_operand" "n"))
3654 (const_int 0)))
3655 (set (match_operand:SI 0 "" "=&r")
3656 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3657 (match_dup 1))
3658 (match_dup 2)))]
3659 "reload_in_progress"
3660 "*
9c08d1fa 3661 output_add_immediate (operands);
87b22bf7 3662 return \"add%?s\\t%0, %0, %3%S5\";
40dbec34 3663"
9c08d1fa 3664[(set_attr "conds" "set")
094e994f 3665 (set_attr "length" "20")])
9c08d1fa 3666
3667(define_insn ""
3668 [(set (reg:CC_NOOV 24)
3669 (compare:CC_NOOV (plus:SI
3670 (plus:SI
3671 (match_operator:SI 5 "shift_operator"
3672 [(match_operand:SI 3 "" "r")
87b22bf7 3673 (match_operand:SI 4 "" "rM")])
9c08d1fa 3674 (match_operand:SI 1 "" "r"))
3675 (match_operand:SI 2 "const_int_operand" "n"))
3676 (const_int 0)))
3677 (clobber (match_scratch:SI 0 "=&r"))]
3678 "reload_in_progress"
3679 "*
9c08d1fa 3680 output_add_immediate (operands);
87b22bf7 3681 return \"add%?s\\t%0, %0, %3%S5\";
40dbec34 3682"
9c08d1fa 3683[(set_attr "conds" "set")
094e994f 3684 (set_attr "length" "20")])
12131158 3685
3686;; These are similar, but are needed when the mla pattern contains the
3687;; eliminated register as operand 3.
3688
3689(define_insn ""
3690 [(set (match_operand:SI 0 "" "=&r,&r")
3691 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3692 (match_operand:SI 2 "" "r,r"))
3693 (match_operand:SI 3 "" "r,r"))
3694 (match_operand:SI 4 "const_int_operand" "n,n")))]
3695 "reload_in_progress"
3696 "*
40dbec34 3697 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
12131158 3698 operands[2] = operands[4];
3699 operands[1] = operands[0];
3700 return output_add_immediate (operands);
3701"
094e994f 3702[(set_attr "length" "20")])
12131158 3703
3704(define_insn ""
3705 [(set (reg:CC_NOOV 24)
3706 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3707 (match_operand:SI 3 "" "r")
3708 (match_operand:SI 4 "" "r"))
3709 (match_operand:SI 1 "" "r"))
3710 (match_operand:SI 2 "const_int_operand" "n"))
3711 (const_int 0)))
3712 (set (match_operand:SI 0 "" "=&r")
3713 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3714 (match_dup 2)))]
3715 "reload_in_progress"
3716 "*
3717 output_add_immediate (operands);
40dbec34 3718 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
e2348bcb 3719 return \"\";
12131158 3720"
094e994f 3721[(set_attr "length" "20")
12131158 3722 (set_attr "conds" "set")])
3723
3724(define_insn ""
3725 [(set (reg:CC_NOOV 24)
3726 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3727 (match_operand:SI 3 "" "r")
3728 (match_operand:SI 4 "" "r"))
3729 (match_operand:SI 1 "" "r"))
3730 (match_operand:SI 2 "const_int_operand" "n"))
3731 (const_int 0)))
3732 (clobber (match_scratch:SI 0 "=&r"))]
3733 "reload_in_progress"
3734 "*
3735 output_add_immediate (operands);
40dbec34 3736 return \"mla%?s\\t%0, %3, %4, %0\";
12131158 3737"
094e994f 3738[(set_attr "length" "20")
12131158 3739 (set_attr "conds" "set")])
3740
3741
9c08d1fa 3742\f
3743
3744(define_insn ""
3745 [(set (match_operand:SI 0 "s_register_operand" "=r")
3746 (and:SI (match_operator 1 "comparison_operator"
4d61e570 3747 [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
9c08d1fa 3748 (match_operand:SI 2 "s_register_operand" "r")))]
3749 ""
e2348bcb 3750 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
9c08d1fa 3751[(set_attr "conds" "use")
094e994f 3752 (set_attr "length" "8")])
9c08d1fa 3753
3754(define_insn ""
3755 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3756 (ior:SI (match_operator 2 "comparison_operator"
3757 [(reg 24) (const_int 0)])
3758 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3759 ""
e2348bcb 3760 "@
899850b0 3761 orr%d2\\t%0, %1, #1
3762 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
9c08d1fa 3763[(set_attr "conds" "use")
094e994f 3764 (set_attr "length" "4,8")])
9c08d1fa 3765
3766(define_insn ""
5565501b 3767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3768 (match_operator 1 "comparison_operator"
5565501b 3769 [(match_operand:SI 2 "s_register_operand" "r,r")
3770 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9c08d1fa 3771 (clobber (reg 24))]
3772 ""
3773 "*
f0e75574 3774 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
e2348bcb 3775 return \"mov\\t%0, %2, lsr #31\";
3776
9c08d1fa 3777 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
e2348bcb 3778 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3779
9c08d1fa 3780 if (GET_CODE (operands[1]) == NE)
3781 {
5565501b 3782 if (which_alternative == 1)
e2348bcb 3783 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3784 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
9c08d1fa 3785 }
5565501b 3786 if (which_alternative == 1)
e2348bcb 3787 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 3788 else
e2348bcb 3789 output_asm_insn (\"cmp\\t%2, %3\", operands);
3790 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
9c08d1fa 3791"
3792[(set_attr "conds" "clob")
094e994f 3793 (set_attr "length" "12")])
9c08d1fa 3794
3795(define_insn ""
3796 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3797 (ior:SI (match_operator 1 "comparison_operator"
3798 [(match_operand:SI 2 "s_register_operand" "r")
3799 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3800 (match_operator 4 "comparison_operator"
3801 [(match_operand:SI 5 "s_register_operand" "r")
3802 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3803 (clobber (reg 24))]
3804 ""
3805 "*
3806{
3807 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3808 GET_CODE (operands[1]));
3809
e2348bcb 3810 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3811 operands);
3812 output_asm_insn (\"mov\\t%0, #0\", operands);
9c08d1fa 3813 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3814 || comparison_dominates_p (GET_CODE (operands[1]),
3815 GET_CODE (operands[4]))
3816 || dominant)
e2348bcb 3817 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3818 operands);
9c08d1fa 3819 else
e2348bcb 3820 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3821 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
9c08d1fa 3822}
3823"
3824[(set_attr "conds" "clob")
3825; worst case length
094e994f 3826 (set_attr "length" "20")])
9c08d1fa 3827
3828(define_split
3829 [(set (pc)
5565501b 3830 (if_then_else
3831 (match_operator 5 "equality_operator"
3832 [(ior:SI (match_operator 6 "comparison_operator"
3833 [(match_operand:SI 0 "s_register_operand" "")
3834 (match_operand:SI 1 "arm_add_operand" "")])
3835 (match_operator 7 "comparison_operator"
3836 [(match_operand:SI 2 "s_register_operand" "")
3837 (match_operand:SI 3 "arm_add_operand" "")]))
3838 (const_int 0)])
3839 (label_ref (match_operand 4 "" ""))
3840 (pc)))
9c08d1fa 3841 (clobber (reg 24))]
3842 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3843 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3844 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3845 [(set (reg:CC 24)
3846 (compare:CC (ior:CC (match_op_dup 6
3847 [(match_dup 0) (match_dup 1)])
3848 (match_op_dup 7
3849 [(match_dup 2) (match_dup 3)]))
3850 (const_int 0)))
3851 (set (pc)
3852 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3853 (label_ref (match_dup 4))
3854 (pc)))]
3855 "
3856{
3857 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3858 GET_CODE (operands[7]))
3859 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3860
3861 if (GET_CODE (operands[5]) == NE)
3862 operands[5] = gen_rtx (code, CCmode,
3863 XEXP (operands[5], 0), XEXP (operands[5], 1));
3864 else
3865 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3866 XEXP (operands[5], 0), XEXP (operands[5], 1));
3867}
3868")
3869
3870;; Don't match these patterns if we can use a conditional compare, since they
3871;; tell the final prescan branch elimator code that full branch inlining
3872;; can't be done.
3873
3874(define_insn ""
3875 [(set (pc)
5565501b 3876 (if_then_else
3877 (ne (ior:SI (match_operator 5 "comparison_operator"
3878 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3879 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3880 (match_operator 6 "comparison_operator"
3881 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3882 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
3883 (const_int 0))
3884 (label_ref (match_operand 4 "" ""))
3885 (pc)))
9c08d1fa 3886 (clobber (reg 24))]
3887 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3888 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3889 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3890 "*
3891{
3892 extern int arm_ccfsm_state;
3893
5565501b 3894 if (which_alternative & 1)
3895 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
9c08d1fa 3896 else
5565501b 3897 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
e2348bcb 3898
5565501b 3899 if (which_alternative >= 2)
e2348bcb 3900 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 3901 else
e2348bcb 3902 output_asm_insn (\"cmp\\t%2, %3\", operands);
3903
9c08d1fa 3904 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3905 {
3906 arm_ccfsm_state += 2;
3907 return \"\";
3908 }
e2348bcb 3909 return \"b%d6\\t%l4\";
9c08d1fa 3910}"
3911[(set_attr "conds" "jump_clob")
094e994f 3912 (set_attr "length" "16")])
9c08d1fa 3913
3914(define_insn ""
3915 [(set (reg:CC 24)
5565501b 3916 (compare:CC
3917 (ior:CC (match_operator 4 "comparison_operator"
3918 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3919 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3920 (match_operator 5 "comparison_operator"
3921 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3922 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
3923 (const_int 0)))]
9c08d1fa 3924 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3925 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3926 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3927 "*
3928 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3929 {
5565501b 3930 if (which_alternative >= 2)
e2348bcb 3931 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 3932 else
e2348bcb 3933 output_asm_insn (\"cmp\\t%2, %3\", operands);
3934
5565501b 3935 if (which_alternative & 1)
e2348bcb 3936 return \"cmn%D5\\t%0, #%n1\";
3937 return \"cmp%D5\\t%0, %1\";
9c08d1fa 3938 }
e2348bcb 3939
5565501b 3940 if (which_alternative & 1)
e2348bcb 3941 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
9c08d1fa 3942 else
e2348bcb 3943 output_asm_insn (\"cmp\\t%0, %1\", operands);
3944
5565501b 3945 if (which_alternative >= 2)
e2348bcb 3946 return \"cmn%D4\\t%2, #%n3\";
3947 return \"cmp%D4\\t%2, %3\";
9c08d1fa 3948"
3949[(set_attr "conds" "set")
094e994f 3950 (set_attr "length" "8")])
9c08d1fa 3951
3952(define_insn ""
3953 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3954 (if_then_else (match_operator 3 "equality_operator"
3955 [(match_operator 4 "comparison_operator"
3956 [(reg 24) (const_int 0)])
3957 (const_int 0)])
3958 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3959 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3960 ""
3961 "*
3962 if (GET_CODE (operands[3]) == NE)
3963 {
9c08d1fa 3964 if (which_alternative != 1)
e2348bcb 3965 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4d61e570 3966 if (which_alternative != 0)
3967 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9c08d1fa 3968 return \"\";
3969 }
3970 if (which_alternative != 0)
e2348bcb 3971 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9c08d1fa 3972 if (which_alternative != 1)
e2348bcb 3973 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9c08d1fa 3974 return \"\";
3975"
3976[(set_attr "conds" "use")
094e994f 3977 (set_attr "length" "4,4,8")])
9c08d1fa 3978
3979(define_insn ""
3980 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3981 (match_operator:SI 5 "shiftable_operator"
3982 [(match_operator:SI 4 "comparison_operator"
3983 [(match_operand:SI 2 "s_register_operand" "r,r")
3984 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3985 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3986 (clobber (reg 24))]
3987 ""
3988 "*
9c08d1fa 3989 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
40dbec34 3990 return \"%i5\\t%0, %1, %2, lsr #31\";
3991
e2348bcb 3992 output_asm_insn (\"cmp\\t%2, %3\", operands);
9c08d1fa 3993 if (GET_CODE (operands[5]) == AND)
e2348bcb 3994 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9c08d1fa 3995 else if (which_alternative != 0)
e2348bcb 3996 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
40dbec34 3997 return \"%i5%d4\\t%0, %1, #1\";
9c08d1fa 3998"
3999[(set_attr "conds" "clob")
094e994f 4000 (set_attr "length" "12")])
9c08d1fa 4001
4002(define_insn ""
4003 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4004 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4005 (match_operator:SI 4 "comparison_operator"
4006 [(match_operand:SI 2 "s_register_operand" "r,r")
4007 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4008 (clobber (reg 24))]
4009 ""
4010 "*
e2348bcb 4011 output_asm_insn (\"cmp\\t%2, %3\", operands);
9c08d1fa 4012 if (which_alternative != 0)
e2348bcb 4013 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4014 return \"sub%d4\\t%0, %1, #1\";
9c08d1fa 4015"
4016[(set_attr "conds" "clob")
094e994f 4017 (set_attr "length" "8,12")])
9c08d1fa 4018
4019(define_insn ""
4020 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4021 (and:SI (match_operator 1 "comparison_operator"
4022 [(match_operand:SI 2 "s_register_operand" "r")
4023 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4024 (match_operator 4 "comparison_operator"
4025 [(match_operand:SI 5 "s_register_operand" "r")
4026 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4027 (clobber (reg 24))]
4028 ""
4029 "*
4030{
4031 int dominant =
4032 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4033 reverse_condition (GET_CODE (operands[4])))
4034 ? 1
4035 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4036 reverse_condition (GET_CODE (operands[1])))
4037 ? 2 : 0;
e2348bcb 4038 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
9c08d1fa 4039 operands);
e2348bcb 4040 output_asm_insn (\"mov\\t%0, #1\", operands);
9c08d1fa 4041 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4042 {
e2348bcb 4043 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
9c08d1fa 4044 : \"cmp%d1\\t%5, %6\", operands);
4045 }
4046 else
4047 {
e2348bcb 4048 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4049 output_asm_insn (\"cmp\\t%5, %6\", operands);
9c08d1fa 4050 }
e2348bcb 4051 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
9c08d1fa 4052}
4053"
4054[(set_attr "conds" "clob")
094e994f 4055 (set_attr "length" "20")])
9c08d1fa 4056
4057(define_split
4058 [(set (pc)
4059 (if_then_else (match_operator 1 "equality_operator"
4060 [(and:SI (match_operator 2 "comparison_operator"
5565501b 4061 [(match_operand:SI 3 "s_register_operand" "")
4062 (match_operand:SI 4 "arm_add_operand" "")])
9c08d1fa 4063 (match_operator 0 "comparison_operator"
5565501b 4064 [(match_operand:SI 5 "s_register_operand" "")
4065 (match_operand:SI 6 "arm_add_operand" "")]))
9c08d1fa 4066 (const_int 0)])
4067 (label_ref (match_operand 7 "" ""))
4068 (pc)))
4069 (clobber (reg 24))]
4070 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4071 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4072 reverse_condition (GET_CODE (operands[0])))
4073 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4074 reverse_condition (GET_CODE (operands[2]))))"
4075 [(set (reg:CC 24)
4076 (compare:CC (ior:CC (match_op_dup 2
4077 [(match_dup 3) (match_dup 4)])
4078 (match_op_dup 0
4079 [(match_dup 5) (match_dup 6)]))
4080 (const_int 0)))
4081 (set (pc)
4082 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4083 (label_ref (match_dup 7))
4084 (pc)))]
4085 "
4086{
4087 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4088 This is safe since we only do it for integer comparisons. */
4089 enum rtx_code code =
4090 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4091 reverse_condition (GET_CODE (operands[0])))
4092 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4093
4094 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4095 GET_MODE (operands[2]), operands[3], operands[4]);
4096 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4097 GET_MODE (operands[0]), operands[5], operands[6]);
4098 if (GET_CODE (operands[1]) == NE)
4099 operands[1] = gen_rtx (code, CCmode,
4100 XEXP (operands[1], 0), XEXP (operands[1], 1));
4101 else
4102 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4103 XEXP (operands[1], 0), XEXP (operands[1], 1));
4104}
4105")
4106
4107;; Don't match these patterns if we can use a conditional compare, since they
4108;; tell the final prescan branch elimator code that full branch inlining
4109;; can't be done.
4110
4111(define_insn ""
4112 [(set (pc)
5565501b 4113 (if_then_else
4114 (eq (and:SI (match_operator 1 "comparison_operator"
4115 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4116 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4117 (match_operator 4 "comparison_operator"
4118 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4119 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4120 (const_int 0))
4121 (label_ref (match_operand 0 "" ""))
4122 (pc)))
9c08d1fa 4123 (clobber (reg 24))]
4124 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4125 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4126 reverse_condition (GET_CODE (operands[4])))
4127 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4128 reverse_condition (GET_CODE (operands[1]))))"
4129 "*
4130{
4131 extern int arm_ccfsm_state;
4132
5565501b 4133 if (which_alternative & 1)
4134 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
9c08d1fa 4135 else
5565501b 4136 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4137
4138 if (which_alternative >= 2)
e2348bcb 4139 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
9c08d1fa 4140 else
e2348bcb 4141 output_asm_insn (\"cmp\\t%5, %6\", operands);
5565501b 4142
9c08d1fa 4143 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4144 {
4145 arm_ccfsm_state += 2;
4146 return \"\";
4147 }
e2348bcb 4148 return \"b%D4\\t%l0\";
9c08d1fa 4149}"
4150[(set_attr "conds" "jump_clob")
094e994f 4151 (set_attr "length" "16")])
9c08d1fa 4152
4153(define_insn ""
4154 [(set (match_operand:SI 0 "s_register_operand" "=r")
4155 (neg:SI (match_operator 3 "comparison_operator"
4156 [(match_operand:SI 1 "s_register_operand" "r")
4157 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4158 (clobber (reg 24))]
4159 ""
4160 "*
f0e75574 4161 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
e2348bcb 4162 return \"mov\\t%0, %1, asr #31\";
4163
9c08d1fa 4164 if (GET_CODE (operands[3]) == NE)
e2348bcb 4165 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4166
9c08d1fa 4167 if (GET_CODE (operands[3]) == GT)
e2348bcb 4168 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4169
4170 output_asm_insn (\"cmp\\t%1, %2\", operands);
4171 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4172 return \"mvn%d3\\t%0, #0\";
9c08d1fa 4173"
4174[(set_attr "conds" "clob")
094e994f 4175 (set_attr "length" "12")])
9c08d1fa 4176
4177(define_insn "movcond"
4178 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 4179 (if_then_else:SI
4180 (match_operator 5 "comparison_operator"
4181 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4182 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4183 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4184 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9c08d1fa 4185 (clobber (reg 24))]
4186 ""
4187 "*
4188 if (GET_CODE (operands[5]) == LT
4189 && (operands[4] == const0_rtx))
4190 {
5565501b 4191 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
9c08d1fa 4192 {
9c08d1fa 4193 if (operands[2] == const0_rtx)
e2348bcb 4194 return \"and\\t%0, %1, %3, asr #31\";
4195 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 4196 }
4197 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4198 {
9c08d1fa 4199 if (operands[1] == const0_rtx)
e2348bcb 4200 return \"bic\\t%0, %2, %3, asr #31\";
4201 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 4202 }
4203 /* The only case that falls through to here is when both ops 1 & 2
4204 are constants */
4205 }
e2348bcb 4206
9c08d1fa 4207 if (GET_CODE (operands[5]) == GE
4208 && (operands[4] == const0_rtx))
4209 {
4210 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4211 {
9c08d1fa 4212 if (operands[2] == const0_rtx)
e2348bcb 4213 return \"bic\\t%0, %1, %3, asr #31\";
4214 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 4215 }
4216 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4217 {
9c08d1fa 4218 if (operands[1] == const0_rtx)
e2348bcb 4219 return \"and\\t%0, %2, %3, asr #31\";
4220 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 4221 }
4222 /* The only case that falls through to here is when both ops 1 & 2
4223 are constants */
4224 }
4225 if (GET_CODE (operands[4]) == CONST_INT
4226 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 4227 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 4228 else
e2348bcb 4229 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 4230 if (which_alternative != 0)
e2348bcb 4231 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 4232 if (which_alternative != 1)
e2348bcb 4233 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 4234 return \"\";
4235"
4236[(set_attr "conds" "clob")
094e994f 4237 (set_attr "length" "8,8,12")])
9c08d1fa 4238
4239(define_insn ""
5565501b 4240 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 4241 (if_then_else:SI (match_operator 9 "comparison_operator"
5565501b 4242 [(match_operand:SI 5 "s_register_operand" "r,r")
4243 (match_operand:SI 6 "arm_add_operand" "rI,L")])
9c08d1fa 4244 (match_operator:SI 8 "shiftable_operator"
5565501b 4245 [(match_operand:SI 1 "s_register_operand" "r,r")
4246 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
9c08d1fa 4247 (match_operator:SI 7 "shiftable_operator"
5565501b 4248 [(match_operand:SI 3 "s_register_operand" "r,r")
4249 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
9c08d1fa 4250 (clobber (reg 24))]
4251 ""
5565501b 4252 "@
4253 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4254 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
9c08d1fa 4255[(set_attr "conds" "clob")
094e994f 4256 (set_attr "length" "12")])
9c08d1fa 4257
4258(define_insn ""
4259 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4260 (if_then_else:SI (match_operator 6 "comparison_operator"
4261 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 4262 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4263 (match_operator:SI 7 "shiftable_operator"
4264 [(match_operand:SI 4 "s_register_operand" "r,r")
4265 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4266 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4267 (clobber (reg 24))]
4268 ""
4269 "*
9c08d1fa 4270 /* If we have an operation where (op x 0) is the identity operation and
4271 the condtional operator is LT or GE and we are comparing against zero and
4272 everything is in registers then we can do this in two instructions */
4273 if (operands[3] == const0_rtx
4274 && GET_CODE (operands[7]) != AND
4275 && GET_CODE (operands[5]) == REG
4276 && GET_CODE (operands[1]) == REG
4277 && REGNO (operands[1]) == REGNO (operands[4])
4278 && REGNO (operands[4]) != REGNO (operands[0]))
4279 {
4280 if (GET_CODE (operands[6]) == LT)
40dbec34 4281 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 4282 else if (GET_CODE (operands[6]) == GE)
40dbec34 4283 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 4284 }
4285 if (GET_CODE (operands[3]) == CONST_INT
4286 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 4287 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 4288 else
e2348bcb 4289 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 4290 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 4291 if (which_alternative != 0)
4292 {
4293 if (GET_CODE (operands[1]) == MEM)
40dbec34 4294 return \"ldr%D6\\t%0, %1\";
9c08d1fa 4295 else
40dbec34 4296 return \"mov%D6\\t%0, %1\";
9c08d1fa 4297 }
4298 return \"\";
9c08d1fa 4299"
4300[(set_attr "conds" "clob")
094e994f 4301 (set_attr "length" "8,12")])
9c08d1fa 4302
4303(define_insn ""
4304 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4305 (if_then_else:SI (match_operator 6 "comparison_operator"
4306 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 4307 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4308 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4309 (match_operator:SI 7 "shiftable_operator"
4310 [(match_operand:SI 2 "s_register_operand" "r,r")
4311 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4312 (clobber (reg 24))]
4313 ""
4314 "*
9c08d1fa 4315 /* If we have an operation where (op x 0) is the identity operation and
4316 the condtional operator is LT or GE and we are comparing against zero and
4317 everything is in registers then we can do this in two instructions */
4318 if (operands[5] == const0_rtx
4319 && GET_CODE (operands[7]) != AND
4320 && GET_CODE (operands[3]) == REG
4321 && GET_CODE (operands[1]) == REG
4322 && REGNO (operands[1]) == REGNO (operands[2])
4323 && REGNO (operands[2]) != REGNO (operands[0]))
4324 {
4325 if (GET_CODE (operands[6]) == GE)
40dbec34 4326 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 4327 else if (GET_CODE (operands[6]) == LT)
40dbec34 4328 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 4329 }
40dbec34 4330
9c08d1fa 4331 if (GET_CODE (operands[5]) == CONST_INT
4332 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 4333 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 4334 else
e2348bcb 4335 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 4336
9c08d1fa 4337 if (which_alternative != 0)
4338 {
4339 if (GET_CODE (operands[1]) == MEM)
e2348bcb 4340 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
9c08d1fa 4341 else
e2348bcb 4342 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9c08d1fa 4343 }
40dbec34 4344 return \"%I7%D6\\t%0, %2, %3\";
9c08d1fa 4345"
4346[(set_attr "conds" "clob")
094e994f 4347 (set_attr "length" "8,12")])
9c08d1fa 4348
4349(define_insn ""
4350 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4351 (if_then_else:SI (match_operator 6 "comparison_operator"
4352 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 4353 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4354 (plus:SI
4355 (match_operand:SI 2 "s_register_operand" "r,r")
4356 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4357 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4358 (clobber (reg 24))]
4359 ""
4360 "*
4361{
4362 if (GET_CODE (operands[5]) == CONST_INT
4363 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 4364 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 4365 else
e2348bcb 4366 output_asm_insn (\"cmp\\t%4, %5\", operands);
9c08d1fa 4367 if (GET_CODE (operands[3]) == CONST_INT
4368 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 4369 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
9c08d1fa 4370 else
e2348bcb 4371 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
9c08d1fa 4372 if (which_alternative != 0)
4373 {
4374 if (GET_CODE (operands[1]) == MEM)
e2348bcb 4375 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
9c08d1fa 4376 else
e2348bcb 4377 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
9c08d1fa 4378 }
4379 return \"\";
4380}
4381"
4382[(set_attr "conds" "clob")
094e994f 4383 (set_attr "length" "8,12")])
9c08d1fa 4384
4385(define_insn ""
4386 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4387 (if_then_else:SI (match_operator 6 "comparison_operator"
4388 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 4389 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4390 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4391 (plus:SI
4392 (match_operand:SI 2 "s_register_operand" "r,r")
5565501b 4393 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9c08d1fa 4394 (clobber (reg 24))]
4395 ""
4396 "*
4397{
4398 if (GET_CODE (operands[5]) == CONST_INT
4399 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 4400 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 4401 else
e2348bcb 4402 output_asm_insn (\"cmp\\t%4, %5\", operands);
9c08d1fa 4403 if (GET_CODE (operands[3]) == CONST_INT
4404 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 4405 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
9c08d1fa 4406 else
e2348bcb 4407 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
9c08d1fa 4408 if (which_alternative != 0)
4409 {
4410 if (GET_CODE (operands[6]) == MEM)
e2348bcb 4411 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
9c08d1fa 4412 else
e2348bcb 4413 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9c08d1fa 4414 }
4415 return \"\";
4416}
4417"
4418[(set_attr "conds" "clob")
094e994f 4419 (set_attr "length" "8,12")])
9c08d1fa 4420
4421(define_insn ""
4422 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4423 (if_then_else:SI (match_operator 5 "comparison_operator"
4424 [(match_operand:SI 3 "s_register_operand" "r,r")
5565501b 4425 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4426 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4427 (not:SI
4428 (match_operand:SI 2 "s_register_operand" "r,r"))))
4429 (clobber (reg 24))]
4430 ""
4431 "#"
4432[(set_attr "conds" "clob")
094e994f 4433 (set_attr "length" "8,12")])
9c08d1fa 4434
9c08d1fa 4435(define_insn ""
5565501b 4436 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4437 (if_then_else:SI
4438 (match_operator 5 "comparison_operator"
4439 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4440 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4441 (not:SI
4442 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4443 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
9c08d1fa 4444 (clobber (reg 24))]
4445 ""
5565501b 4446 "@
4447 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4448 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4449 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4450 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
9c08d1fa 4451[(set_attr "conds" "clob")
5565501b 4452 (set_attr "length" "8,8,12,12")])
4453
4454(define_insn ""
4455 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4456 (if_then_else:SI
4457 (match_operator 6 "comparison_operator"
4458 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4459 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4460 (match_operator:SI 7 "shift_operator"
4461 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
87b22bf7 4462 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
5565501b 4463 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
9c08d1fa 4464 (clobber (reg 24))]
4465 ""
5565501b 4466 "@
87b22bf7 4467 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4468 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4469 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4470 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
9c08d1fa 4471[(set_attr "conds" "clob")
5565501b 4472 (set_attr "length" "8,8,12,12")])
4473
4474(define_insn ""
4475 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4476 (if_then_else:SI
4477 (match_operator 6 "comparison_operator"
4478 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4479 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4480 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4481 (match_operator:SI 7 "shift_operator"
4482 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
87b22bf7 4483 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
9c08d1fa 4484 (clobber (reg 24))]
4485 ""
5565501b 4486 "@
87b22bf7 4487 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4488 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4489 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4490 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
9c08d1fa 4491[(set_attr "conds" "clob")
5565501b 4492 (set_attr "length" "8,8,12,12")])
9c08d1fa 4493
4494(define_insn ""
5565501b 4495 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4496 (if_then_else:SI
4497 (match_operator 7 "comparison_operator"
4498 [(match_operand:SI 5 "s_register_operand" "r,r")
4499 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4500 (match_operator:SI 8 "shift_operator"
4501 [(match_operand:SI 1 "s_register_operand" "r,r")
87b22bf7 4502 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
5565501b 4503 (match_operator:SI 9 "shift_operator"
4504 [(match_operand:SI 3 "s_register_operand" "r,r")
4505 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
9c08d1fa 4506 (clobber (reg 24))]
4507 ""
5565501b 4508 "@
87b22bf7 4509 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4510 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
9c08d1fa 4511[(set_attr "conds" "clob")
094e994f 4512 (set_attr "length" "12")])
9c08d1fa 4513
4514(define_insn ""
5565501b 4515 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4516 (if_then_else:SI
4517 (match_operator 6 "comparison_operator"
4518 [(match_operand:SI 4 "s_register_operand" "r,r")
4519 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4520 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4521 (match_operator:SI 7 "shiftable_operator"
4522 [(match_operand:SI 2 "s_register_operand" "r,r")
4523 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9c08d1fa 4524 (clobber (reg 24))]
4525 ""
5565501b 4526 "@
4527 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4528 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
9c08d1fa 4529[(set_attr "conds" "clob")
094e994f 4530 (set_attr "length" "12")])
9c08d1fa 4531
4532(define_insn ""
5565501b 4533 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4534 (if_then_else:SI
4535 (match_operator 6 "comparison_operator"
4536 [(match_operand:SI 4 "s_register_operand" "r,r")
4537 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4538 (match_operator:SI 7 "shiftable_operator"
4539 [(match_operand:SI 2 "s_register_operand" "r,r")
4540 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4541 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
9c08d1fa 4542 (clobber (reg 24))]
4543 ""
5565501b 4544 "@
899850b0 4545 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4546 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
9c08d1fa 4547[(set_attr "conds" "clob")
094e994f 4548 (set_attr "length" "12")])
9c08d1fa 4549
4550(define_insn ""
5565501b 4551 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4552 (if_then_else:SI
4553 (match_operator 5 "comparison_operator"
4554 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4555 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4556 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4557 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
9c08d1fa 4558 (clobber (reg:CC 24))]
4559 ""
5565501b 4560 "@
4561 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4562 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4563 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4564 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
9c08d1fa 4565[(set_attr "conds" "clob")
5565501b 4566 (set_attr "length" "8,8,12,12")])
9c08d1fa 4567
4568(define_insn ""
5565501b 4569 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4570 (if_then_else:SI
4571 (match_operator 5 "comparison_operator"
4572 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4573 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4574 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4575 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
9c08d1fa 4576 (clobber (reg:CC 24))]
4577 ""
5565501b 4578 "@
4579 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4580 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4581 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4582 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
9c08d1fa 4583[(set_attr "conds" "clob")
5565501b 4584 (set_attr "length" "8,8,12,12")])
9c08d1fa 4585
4586(define_insn ""
4587 [(set (match_operand:SI 0 "s_register_operand" "=r")
4588 (match_operator:SI 1 "shiftable_operator"
4589 [(match_operand:SI 2 "memory_operand" "m")
4590 (match_operand:SI 3 "memory_operand" "m")]))
4591 (clobber (match_scratch:SI 4 "=r"))]
4592 "adjacent_mem_locations (operands[2], operands[3])"
4593 "*
4594{
4595 rtx ldm[3];
c7597b5d 4596 rtx arith[4];
9c08d1fa 4597 int val1 = 0, val2 = 0;
4598
9c08d1fa 4599 if (REGNO (operands[0]) > REGNO (operands[4]))
4600 {
4601 ldm[1] = operands[4];
4602 ldm[2] = operands[0];
4603 }
4604 else
4605 {
4606 ldm[1] = operands[0];
4607 ldm[2] = operands[4];
4608 }
4609 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4610 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4611 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4612 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4613 arith[0] = operands[0];
c7597b5d 4614 arith[3] = operands[1];
9c08d1fa 4615 if (val1 < val2)
4616 {
4617 arith[1] = ldm[1];
4618 arith[2] = ldm[2];
4619 }
4620 else
4621 {
4622 arith[1] = ldm[2];
4623 arith[2] = ldm[1];
4624 }
4625 if (val1 && val2)
4626 {
4627 rtx ops[3];
4628 ldm[0] = ops[0] = operands[4];
4629 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4630 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4631 output_add_immediate (ops);
4632 if (val1 < val2)
40dbec34 4633 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9c08d1fa 4634 else
40dbec34 4635 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9c08d1fa 4636 }
4637 else if (val1)
4638 {
4639 ldm[0] = XEXP (operands[3], 0);
4640 if (val1 < val2)
40dbec34 4641 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9c08d1fa 4642 else
40dbec34 4643 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9c08d1fa 4644 }
4645 else
4646 {
4647 ldm[0] = XEXP (operands[2], 0);
4648 if (val1 < val2)
40dbec34 4649 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9c08d1fa 4650 else
40dbec34 4651 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9c08d1fa 4652 }
c7597b5d 4653 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
e2348bcb 4654 return \"\";
9c08d1fa 4655}
4656"
094e994f 4657[(set_attr "length" "12")
9c08d1fa 4658 (set_attr "type" "load")])
4659
4660;; the arm can support extended pre-inc instructions
4661
4662;; In all these cases, we use operands 0 and 1 for the register being
4663;; incremented because those are the operands that local-alloc will
4664;; tie and these are the pair most likely to be tieable (and the ones
4665;; that will benefit the most).
4666
4667;; We reject the frame pointer if it occurs anywhere in these patterns since
4668;; elimination will cause too many headaches.
4669
4670(define_insn ""
4671 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4672 (match_operand:SI 2 "index_operand" "rJ")))
4673 (match_operand:QI 3 "s_register_operand" "r"))
4674 (set (match_operand:SI 0 "s_register_operand" "=r")
4675 (plus:SI (match_dup 1) (match_dup 2)))]
4676 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4677 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4678 && (GET_CODE (operands[2]) != REG
4679 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4680 "str%?b\\t%3, [%0, %2]!"
9c08d1fa 4681[(set_attr "type" "store1")])
4682
4683(define_insn ""
4684 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4685 (match_operand:SI 2 "s_register_operand" "r")))
4686 (match_operand:QI 3 "s_register_operand" "r"))
4687 (set (match_operand:SI 0 "s_register_operand" "=r")
4688 (minus:SI (match_dup 1) (match_dup 2)))]
4689 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4690 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4691 && (GET_CODE (operands[2]) != REG
4692 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4693 "str%?b\\t%3, [%0, -%2]!"
9c08d1fa 4694[(set_attr "type" "store1")])
4695
4696(define_insn ""
4697 [(set (match_operand:QI 3 "s_register_operand" "=r")
4698 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4699 (match_operand:SI 2 "index_operand" "rJ"))))
4700 (set (match_operand:SI 0 "s_register_operand" "=r")
4701 (plus:SI (match_dup 1) (match_dup 2)))]
4702 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4703 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4704 && (GET_CODE (operands[2]) != REG
4705 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4706 "ldr%?b\\t%3, [%0, %2]!"
9c08d1fa 4707[(set_attr "type" "load")])
4708
4709(define_insn ""
4710 [(set (match_operand:QI 3 "s_register_operand" "=r")
4711 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4712 (match_operand:SI 2 "s_register_operand" "r"))))
4713 (set (match_operand:SI 0 "s_register_operand" "=r")
4714 (minus:SI (match_dup 1) (match_dup 2)))]
4715 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4716 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4717 && (GET_CODE (operands[2]) != REG
4718 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4719 "ldr%?b\\t%3, [%0, -%2]!"
9c08d1fa 4720[(set_attr "type" "load")])
4721
4722(define_insn ""
4723 [(set (match_operand:SI 3 "s_register_operand" "=r")
4724 (zero_extend:SI
4725 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4726 (match_operand:SI 2 "index_operand" "rJ")))))
4727 (set (match_operand:SI 0 "s_register_operand" "=r")
4728 (plus:SI (match_dup 1) (match_dup 2)))]
4729 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4730 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4731 && (GET_CODE (operands[2]) != REG
4732 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4733 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9c08d1fa 4734[(set_attr "type" "load")])
4735
4736(define_insn ""
4737 [(set (match_operand:SI 3 "s_register_operand" "=r")
4738 (zero_extend:SI
4739 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4740 (match_operand:SI 2 "s_register_operand" "r")))))
4741 (set (match_operand:SI 0 "s_register_operand" "=r")
4742 (minus:SI (match_dup 1) (match_dup 2)))]
4743 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4744 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4745 && (GET_CODE (operands[2]) != REG
4746 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4747 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9c08d1fa 4748[(set_attr "type" "load")])
4749
4750(define_insn ""
4751 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4752 (match_operand:SI 2 "index_operand" "rJ")))
4753 (match_operand:SI 3 "s_register_operand" "r"))
4754 (set (match_operand:SI 0 "s_register_operand" "=r")
4755 (plus:SI (match_dup 1) (match_dup 2)))]
4756 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4757 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4758 && (GET_CODE (operands[2]) != REG
4759 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4760 "str%?\\t%3, [%0, %2]!"
9c08d1fa 4761[(set_attr "type" "store1")])
4762
4763(define_insn ""
4764 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4765 (match_operand:SI 2 "s_register_operand" "r")))
4766 (match_operand:SI 3 "s_register_operand" "r"))
4767 (set (match_operand:SI 0 "s_register_operand" "=r")
4768 (minus:SI (match_dup 1) (match_dup 2)))]
4769 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4770 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4771 && (GET_CODE (operands[2]) != REG
4772 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4773 "str%?\\t%3, [%0, -%2]!"
9c08d1fa 4774[(set_attr "type" "store1")])
4775
4776(define_insn ""
4777 [(set (match_operand:SI 3 "s_register_operand" "=r")
4778 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4779 (match_operand:SI 2 "index_operand" "rJ"))))
4780 (set (match_operand:SI 0 "s_register_operand" "=r")
4781 (plus:SI (match_dup 1) (match_dup 2)))]
4782 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4783 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4784 && (GET_CODE (operands[2]) != REG
4785 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4786 "ldr%?\\t%3, [%0, %2]!"
9c08d1fa 4787[(set_attr "type" "load")])
4788
4789(define_insn ""
4790 [(set (match_operand:SI 3 "s_register_operand" "=r")
4791 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4792 (match_operand:SI 2 "s_register_operand" "r"))))
4793 (set (match_operand:SI 0 "s_register_operand" "=r")
4794 (minus:SI (match_dup 1) (match_dup 2)))]
4795 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4796 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4797 && (GET_CODE (operands[2]) != REG
4798 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4799 "ldr%?\\t%3, [%0, -%2]!"
9c08d1fa 4800[(set_attr "type" "load")])
4801
4802(define_insn ""
4803 [(set (match_operand:HI 3 "s_register_operand" "=r")
4804 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4805 (match_operand:SI 2 "index_operand" "rJ"))))
4806 (set (match_operand:SI 0 "s_register_operand" "=r")
4807 (plus:SI (match_dup 1) (match_dup 2)))]
c7597b5d 4808 "(! BYTES_BIG_ENDIAN)
25f7a26e 4809 && ! TARGET_SHORT_BY_BYTES
c7597b5d 4810 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 4811 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4812 && (GET_CODE (operands[2]) != REG
4813 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4814 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
9c08d1fa 4815[(set_attr "type" "load")])
4816
4817(define_insn ""
4818 [(set (match_operand:HI 3 "s_register_operand" "=r")
4819 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4820 (match_operand:SI 2 "s_register_operand" "r"))))
4821 (set (match_operand:SI 0 "s_register_operand" "=r")
4822 (minus:SI (match_dup 1) (match_dup 2)))]
c7597b5d 4823 "(!BYTES_BIG_ENDIAN)
25f7a26e 4824 && ! TARGET_SHORT_BY_BYTES
c7597b5d 4825 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 4826 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4827 && (GET_CODE (operands[2]) != REG
4828 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4829 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
9c08d1fa 4830[(set_attr "type" "load")])
4831
4832(define_insn ""
4833 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4834 [(match_operand:SI 3 "s_register_operand" "r")
4835 (match_operand:SI 4 "const_shift_operand" "n")])
4836 (match_operand:SI 1 "s_register_operand" "0")))
4837 (match_operand:QI 5 "s_register_operand" "r"))
4838 (set (match_operand:SI 0 "s_register_operand" "=r")
4839 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4840 (match_dup 1)))]
4841 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4842 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4843 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4844 "str%?b\\t%5, [%0, %3%S2]!"
9c08d1fa 4845[(set_attr "type" "store1")])
4846
4847(define_insn ""
4848 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4849 (match_operator:SI 2 "shift_operator"
4850 [(match_operand:SI 3 "s_register_operand" "r")
4851 (match_operand:SI 4 "const_shift_operand" "n")])))
4852 (match_operand:QI 5 "s_register_operand" "r"))
4853 (set (match_operand:SI 0 "s_register_operand" "=r")
4854 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4855 (match_dup 4)])))]
4856 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4857 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4858 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4859 "str%?b\\t%5, [%0, -%3%S2]!"
9c08d1fa 4860[(set_attr "type" "store1")])
4861
4862(define_insn ""
4863 [(set (match_operand:QI 5 "s_register_operand" "=r")
4864 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4865 [(match_operand:SI 3 "s_register_operand" "r")
4866 (match_operand:SI 4 "const_shift_operand" "n")])
4867 (match_operand:SI 1 "s_register_operand" "0"))))
4868 (set (match_operand:SI 0 "s_register_operand" "=r")
4869 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4870 (match_dup 1)))]
4871 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4872 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4873 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4874 "ldr%?b\\t%5, [%0, %3%S2]!"
9c08d1fa 4875[(set_attr "type" "load")])
4876
4877(define_insn ""
4878 [(set (match_operand:QI 5 "s_register_operand" "=r")
4879 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4880 (match_operator:SI 2 "shift_operator"
4881 [(match_operand:SI 3 "s_register_operand" "r")
4882 (match_operand:SI 4 "const_shift_operand" "n")]))))
4883 (set (match_operand:SI 0 "s_register_operand" "=r")
4884 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4885 (match_dup 4)])))]
4886 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4887 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4888 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4889 "ldr%?b\\t%5, [%0, -%3%S2]!"
9c08d1fa 4890[(set_attr "type" "load")])
4891
4892(define_insn ""
4893 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4894 [(match_operand:SI 3 "s_register_operand" "r")
4895 (match_operand:SI 4 "const_shift_operand" "n")])
4896 (match_operand:SI 1 "s_register_operand" "0")))
4897 (match_operand:SI 5 "s_register_operand" "r"))
4898 (set (match_operand:SI 0 "s_register_operand" "=r")
4899 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4900 (match_dup 1)))]
4901 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4902 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4903 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4904 "str%?\\t%5, [%0, %3%S2]!"
9c08d1fa 4905[(set_attr "type" "store1")])
4906
4907(define_insn ""
4908 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4909 (match_operator:SI 2 "shift_operator"
4910 [(match_operand:SI 3 "s_register_operand" "r")
4911 (match_operand:SI 4 "const_shift_operand" "n")])))
4912 (match_operand:SI 5 "s_register_operand" "r"))
4913 (set (match_operand:SI 0 "s_register_operand" "=r")
4914 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4915 (match_dup 4)])))]
4916 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4917 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4918 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4919 "str%?\\t%5, [%0, -%3%S2]!"
9c08d1fa 4920[(set_attr "type" "store1")])
4921
4922(define_insn ""
4923 [(set (match_operand:SI 5 "s_register_operand" "=r")
4924 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4925 [(match_operand:SI 3 "s_register_operand" "r")
4926 (match_operand:SI 4 "const_shift_operand" "n")])
4927 (match_operand:SI 1 "s_register_operand" "0"))))
4928 (set (match_operand:SI 0 "s_register_operand" "=r")
4929 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4930 (match_dup 1)))]
4931 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4932 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4933 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4934 "ldr%?\\t%5, [%0, %3%S2]!"
9c08d1fa 4935[(set_attr "type" "load")])
4936
4937(define_insn ""
4938 [(set (match_operand:SI 5 "s_register_operand" "=r")
4939 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4940 (match_operator:SI 2 "shift_operator"
4941 [(match_operand:SI 3 "s_register_operand" "r")
4942 (match_operand:SI 4 "const_shift_operand" "n")]))))
4943 (set (match_operand:SI 0 "s_register_operand" "=r")
4944 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4945 (match_dup 4)])))]
4946 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4947 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4948 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4949 "ldr%?\\t%5, [%0, -%3%S2]!"
9c08d1fa 4950[(set_attr "type" "load")])
4951
4952(define_insn ""
4953 [(set (match_operand:HI 5 "s_register_operand" "=r")
4954 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
4955 [(match_operand:SI 3 "s_register_operand" "r")
4956 (match_operand:SI 4 "const_shift_operand" "n")])
4957 (match_operand:SI 1 "s_register_operand" "0"))))
4958 (set (match_operand:SI 0 "s_register_operand" "=r")
4959 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4960 (match_dup 1)))]
c7597b5d 4961 "(! BYTES_BIG_ENDIAN)
25f7a26e 4962 && ! TARGET_SHORT_BY_BYTES
c7597b5d 4963 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 4964 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4965 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4966 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
9c08d1fa 4967[(set_attr "type" "load")])
4968
4969(define_insn ""
4970 [(set (match_operand:HI 5 "s_register_operand" "=r")
4971 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4972 (match_operator:SI 2 "shift_operator"
4973 [(match_operand:SI 3 "s_register_operand" "r")
4974 (match_operand:SI 4 "const_shift_operand" "n")]))))
4975 (set (match_operand:SI 0 "s_register_operand" "=r")
4976 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4977 (match_dup 4)])))]
c7597b5d 4978 "(! BYTES_BIG_ENDIAN)
25f7a26e 4979 && ! TARGET_SHORT_BY_BYTES
c7597b5d 4980 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 4981 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4982 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4983 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
9c08d1fa 4984[(set_attr "type" "load")])
4985
4986; It can also support extended post-inc expressions, but combine doesn't
4987; try these....
4988; It doesn't seem worth adding peepholes for anything but the most common
4989; cases since, unlike combine, the increment must immediately follow the load
4990; for this pattern to match.
4991; When loading we must watch to see that the base register isn't trampled by
4992; the load. In such cases this isn't a post-inc expression.
4993
4994(define_peephole
4995 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
4996 (match_operand:QI 2 "s_register_operand" "r"))
4997 (set (match_dup 0)
4998 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4999 ""
c7597b5d 5000 "str%?b\\t%2, [%0], %1")
9c08d1fa 5001
5002(define_peephole
5003 [(set (match_operand:QI 0 "s_register_operand" "=r")
5004 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5005 (set (match_dup 1)
5006 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5007 "REGNO(operands[0]) != REGNO(operands[1])
5008 && (GET_CODE (operands[2]) != REG
5009 || REGNO(operands[0]) != REGNO (operands[2]))"
40dbec34 5010 "ldr%?b\\t%0, [%1], %2")
9c08d1fa 5011
5012(define_peephole
5013 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5014 (match_operand:SI 2 "s_register_operand" "r"))
5015 (set (match_dup 0)
5016 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5017 ""
40dbec34 5018 "str%?\\t%2, [%0], %1")
9c08d1fa 5019
5020(define_peephole
5021 [(set (match_operand:HI 0 "s_register_operand" "=r")
5022 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5023 (set (match_dup 1)
5024 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
c7597b5d 5025 "(! BYTES_BIG_ENDIAN)
25f7a26e 5026 && ! TARGET_SHORT_BY_BYTES
c7597b5d 5027 && REGNO(operands[0]) != REGNO(operands[1])
9c08d1fa 5028 && (GET_CODE (operands[2]) != REG
5029 || REGNO(operands[0]) != REGNO (operands[2]))"
40dbec34 5030 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
9c08d1fa 5031
5032(define_peephole
5033 [(set (match_operand:SI 0 "s_register_operand" "=r")
5034 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5035 (set (match_dup 1)
5036 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5037 "REGNO(operands[0]) != REGNO(operands[1])
5038 && (GET_CODE (operands[2]) != REG
5039 || REGNO(operands[0]) != REGNO (operands[2]))"
40dbec34 5040 "ldr%?\\t%0, [%1], %2")
9c08d1fa 5041
c7597b5d 5042(define_peephole
5043 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5044 (match_operand:SI 1 "index_operand" "rJ")))
5045 (match_operand:QI 2 "s_register_operand" "r"))
5046 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5047 ""
5048 "str%?b\\t%2, [%0, %1]!")
5049
5050(define_peephole
5051 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5052 [(match_operand:SI 0 "s_register_operand" "r")
87b22bf7 5053 (match_operand:SI 1 "const_int_operand" "n")])
c7597b5d 5054 (match_operand:SI 2 "s_register_operand" "+r")))
5055 (match_operand:QI 3 "s_register_operand" "r"))
5056 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5057 (match_dup 2)))]
5058 ""
87b22bf7 5059 "str%?b\\t%3, [%2, %0%S4]!")
c7597b5d 5060
9c08d1fa 5061; This pattern is never tried by combine, so do it as a peephole
5062
5063(define_peephole
5064 [(set (match_operand:SI 0 "s_register_operand" "=r")
5065 (match_operand:SI 1 "s_register_operand" "r"))
5066 (set (match_operand 2 "cc_register" "")
5067 (compare (match_dup 1) (const_int 0)))]
5068 ""
40dbec34 5069 "sub%?s\\t%0, %1, #0"
9c08d1fa 5070[(set_attr "conds" "set")])
5071
5072; Peepholes to spot possible load- and store-multiples, if the ordering is
5073; reversed, check that the memory references aren't volatile.
5074
5075(define_peephole
5076 [(set (match_operand:SI 0 "s_register_operand" "=r")
5077 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5078 (const_int 12))))
5079 (set (match_operand:SI 2 "s_register_operand" "=r")
5080 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5081 (set (match_operand:SI 3 "s_register_operand" "=r")
5082 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5083 (set (match_operand:SI 4 "s_register_operand" "=r")
5084 (mem:SI (match_dup 1)))]
5085 "REGNO (operands[0]) > REGNO (operands[2])
5086 && REGNO (operands[2]) > REGNO (operands[3])
5087 && REGNO (operands[3]) > REGNO (operands[4])
5088 && !(REGNO (operands[1]) == REGNO (operands[0])
5089 || REGNO (operands[1]) == REGNO (operands[2])
5090 || REGNO (operands[1]) == REGNO (operands[3])
5091 || REGNO (operands[1]) == REGNO (operands[4]))
5092 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5093 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5094 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5095 (prev_nonnote_insn (insn)))))
5096 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5097 (prev_nonnote_insn
5098 (prev_nonnote_insn (insn))))))"
40dbec34 5099 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
9c08d1fa 5100
5101(define_peephole
5102 [(set (match_operand:SI 0 "s_register_operand" "=r")
5103 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5104 (const_int 8))))
5105 (set (match_operand:SI 2 "s_register_operand" "=r")
5106 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5107 (set (match_operand:SI 3 "s_register_operand" "=r")
5108 (mem:SI (match_dup 1)))]
5109 "REGNO (operands[0]) > REGNO (operands[2])
5110 && REGNO (operands[2]) > REGNO (operands[3])
5111 && !(REGNO (operands[1]) == REGNO (operands[0])
5112 || REGNO (operands[1]) == REGNO (operands[2])
5113 || REGNO (operands[1]) == REGNO (operands[3]))
5114 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5115 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5116 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5117 (prev_nonnote_insn (insn)))))"
40dbec34 5118 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
9c08d1fa 5119
5120(define_peephole
5121 [(set (match_operand:SI 0 "s_register_operand" "=r")
5122 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5123 (const_int 4))))
5124 (set (match_operand:SI 2 "s_register_operand" "=r")
5125 (mem:SI (match_dup 1)))]
5126 "REGNO (operands[0]) > REGNO (operands[2])
5127 && !(REGNO (operands[1]) == REGNO (operands[0])
5128 || REGNO (operands[1]) == REGNO (operands[2]))
5129 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5130 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
40dbec34 5131 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
9c08d1fa 5132
5133(define_peephole
5134 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5135 (const_int 12)))
5136 (match_operand:SI 0 "s_register_operand" "r"))
5137 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5138 (match_operand:SI 2 "s_register_operand" "r"))
5139 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5140 (match_operand:SI 3 "s_register_operand" "r"))
5141 (set (mem:SI (match_dup 1))
5142 (match_operand:SI 4 "s_register_operand" "r"))]
5143 "REGNO (operands[0]) > REGNO (operands[2])
5144 && REGNO (operands[2]) > REGNO (operands[3])
5145 && REGNO (operands[3]) > REGNO (operands[4])
5146 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5147 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5148 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5149 (prev_nonnote_insn (insn)))))
5150 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5151 (prev_nonnote_insn
5152 (prev_nonnote_insn (insn))))))"
40dbec34 5153 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
9c08d1fa 5154
5155(define_peephole
5156 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5157 (const_int 8)))
5158 (match_operand:SI 0 "s_register_operand" "r"))
5159 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5160 (match_operand:SI 2 "s_register_operand" "r"))
5161 (set (mem:SI (match_dup 1))
5162 (match_operand:SI 3 "s_register_operand" "r"))]
5163 "REGNO (operands[0]) > REGNO (operands[2])
5164 && REGNO (operands[2]) > REGNO (operands[3])
5165 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5166 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5167 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5168 (prev_nonnote_insn (insn)))))"
40dbec34 5169 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
9c08d1fa 5170
5171(define_peephole
5172 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5173 (const_int 4)))
5174 (match_operand:SI 0 "s_register_operand" "r"))
5175 (set (mem:SI (match_dup 1))
5176 (match_operand:SI 2 "s_register_operand" "r"))]
5177 "REGNO (operands[0]) > REGNO (operands[2])
5178 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5179 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
40dbec34 5180 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
9c08d1fa 5181
5182;; A call followed by return can be replaced by restoring the regs and
5183;; jumping to the subroutine, provided we aren't passing the address of
5184;; any of our local variables. If we call alloca then this is unsafe
5185;; since restoring the frame frees the memory, which is not what we want.
5186;; Sometimes the return might have been targeted by the final prescan:
5187;; if so then emit a propper return insn as well.
5188;; Unfortunately, if the frame pointer is required, we don't know if the
5189;; current function has any implicit stack pointer adjustments that will
5190;; be restored by the return: we can't therefore do a tail call.
5191;; Another unfortunate that we can't handle is if current_function_args_size
5192;; is non-zero: in this case elimination of the argument pointer assumed
5193;; that lr was pushed onto the stack, so eliminating upsets the offset
5194;; calculations.
5195
5196(define_peephole
5197 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5198 (match_operand:SI 1 "general_operand" "g"))
5199 (clobber (reg:SI 14))])
5200 (return)]
5201 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5202 && !get_frame_size () && !current_function_calls_alloca
5203 && !frame_pointer_needed && !current_function_args_size)"
5204 "*
5205{
5206 extern rtx arm_target_insn;
5207 extern int arm_ccfsm_state, arm_current_cc;
5208
5209 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5210 {
5211 arm_current_cc ^= 1;
5212 output_return_instruction (NULL, TRUE);
5213 arm_ccfsm_state = 0;
5214 arm_target_insn = NULL;
5215 }
5216
5217 output_return_instruction (NULL, FALSE);
40dbec34 5218 return \"b%?\\t%a0\";
9c08d1fa 5219}"
5220[(set (attr "conds")
5221 (if_then_else (eq_attr "cpu" "arm6")
5222 (const_string "clob")
5223 (const_string "nocond")))
094e994f 5224 (set_attr "length" "8")])
9c08d1fa 5225
5226(define_peephole
5227 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5228 (call (mem:SI (match_operand:SI 1 "" "i"))
5229 (match_operand:SI 2 "general_operand" "g")))
5230 (clobber (reg:SI 14))])
5231 (return)]
5232 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5233 && !get_frame_size () && !current_function_calls_alloca
5234 && !frame_pointer_needed && !current_function_args_size)"
5235 "*
5236{
5237 extern rtx arm_target_insn;
5238 extern int arm_ccfsm_state, arm_current_cc;
5239
5240 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5241 {
5242 arm_current_cc ^= 1;
5243 output_return_instruction (NULL, TRUE);
5244 arm_ccfsm_state = 0;
5245 arm_target_insn = NULL;
5246 }
5247
5248 output_return_instruction (NULL, FALSE);
40dbec34 5249 return \"b%?\\t%a1\";
9c08d1fa 5250}"
5251[(set (attr "conds")
5252 (if_then_else (eq_attr "cpu" "arm6")
5253 (const_string "clob")
5254 (const_string "nocond")))
094e994f 5255 (set_attr "length" "8")])
9c08d1fa 5256
5257;; As above but when this function is not void, we must be returning the
5258;; result of the called subroutine.
5259
5260(define_peephole
5261 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5262 (call (mem:SI (match_operand:SI 1 "" "i"))
5263 (match_operand:SI 2 "general_operand" "g")))
5264 (clobber (reg:SI 14))])
5265 (use (match_dup 0))
5266 (return)]
5267 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5268 && !get_frame_size () && !current_function_calls_alloca
5269 && !frame_pointer_needed && !current_function_args_size)"
5270 "*
5271{
5272 extern rtx arm_target_insn;
5273 extern int arm_ccfsm_state, arm_current_cc;
5274
5275 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5276 {
5277 arm_current_cc ^= 1;
5278 output_return_instruction (NULL, TRUE);
5279 arm_ccfsm_state = 0;
5280 arm_target_insn = NULL;
5281 }
5282
5283 output_return_instruction (NULL, FALSE);
40dbec34 5284 return \"b%?\\t%a1\";
9c08d1fa 5285}"
5286[(set (attr "conds")
5287 (if_then_else (eq_attr "cpu" "arm6")
5288 (const_string "clob")
5289 (const_string "nocond")))
094e994f 5290 (set_attr "length" "8")])
9c08d1fa 5291
5292;; If calling a subroutine and then jumping back to somewhere else, but not
5293;; too far away, then we can set the link register with the branch address
5294;; and jump direct to the subroutine. On return from the subroutine
5295;; execution continues at the branch; this avoids a prefetch stall.
5296;; We use the length attribute (via short_branch ()) to establish whether or
5297;; not this is possible, this is the same asthe sparc does.
5298
5299(define_peephole
5300 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5301 (match_operand:SI 1 "general_operand" "g"))
5302 (clobber (reg:SI 14))])
5303 (set (pc)
5304 (label_ref (match_operand 2 "" "")))]
048b40f1 5305 "0 && GET_CODE (operands[0]) == SYMBOL_REF
9c08d1fa 5306 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5307 && arm_insn_not_targeted (insn)"
5308 "*
5309{
5310 int backward = arm_backwards_branch (INSN_UID (insn),
5311 INSN_UID (operands[2]));
5312
5313#if 0
5314 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5315 * above, leaving it out means that the code will still run on an arm 2 or 3
5316 */
5317 if (TARGET_6)
5318 {
5319 if (backward)
899850b0 5320 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
9c08d1fa 5321 else
899850b0 5322 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
9c08d1fa 5323 }
5324 else
5325#endif
5326 {
899850b0 5327 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
9c08d1fa 5328 if (backward)
899850b0 5329 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
9c08d1fa 5330 else
899850b0 5331 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
9c08d1fa 5332 }
40dbec34 5333 return \"b%?\\t%a0\";
9c08d1fa 5334}"
5335[(set (attr "conds")
5336 (if_then_else (eq_attr "cpu" "arm6")
5337 (const_string "clob")
5338 (const_string "nocond")))
5339 (set (attr "length")
5340 (if_then_else (eq_attr "cpu" "arm6")
094e994f 5341 (const_int 8)
5342 (const_int 12)))])
9c08d1fa 5343
5344(define_peephole
5345 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5346 (call (mem:SI (match_operand:SI 1 "" "i"))
5347 (match_operand:SI 2 "general_operand" "g")))
5348 (clobber (reg:SI 14))])
5349 (set (pc)
5350 (label_ref (match_operand 3 "" "")))]
048b40f1 5351 "0 && GET_CODE (operands[0]) == SYMBOL_REF
9c08d1fa 5352 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5353 && arm_insn_not_targeted (insn)"
5354 "*
5355{
5356 int backward = arm_backwards_branch (INSN_UID (insn),
5357 INSN_UID (operands[3]));
5358
5359#if 0
5360 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5361 * above, leaving it out means that the code will still run on an arm 2 or 3
5362 */
5363 if (TARGET_6)
5364 {
5365 if (backward)
899850b0 5366 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
9c08d1fa 5367 else
899850b0 5368 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
9c08d1fa 5369 }
5370 else
5371#endif
5372 {
899850b0 5373 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
9c08d1fa 5374 if (backward)
899850b0 5375 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
9c08d1fa 5376 else
899850b0 5377 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
9c08d1fa 5378 }
40dbec34 5379 return \"b%?\\t%a1\";
9c08d1fa 5380}"
5381[(set (attr "conds")
5382 (if_then_else (eq_attr "cpu" "arm6")
5383 (const_string "clob")
5384 (const_string "nocond")))
5385 (set (attr "length")
5386 (if_then_else (eq_attr "cpu" "arm6")
094e994f 5387 (const_int 8)
5388 (const_int 12)))])
9c08d1fa 5389
5390(define_split
5391 [(set (pc)
5392 (if_then_else (match_operator 0 "comparison_operator"
5393 [(match_operator:SI 1 "shift_operator"
5394 [(match_operand:SI 2 "s_register_operand" "r")
87b22bf7 5395 (match_operand:SI 3 "reg_or_int_operand" "rM")])
9c08d1fa 5396 (match_operand:SI 4 "s_register_operand" "r")])
5397 (label_ref (match_operand 5 "" ""))
5398 (pc)))
5399 (clobber (reg 24))]
5400 ""
5401 [(set (reg:CC 24)
5402 (compare:CC (match_dup 4)
5403 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5404 (set (pc)
5405 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5406 (label_ref (match_dup 5))
5407 (pc)))]
5408 "
5409 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5410 operands[1], operands[2]);
5411")
5412
5413(define_split
5414 [(set (match_operand:SI 0 "s_register_operand" "")
5415 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5416 (const_int 0))
5417 (neg:SI (match_operator:SI 2 "comparison_operator"
5418 [(match_operand:SI 3 "s_register_operand" "")
5419 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5420 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5421 ""
5422 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5423 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5424 (match_dup 5)))]
5425 "")
5426
5427;; This pattern can be used because cc_noov mode implies that the following
5428;; branch will be an equality (EQ or NE), so the sign extension is not
5429;; needed. Combine doesn't eliminate these because by the time it sees the
5430;; branch it no-longer knows that the data came from memory.
5431
5432(define_insn ""
5433 [(set (reg:CC_NOOV 24)
5434 (compare:CC_NOOV
5435 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5436 (const_int 24))
5437 (match_operand 1 "immediate_operand" "I")))
5438 (clobber (match_scratch:SI 2 "=r"))]
5439 "((unsigned long) INTVAL (operands[1]))
5440 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5441 "*
5442 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
40dbec34 5443 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5444 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
e2348bcb 5445 return \"\";
9c08d1fa 5446"
5447[(set_attr "conds" "set")
094e994f 5448 (set_attr "length" "8")
9c08d1fa 5449 (set_attr "type" "load")])
5450
87b22bf7 5451(define_expand "prologue"
5452 [(clobber (const_int 0))]
5453 ""
5454 "
5455 arm_expand_prologue ();
5456 DONE;
5457")
5458
9c08d1fa 5459;; This split is only used during output to reduce the number of patterns
5460;; that need assembler instructions adding to them. We allowed the setting
5461;; of the conditions to be implicit during rtl generation so that
5462;; the conditional compare patterns would work. However this conflicts to
5463;; some extend with the conditional data operations, so we have to split them
5464;; up again here.
5465
5466(define_split
5467 [(set (match_operand:SI 0 "s_register_operand" "")
5468 (if_then_else:SI (match_operator 1 "comparison_operator"
5469 [(match_operand 2 "" "") (match_operand 3 "" "")])
5470 (match_operand 4 "" "")
5471 (match_operand 5 "" "")))
5472 (clobber (reg 24))]
5473 "reload_completed"
5474 [(set (match_dup 6) (match_dup 7))
5475 (set (match_dup 0)
5476 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5477 (match_dup 4)
5478 (match_dup 5)))]
5479 "
5480{
5481 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5482 operands[3]);
5483
5484 operands[6] = gen_rtx (REG, mode, 24);
5485 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5486}
5487")
5488
5489
5490(define_insn ""
5491 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5492 (if_then_else:SI (match_operator 4 "comparison_operator"
4d61e570 5493 [(match_operand 3 "reversible_cc_register" "")
5494 (const_int 0)])
9c08d1fa 5495 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5496 (not:SI
5497 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5498 ""
e2348bcb 5499 "@
899850b0 5500 mvn%D4\\t%0, %2
5501 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
9c08d1fa 5502[(set_attr "conds" "use")
094e994f 5503 (set_attr "length" "4,8")])
9c08d1fa 5504
5505;; The next two patterns occur when an AND operation is followed by a
5506;; scc insn sequence
5507
5508(define_insn ""
5509 [(set (match_operand:SI 0 "s_register_operand" "=r")
5510 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5511 (const_int 1)
5512 (match_operand:SI 2 "immediate_operand" "n")))]
5513 ""
5514 "*
5515 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
e2348bcb 5516 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5517 return \"mvnne\\t%0, #0\";
9c08d1fa 5518"
5519[(set_attr "conds" "clob")
094e994f 5520 (set_attr "length" "8")])
9c08d1fa 5521
5522(define_insn ""
5523 [(set (match_operand:SI 0 "s_register_operand" "=r")
5524 (not:SI
5525 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5526 (const_int 1)
5527 (match_operand:SI 2 "immediate_operand" "n"))))]
5528 ""
5529 "*
5530 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
e2348bcb 5531 output_asm_insn (\"tst\\t%1, %2\", operands);
5532 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5533 return \"movne\\t%0, #0\";
9c08d1fa 5534"
5535[(set_attr "conds" "clob")
094e994f 5536 (set_attr "length" "12")])
87b22bf7 5537
5538;; Push multiple registers to the stack. The first register is in the
5539;; unspec part of the insn; subsequent registers are in parallel (use ...)
5540;; expressions.
5541(define_insn ""
5542 [(match_parallel 2 "multi_register_push"
5543 [(set (match_operand:BLK 0 "memory_operand" "=m")
5544 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5545 ""
5546 "*
5547{
5548 char pattern[100];
5549 int i;
5550 extern int lr_save_eliminated;
5551
5552 if (lr_save_eliminated)
5553 {
5554 if (XVECLEN (operands[2], 0) > 1)
5555 abort ();
5556 return \"\";
5557 }
5558 strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5559 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5560 {
5561 strcat (pattern, \", %|\");
5562 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5563 0))]);
5564 }
5565 strcat (pattern, \"}\");
5566 output_asm_insn (pattern, operands);
5567 return \"\";
5568}"
5569[(set_attr "type" "store4")])