]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
Change FSF address.
[thirdparty/gcc.git] / gcc / config / arm / arm.md
CommitLineData
3d91c5d6 1;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
f61cee18 2;; Copyright (C) 1991, 1993, 1994, 1995 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
01cc3b75 57; NOCOND means that the condition codes are neither altered nor affect the
9c08d1fa 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")))]
9a1112d7 358 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 368 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 379 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 390 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 400 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 408 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 547 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 557 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 568 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 577 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 589 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 597 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 679 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 687 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 696 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 705 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 715 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 723 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 733 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 743 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 754 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 763 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 773 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 781 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 793 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 801 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 810 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 819 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 829 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 837 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1466 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1473 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 1481 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1488 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1522 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1529 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 1537 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1544 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1551 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1558 "TARGET_HARD_FLOAT"
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"))))]
9a1112d7 1566 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1573 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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))]
9a1112d7 1580 "TARGET_HARD_FLOAT"
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))]
9a1112d7 1587 "TARGET_HARD_FLOAT"
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))]
9a1112d7 1595 "TARGET_HARD_FLOAT"
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))]
9a1112d7 1602 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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))]
9a1112d7 1609 "TARGET_HARD_FLOAT"
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))]
9a1112d7 1616 "TARGET_HARD_FLOAT"
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))]
9a1112d7 1624 "TARGET_HARD_FLOAT"
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))]
9a1112d7 1631 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1672 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1679 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1686 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1693 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1700 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1707 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1717 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1725 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1733 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1904 "TARGET_HARD_FLOAT"
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")))]
9a1112d7 1911 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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")))]
9a1112d7 1918 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
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)))
17ea8270 2074 (set_attr "type" "load,load,*,*,store1,*,*")])
87b22bf7 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
01cc3b75 2107;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 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
f1a6e148 2412 && (TARGET_SOFT_FLOAT
2413 || (GET_CODE (operands[0]) == REG
2414 && REGNO (operands[0]) < 16)
87b22bf7 2415 || ! (const_double_rtx_ok_for_fpu (operands[1])
2416 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2417 {
2418 extern int optimize;
2419 rtx mem = force_const_mem (SFmode, operands[1]);
3ab84030 2420 rtx addr;
2421
2422 if (reload_in_progress || reload_completed)
2423 addr = gen_rtx (REG, SImode, REGNO (operands[0]));
2424 else
2425 addr = gen_reg_rtx (SImode);
87b22bf7 2426 if (optimize == 0)
2427 {
2428 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2429 emit_insn (gen_movsi (addr, ptr));
2430 }
2431 else
2432 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2433 operands[1] = gen_rtx (MEM, SFmode, addr);
2434 }
2435 if (GET_CODE (operands[0]) == MEM)
2436 operands[1] = force_reg (SFmode, operands[1]);
2437")
2438
2439(define_insn ""
9c08d1fa 2440 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2441 (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
9a1112d7 2442 "TARGET_HARD_FLOAT
2443 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
5565501b 2444 "@
2445 mvf%?s\\t%0, %1
2446 mnf%?s\\t%0, #%N1
2447 ldf%?s\\t%0, %1
2448 stf%?s\\t%1, %0
899850b0 2449 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2450 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
5565501b 2451 mov%?\\t%0, %1
2452 ldr%?\\t%0, %1\\t%@ float
2453 str%?\\t%1, %0\\t%@ float"
094e994f 2454[(set_attr "length" "4,4,4,4,8,8,4,4,4")
3d91c5d6 2455 (set_attr "type"
2456 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
9c08d1fa 2457
9a1112d7 2458;; Exactly the same as above, except that all `f' cases are deleted.
2459;; This is necessary to prevent reload from ever trying to use a `f' reg
2460;; when -msoft-float.
2461
2462(define_insn "*movsf_soft_insn"
2463 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
2464 (match_operand:SF 1 "general_operand" "r,m,r"))]
2465 "TARGET_SOFT_FLOAT
2466 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
2467 "@
2468 mov%?\\t%0, %1
2469 ldr%?\\t%0, %1\\t%@ float
2470 str%?\\t%1, %0\\t%@ float"
2471[(set_attr "length" "4,4,4")
2472 (set_attr "type" "*,load,store1")])
2473
9c08d1fa 2474(define_expand "movdf"
87b22bf7 2475 [(set (match_operand:DF 0 "general_operand" "")
2476 (match_operand:DF 1 "general_operand" ""))]
9c08d1fa 2477 ""
2478 "
87b22bf7 2479 if (GET_CODE (operands[1]) == CONST_DOUBLE
f1a6e148 2480 && (TARGET_SOFT_FLOAT
2481 || (GET_CODE (operands[0]) == REG
2482 && REGNO (operands[0]) < 16)
87b22bf7 2483 || ! (const_double_rtx_ok_for_fpu (operands[1])
2484 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2485 {
2486 extern int optimize;
2487 rtx mem = force_const_mem (DFmode, operands[1]);
3ab84030 2488 rtx addr;
2489
2490 if (reload_in_progress || reload_completed)
2491 addr = gen_rtx (REG, SImode, REGNO (operands[0]));
2492 else
2493 addr = gen_reg_rtx (SImode);
87b22bf7 2494 if (optimize == 0)
2495 {
2496 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2497 emit_insn (gen_movsi (addr, ptr));
2498 }
2499 else
2500 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2501 operands[1] = gen_rtx (MEM, DFmode, addr);
2502 }
9c08d1fa 2503 if (GET_CODE (operands[0]) == MEM)
2504 operands[1] = force_reg (DFmode, operands[1]);
b11cae9e 2505")
2506
9c08d1fa 2507;; Reloading a df mode value stored in integer regs to memory can require a
2508;; scratch reg.
2509(define_expand "reload_outdf"
87b22bf7 2510 [(match_operand:DF 0 "reload_memory_operand" "=o")
2511 (match_operand:DF 1 "s_register_operand" "r")
2512 (match_operand:SI 2 "s_register_operand" "=&r")]
b11cae9e 2513 ""
87b22bf7 2514 "
443a31dc 2515 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2516 operands[2] = XEXP (operands[0], 0);
2517 else
2518 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2519 XEXP (XEXP (operands[0], 0), 1)));
87b22bf7 2520 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2521 operands[1]));
2522 DONE;
2523")
9c08d1fa 2524
2525(define_insn ""
87b22bf7 2526 [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
9c08d1fa 2527 (match_operand:DF 1 "general_operand"
87b22bf7 2528 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
9a1112d7 2529 "TARGET_HARD_FLOAT
2530 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode))"
9c08d1fa 2531 "*
2532{
9c08d1fa 2533 rtx ops[3];
2534
2535 switch (which_alternative)
2536 {
2537 case 0:
40dbec34 2538 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
e2348bcb 2539
9c08d1fa 2540 case 1:
40dbec34 2541 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
e2348bcb 2542
9c08d1fa 2543 case 2:
2544 ops[0] = operands[0];
2545 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2546 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2547 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
40dbec34 2548 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
9c08d1fa 2549 else
40dbec34 2550 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2551 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
9c08d1fa 2552
e2348bcb 2553 case 3:
9c08d1fa 2554 case 4:
40dbec34 2555 return \"mvf%?d\\t%0, %1\";
e2348bcb 2556
87b22bf7 2557 case 5: return \"mnf%?d\\t%0, #%N1\";
2558 case 6: return \"ldf%?d\\t%0, %1\";
2559 case 7: return \"stf%?d\\t%1, %0\";
2560 case 8: return output_mov_double_fpu_from_arm (operands);
2561 case 9: return output_mov_double_arm_from_fpu (operands);
2562 case 10: return output_move_double (operands);
9c08d1fa 2563 }
2564}
2565"
87b22bf7 2566[(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
9c08d1fa 2567 (set_attr "type"
3d91c5d6 2568"load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
9c08d1fa 2569
39b5e676 2570;; Software floating point version. This is essentially the same as movdi.
2571;; Do not use `f' as a constraint to prevent reload from ever trying to use
2572;; an `f' reg.
9a1112d7 2573
2574(define_insn "*movdf_soft_insn"
39b5e676 2575 [(set (match_operand:DF 0 "soft_df_operand" "=r,r,o<>,r")
2576 (match_operand:DF 1 "soft_df_operand" "r,o<>,r,F"))]
2577 "TARGET_SOFT_FLOAT"
2578 "* return output_move_double (operands);"
2579[(set_attr "length" "8,8,8,32")
2580 (set_attr "type" "*,load,store2,*")])
9a1112d7 2581
87b22bf7 2582(define_expand "movxf"
2583 [(set (match_operand:XF 0 "general_operand" "")
2584 (match_operand:XF 1 "general_operand" ""))]
9a1112d7 2585 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
87b22bf7 2586 "")
2587
2588;; Even when the XFmode patterns aren't enabled, we enable this after
2589;; reloading so that we can push floating point registers in the prologue.
2590
2591(define_insn ""
9c08d1fa 2592 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2593 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
9a1112d7 2594 "TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
b11cae9e 2595 "*
2596 switch (which_alternative)
2597 {
40dbec34 2598 case 0: return \"mvf%?e\\t%0, %1\";
5565501b 2599 case 1: return \"mnf%?e\\t%0, #%N1\";
40dbec34 2600 case 2: return \"ldf%?e\\t%0, %1\";
2601 case 3: return \"stf%?e\\t%1, %0\";
9c08d1fa 2602 case 4: return output_mov_long_double_fpu_from_arm (operands);
2603 case 5: return output_mov_long_double_arm_from_fpu (operands);
2604 case 6: return output_mov_long_double_arm_from_arm (operands);
b11cae9e 2605 }
9c08d1fa 2606"
094e994f 2607[(set_attr "length" "4,4,4,4,8,8,12")
3d91c5d6 2608 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
b11cae9e 2609\f
b11cae9e 2610
9c08d1fa 2611;; load- and store-multiple insns
2612;; The arm can load/store any set of registers, provided that they are in
2613;; ascending order; but that is beyond GCC so stick with what it knows.
b11cae9e 2614
9c08d1fa 2615(define_expand "load_multiple"
2616 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2617 (match_operand:SI 1 "" ""))
2618 (use (match_operand:SI 2 "" ""))])]
b11cae9e 2619 ""
9c08d1fa 2620 "
2621 /* Support only fixed point registers */
2622 if (GET_CODE (operands[2]) != CONST_INT
2623 || INTVAL (operands[2]) > 14
2624 || INTVAL (operands[2]) < 2
2625 || GET_CODE (operands[1]) != MEM
2626 || GET_CODE (operands[0]) != REG
2627 || REGNO (operands[0]) > 14
2628 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2629 FAIL;
2630
2631 operands[3]
2632 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2633 force_reg (SImode, XEXP (operands[1], 0)),
2634 TRUE, FALSE);
b11cae9e 2635")
2636
9c08d1fa 2637;; Load multiple with write-back
2638
b11cae9e 2639(define_insn ""
9c08d1fa 2640 [(match_parallel 0 "load_multiple_operation"
2641 [(set (match_operand:SI 1 "s_register_operand" "+r")
2642 (plus:SI (match_dup 1)
2643 (match_operand:SI 2 "immediate_operand" "n")))
2644 (set (match_operand:SI 3 "s_register_operand" "=r")
2645 (mem:SI (match_dup 1)))])]
2646 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
b11cae9e 2647 "*
9c08d1fa 2648{
2649 rtx ops[3];
2650 int count = XVECLEN (operands[0], 0);
b11cae9e 2651
9c08d1fa 2652 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2653 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2654 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
b11cae9e 2655
40dbec34 2656 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
e2348bcb 2657 return \"\";
9c08d1fa 2658}
2659"
2660[(set_attr "type" "load")])
b11cae9e 2661
9c08d1fa 2662;; Ordinary load multiple
b11cae9e 2663
9c08d1fa 2664(define_insn ""
2665 [(match_parallel 0 "load_multiple_operation"
2666 [(set (match_operand:SI 1 "s_register_operand" "=r")
2667 (match_operand:SI 2 "indirect_operand" "Q"))])]
b11cae9e 2668 ""
2669 "*
9c08d1fa 2670{
2671 rtx ops[3];
2672 int count = XVECLEN (operands[0], 0);
2673
2674 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2675 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2676 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2677
40dbec34 2678 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
e2348bcb 2679 return \"\";
9c08d1fa 2680}
2681"
2682[(set_attr "type" "load")])
2683
2684(define_expand "store_multiple"
2685 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2686 (match_operand:SI 1 "" ""))
2687 (use (match_operand:SI 2 "" ""))])]
b11cae9e 2688 ""
9c08d1fa 2689 "
2690 /* Support only fixed point registers */
2691 if (GET_CODE (operands[2]) != CONST_INT
2692 || INTVAL (operands[2]) > 14
2693 || INTVAL (operands[2]) < 2
2694 || GET_CODE (operands[1]) != REG
2695 || GET_CODE (operands[0]) != MEM
2696 || REGNO (operands[1]) > 14
2697 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2698 FAIL;
2699
2700 operands[3]
2701 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2702 force_reg (SImode, XEXP (operands[0], 0)),
2703 TRUE, FALSE);
b11cae9e 2704")
2705
9c08d1fa 2706;; Store multiple with write-back
2707
2708(define_insn ""
2709 [(match_parallel 0 "store_multiple_operation"
2710 [(set (match_operand:SI 1 "s_register_operand" "+r")
2711 (plus:SI (match_dup 1)
2712 (match_operand:SI 2 "immediate_operand" "n")))
2713 (set (mem:SI (match_dup 1))
2714 (match_operand:SI 3 "s_register_operand" "r"))])]
2715 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
b11cae9e 2716 "*
9c08d1fa 2717{
2718 rtx ops[3];
2719 int count = XVECLEN (operands[0], 0);
b11cae9e 2720
9c08d1fa 2721 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2722 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2723 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2724
40dbec34 2725 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
e2348bcb 2726 return \"\";
9c08d1fa 2727}
2728"
2729[(set (attr "type")
2730 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2731 (const_string "store2")
2732 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2733 (const_string "store3")]
2734 (const_string "store4")))])
2735
2736;; Ordinary store multiple
2737
2738(define_insn ""
2739 [(match_parallel 0 "store_multiple_operation"
2740 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2741 (match_operand:SI 1 "s_register_operand" "r"))])]
b11cae9e 2742 ""
2743 "*
9c08d1fa 2744{
2745 rtx ops[3];
2746 int count = XVECLEN (operands[0], 0);
2747
2748 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2749 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2750 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2751
40dbec34 2752 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
e2348bcb 2753 return \"\";
9c08d1fa 2754}
2755"
2756[(set (attr "type")
2757 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2758 (const_string "store2")
2759 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2760 (const_string "store3")]
2761 (const_string "store4")))])
2762
2763;; Move a block of memory if it is word aligned and MORE than 2 words long.
2764;; We could let this apply for blocks of less than this, but it clobbers so
2765;; many registers that there is then probably a better way.
2766
34191dd1 2767(define_expand "movstrqi"
2768 [(match_operand:BLK 0 "general_operand" "")
2769 (match_operand:BLK 1 "general_operand" "")
2770 (match_operand:SI 2 "const_int_operand" "")
2771 (match_operand:SI 3 "const_int_operand" "")]
9c08d1fa 2772 ""
2773 "
34191dd1 2774 if (arm_gen_movstrqi (operands))
2775 DONE;
2776 FAIL;
b11cae9e 2777")
9c08d1fa 2778\f
b11cae9e 2779
9c08d1fa 2780;; Comparison and test insns
2781
2782(define_expand "cmpsi"
2783 [(set (reg:CC 24)
2784 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2785 (match_operand:SI 1 "arm_add_operand" "")))]
b11cae9e 2786 ""
9c08d1fa 2787 "
2788{
2789 arm_compare_op0 = operands[0];
2790 arm_compare_op1 = operands[1];
2791 arm_compare_fp = 0;
2792 DONE;
2793}
b11cae9e 2794")
2795
9c08d1fa 2796(define_expand "cmpsf"
2797 [(set (reg:CC 24)
2798 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2799 (match_operand:SF 1 "fpu_rhs_operand" "")))]
9a1112d7 2800 "TARGET_HARD_FLOAT"
9c08d1fa 2801 "
2802{
2803 arm_compare_op0 = operands[0];
2804 arm_compare_op1 = operands[1];
2805 arm_compare_fp = 1;
2806 DONE;
2807}
b11cae9e 2808")
2809
9c08d1fa 2810(define_expand "cmpdf"
2811 [(set (reg:CC 24)
2812 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2813 (match_operand:DF 1 "fpu_rhs_operand" "")))]
9a1112d7 2814 "TARGET_HARD_FLOAT"
9c08d1fa 2815 "
2816{
2817 arm_compare_op0 = operands[0];
2818 arm_compare_op1 = operands[1];
2819 arm_compare_fp = 1;
2820 DONE;
2821}
b11cae9e 2822")
2823
9c08d1fa 2824(define_expand "cmpxf"
2825 [(set (reg:CC 24)
2826 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2827 (match_operand:XF 1 "fpu_rhs_operand" "")))]
9a1112d7 2828 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
9c08d1fa 2829 "
2830{
2831 arm_compare_op0 = operands[0];
2832 arm_compare_op1 = operands[1];
2833 arm_compare_fp = 1;
2834 DONE;
2835}
b11cae9e 2836")
2837
9c08d1fa 2838(define_insn ""
2839 [(set (match_operand 0 "cc_register" "")
5565501b 2840 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2841 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
b11cae9e 2842 ""
5565501b 2843 "@
2844 cmp%?\\t%1, %2
2845 cmn%?\\t%1, #%n2"
9c08d1fa 2846[(set_attr "conds" "set")])
b11cae9e 2847
2848(define_insn ""
9c08d1fa 2849 [(set (match_operand 0 "cc_register" "")
2850 (compare (match_operand:SI 1 "s_register_operand" "r")
2851 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
b11cae9e 2852 ""
40dbec34 2853 "cmn%?\\t%1, %2"
9c08d1fa 2854[(set_attr "conds" "set")])
b11cae9e 2855
2856(define_insn ""
9c08d1fa 2857 [(set (match_operand 0 "cc_register" "")
2858 (compare (match_operand:SI 1 "s_register_operand" "r")
2859 (match_operator:SI 2 "shift_operator"
2860 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 2861 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
b11cae9e 2862 ""
87b22bf7 2863 "cmp%?\\t%1, %3%S2"
9c08d1fa 2864[(set_attr "conds" "set")])
b11cae9e 2865
2866(define_insn ""
9c08d1fa 2867 [(set (match_operand 0 "cc_register" "")
2868 (compare (match_operand:SI 1 "s_register_operand" "r")
2869 (neg:SI (match_operator:SI 2 "shift_operator"
2870 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 2871 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
b11cae9e 2872 ""
87b22bf7 2873 "cmn%?\\t%1, %3%S2"
9c08d1fa 2874[(set_attr "conds" "set")])
b11cae9e 2875
2876(define_insn ""
9c08d1fa 2877 [(set (reg:CCFP 24)
2878 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2879 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2880 "TARGET_HARD_FLOAT"
5565501b 2881 "@
2882 cmf%?\\t%0, %1
2883 cnf%?\\t%0, #%N1"
9c08d1fa 2884[(set_attr "conds" "set")
2885 (set_attr "type" "f_2_r")])
b11cae9e 2886
2887(define_insn ""
9c08d1fa 2888 [(set (reg:CCFP 24)
2889 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2890 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2891 "TARGET_HARD_FLOAT"
5565501b 2892 "@
2893 cmf%?\\t%0, %1
2894 cnf%?\\t%0, #%N1"
9c08d1fa 2895[(set_attr "conds" "set")
2896 (set_attr "type" "f_2_r")])
b11cae9e 2897
2898(define_insn ""
9c08d1fa 2899 [(set (reg:CCFP 24)
2900 (compare:CCFP (float_extend:DF
2901 (match_operand:SF 0 "s_register_operand" "f,f"))
2902 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2903 "TARGET_HARD_FLOAT"
5565501b 2904 "@
2905 cmf%?\\t%0, %1
2906 cnf%?\\t%0, #%N1"
9c08d1fa 2907[(set_attr "conds" "set")
2908 (set_attr "type" "f_2_r")])
b11cae9e 2909
2910(define_insn ""
9c08d1fa 2911 [(set (reg:CCFP 24)
2912 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2913 (float_extend:DF
2914 (match_operand:SF 1 "s_register_operand" "f"))))]
9a1112d7 2915 "TARGET_HARD_FLOAT"
40dbec34 2916 "cmf%?\\t%0, %1"
9c08d1fa 2917[(set_attr "conds" "set")
2918 (set_attr "type" "f_2_r")])
b11cae9e 2919
2920(define_insn ""
9c08d1fa 2921 [(set (reg:CCFP 24)
2922 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2923 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2924 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
5565501b 2925 "@
2926 cmf%?\\t%0, %1
2927 cnf%?\\t%0, #%N1"
9c08d1fa 2928[(set_attr "conds" "set")
2929 (set_attr "type" "f_2_r")])
b11cae9e 2930
2931(define_insn ""
9c08d1fa 2932 [(set (reg:CCFPE 24)
2933 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2934 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2935 "TARGET_HARD_FLOAT"
5565501b 2936 "@
4d61e570 2937 cmf%?e\\t%0, %1
2938 cnf%?e\\t%0, #%N1"
9c08d1fa 2939[(set_attr "conds" "set")
2940 (set_attr "type" "f_2_r")])
b11cae9e 2941
9c08d1fa 2942(define_insn ""
2943 [(set (reg:CCFPE 24)
2944 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2945 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2946 "TARGET_HARD_FLOAT"
5565501b 2947 "@
2948 cmf%?e\\t%0, %1
2949 cnf%?e\\t%0, #%N1"
9c08d1fa 2950[(set_attr "conds" "set")
2951 (set_attr "type" "f_2_r")])
2952
2953(define_insn ""
2954 [(set (reg:CCFPE 24)
2955 (compare:CCFPE (float_extend:DF
2956 (match_operand:SF 0 "s_register_operand" "f,f"))
2957 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2958 "TARGET_HARD_FLOAT"
5565501b 2959 "@
2960 cmf%?e\\t%0, %1
2961 cnf%?e\\t%0, #%N1"
9c08d1fa 2962[(set_attr "conds" "set")
2963 (set_attr "type" "f_2_r")])
b11cae9e 2964
2965(define_insn ""
9c08d1fa 2966 [(set (reg:CCFPE 24)
2967 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2968 (float_extend:DF
2969 (match_operand:SF 1 "s_register_operand" "f"))))]
9a1112d7 2970 "TARGET_HARD_FLOAT"
40dbec34 2971 "cmf%?e\\t%0, %1"
9c08d1fa 2972[(set_attr "conds" "set")
2973 (set_attr "type" "f_2_r")])
b11cae9e 2974
2975(define_insn ""
9c08d1fa 2976 [(set (reg:CCFPE 24)
2977 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2978 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
9a1112d7 2979 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
5565501b 2980 "@
2981 cmf%?e\\t%0, %1
2982 cnf%?e\\t%0, #%N1"
9c08d1fa 2983[(set_attr "conds" "set")
2984 (set_attr "type" "f_2_r")])
5c951228 2985
9c08d1fa 2986; This insn allows redundant compares to be removed by cse, nothing should
2987; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2988; is deleted later on. The match_dup will match the mode here, so that
2989; mode changes of the condition codes aren't lost by this even though we don't
2990; specify what they are.
2991
2992(define_insn ""
2993 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2994 ""
40dbec34 2995 "\\t%@ deleted compare"
9c08d1fa 2996[(set_attr "conds" "set")
2997 (set_attr "length" "0")])
2998
2999\f
3000;; Conditional branch insns
3001
3002(define_expand "beq"
3003 [(set (pc)
3004 (if_then_else (eq (match_dup 1) (const_int 0))
3005 (label_ref (match_operand 0 "" ""))
3006 (pc)))]
5c951228 3007 ""
3008 "
3009{
9c08d1fa 3010 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3011 arm_compare_fp);
3012}
3013")
5c951228 3014
9c08d1fa 3015(define_expand "bne"
3016 [(set (pc)
3017 (if_then_else (ne (match_dup 1) (const_int 0))
3018 (label_ref (match_operand 0 "" ""))
3019 (pc)))]
3020 ""
3021 "
3022{
3023 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3024 arm_compare_fp);
3025}
3026")
5c951228 3027
9c08d1fa 3028(define_expand "bgt"
3029 [(set (pc)
3030 (if_then_else (gt (match_dup 1) (const_int 0))
3031 (label_ref (match_operand 0 "" ""))
3032 (pc)))]
3033 ""
3034 "
3035{
3036 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3037 arm_compare_fp);
3038}
3039")
5c951228 3040
9c08d1fa 3041(define_expand "ble"
3042 [(set (pc)
3043 (if_then_else (le (match_dup 1) (const_int 0))
3044 (label_ref (match_operand 0 "" ""))
3045 (pc)))]
3046 ""
3047 "
3048{
3049 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3050 arm_compare_fp);
3051}
3052")
5c951228 3053
9c08d1fa 3054(define_expand "bge"
3055 [(set (pc)
3056 (if_then_else (ge (match_dup 1) (const_int 0))
3057 (label_ref (match_operand 0 "" ""))
3058 (pc)))]
3059 ""
3060 "
3061{
3062 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3063 arm_compare_fp);
3064}
3065")
5c951228 3066
9c08d1fa 3067(define_expand "blt"
3068 [(set (pc)
3069 (if_then_else (lt (match_dup 1) (const_int 0))
3070 (label_ref (match_operand 0 "" ""))
3071 (pc)))]
3072 ""
3073 "
3074{
3075 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3076 arm_compare_fp);
3077}
3078")
5c951228 3079
9c08d1fa 3080(define_expand "bgtu"
3081 [(set (pc)
3082 (if_then_else (gtu (match_dup 1) (const_int 0))
3083 (label_ref (match_operand 0 "" ""))
3084 (pc)))]
5c951228 3085 ""
9c08d1fa 3086 "
3087{
3088 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3089 arm_compare_fp);
3090}
3091")
5c951228 3092
9c08d1fa 3093(define_expand "bleu"
b11cae9e 3094 [(set (pc)
9c08d1fa 3095 (if_then_else (leu (match_dup 1) (const_int 0))
3096 (label_ref (match_operand 0 "" ""))
3097 (pc)))]
b11cae9e 3098 ""
9c08d1fa 3099 "
3100{
3101 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3102 arm_compare_fp);
3103}
b11cae9e 3104")
3105
9c08d1fa 3106(define_expand "bgeu"
b11cae9e 3107 [(set (pc)
9c08d1fa 3108 (if_then_else (geu (match_dup 1) (const_int 0))
3109 (label_ref (match_operand 0 "" ""))
3110 (pc)))]
b11cae9e 3111 ""
9c08d1fa 3112 "
3113{
3114 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3115 arm_compare_fp);
3116}
b11cae9e 3117")
b11cae9e 3118
9c08d1fa 3119(define_expand "bltu"
3120 [(set (pc)
3121 (if_then_else (ltu (match_dup 1) (const_int 0))
3122 (label_ref (match_operand 0 "" ""))
3123 (pc)))]
b11cae9e 3124 ""
9c08d1fa 3125 "
3126{
3127 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3128 arm_compare_fp);
3129}
b11cae9e 3130")
b11cae9e 3131
9c08d1fa 3132;; patterns to match conditional branch insns
3133
3134(define_insn ""
3135 [(set (pc)
3136 (if_then_else (match_operator 1 "comparison_operator"
3137 [(reg 24) (const_int 0)])
3138 (label_ref (match_operand 0 "" ""))
3139 (pc)))]
d75350ce 3140 ""
3141 "*
9c08d1fa 3142{
3143 extern int arm_ccfsm_state;
d75350ce 3144
9c08d1fa 3145 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3146 {
3147 arm_ccfsm_state += 2;
3148 return \"\";
3149 }
e2348bcb 3150 return \"b%d1\\t%l0\";
9c08d1fa 3151}"
3152[(set_attr "conds" "use")])
d75350ce 3153
3154(define_insn ""
9c08d1fa 3155 [(set (pc)
3156 (if_then_else (match_operator 1 "comparison_operator"
3157 [(reg 24) (const_int 0)])
3158 (pc)
3159 (label_ref (match_operand 0 "" ""))))]
87b22bf7 3160 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
d75350ce 3161 "*
3162{
9c08d1fa 3163 extern int arm_ccfsm_state;
3164
3165 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3166 {
3167 arm_ccfsm_state += 2;
3168 return \"\";
3169 }
e2348bcb 3170 return \"b%D1\\t%l0\";
9c08d1fa 3171}"
3172[(set_attr "conds" "use")])
b11cae9e 3173\f
9c08d1fa 3174
3175; scc insns
3176
3177(define_expand "seq"
3178 [(set (match_operand:SI 0 "s_register_operand" "=r")
3179 (eq:SI (match_dup 1) (const_int 0)))]
3180 ""
3181 "
3182{
3183 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3184 arm_compare_fp);
3185}
3186")
3187
3188(define_expand "sne"
3189 [(set (match_operand:SI 0 "s_register_operand" "=r")
3190 (ne:SI (match_dup 1) (const_int 0)))]
3191 ""
3192 "
3193{
3194 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3195 arm_compare_fp);
3196}
3197")
3198
3199(define_expand "sgt"
3200 [(set (match_operand:SI 0 "s_register_operand" "=r")
3201 (gt:SI (match_dup 1) (const_int 0)))]
3202 ""
3203 "
3204{
3205 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3206 arm_compare_fp);
3207}
3208")
3209
3210(define_expand "sle"
3211 [(set (match_operand:SI 0 "s_register_operand" "=r")
3212 (le:SI (match_dup 1) (const_int 0)))]
3213 ""
3214 "
3215{
3216 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3217 arm_compare_fp);
3218}
3219")
3220
3221(define_expand "sge"
3222 [(set (match_operand:SI 0 "s_register_operand" "=r")
3223 (ge:SI (match_dup 1) (const_int 0)))]
3224 ""
3225 "
3226{
3227 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3228 arm_compare_fp);
3229}
3230")
3231
3232(define_expand "slt"
3233 [(set (match_operand:SI 0 "s_register_operand" "=r")
3234 (lt:SI (match_dup 1) (const_int 0)))]
3235 ""
3236 "
3237{
3238 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3239 arm_compare_fp);
3240}
3241")
3242
3243(define_expand "sgtu"
3244 [(set (match_operand:SI 0 "s_register_operand" "=r")
3245 (gtu:SI (match_dup 1) (const_int 0)))]
3246 ""
3247 "
3248{
3249 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3250 arm_compare_fp);
3251}
3252")
3253
3254(define_expand "sleu"
3255 [(set (match_operand:SI 0 "s_register_operand" "=r")
3256 (leu:SI (match_dup 1) (const_int 0)))]
3257 ""
3258 "
3259{
3260 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3261 arm_compare_fp);
3262}
3263")
3264
3265(define_expand "sgeu"
3266 [(set (match_operand:SI 0 "s_register_operand" "=r")
3267 (geu:SI (match_dup 1) (const_int 0)))]
3268 ""
3269 "
3270{
3271 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3272 arm_compare_fp);
3273}
3274")
3275
3276(define_expand "sltu"
3277 [(set (match_operand:SI 0 "s_register_operand" "=r")
3278 (ltu:SI (match_dup 1) (const_int 0)))]
3279 ""
3280 "
3281{
3282 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3283 arm_compare_fp);
3284}
3285")
3286
3287(define_insn ""
3288 [(set (match_operand:SI 0 "s_register_operand" "=r")
3289 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3290 ""
4d61e570 3291 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
9c08d1fa 3292[(set_attr "conds" "use")
094e994f 3293 (set_attr "length" "8")])
9c08d1fa 3294
3295(define_insn ""
3296 [(set (match_operand:SI 0 "s_register_operand" "=r")
3297 (neg:SI (match_operator:SI 1 "comparison_operator"
3298 [(reg 24) (const_int 0)])))]
3299 ""
4d61e570 3300 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
9c08d1fa 3301[(set_attr "conds" "use")
094e994f 3302 (set_attr "length" "8")])
9c08d1fa 3303
3304(define_insn ""
3305 [(set (match_operand:SI 0 "s_register_operand" "=r")
3306 (not:SI (match_operator:SI 1 "comparison_operator"
3307 [(reg 24) (const_int 0)])))]
3308 ""
4d61e570 3309 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
9c08d1fa 3310[(set_attr "conds" "use")
094e994f 3311 (set_attr "length" "8")])
9c08d1fa 3312
3313\f
39b5e676 3314;; Conditional move insns
3315
3316(define_expand "movsicc"
3317 [(set (match_operand:SI 0 "register_operand" "")
3318 (if_then_else (match_operand 1 "comparison_operator" "")
3319 (match_operand:SI 2 "arm_not_operand" "")
3320 (match_operand:SI 3 "register_operand" "")))]
3321 ""
3322 "
3323{
3324 enum rtx_code code = GET_CODE (operands[1]);
3325 rtx ccreg = gen_rtx (REG,
3326 SELECT_CC_MODE (code, arm_compare_op0, arm_compare_op1),
3327 CC_REGNUM);
3328
3329 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3330}")
3331
3332(define_expand "movsfcc"
3333 [(set (match_operand:SF 0 "register_operand" "")
3334 (if_then_else (match_operand 1 "comparison_operator" "")
3335 (match_operand:SF 2 "nonmemory_operand" "")
3336 (match_operand:SF 3 "register_operand" "")))]
3337 ""
3338 "
3339{
3340 enum rtx_code code = GET_CODE (operands[1]);
3341 rtx ccreg = gen_rtx (REG,
3342 SELECT_CC_MODE (code, arm_compare_op0, arm_compare_op1),
3343 CC_REGNUM);
3344
3345 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3346}")
3347
3348(define_expand "movdfcc"
3349 [(set (match_operand:DF 0 "register_operand" "")
3350 (if_then_else (match_operand 1 "comparison_operator" "")
3351 (match_operand:DF 2 "nonmemory_operand" "")
3352 (match_operand:DF 3 "register_operand" "")))]
3353 "TARGET_HARD_FLOAT"
3354 "
3355{
3356 enum rtx_code code = GET_CODE (operands[1]);
3357 rtx ccreg = gen_rtx (REG,
3358 SELECT_CC_MODE (code, arm_compare_op0, arm_compare_op1),
3359 CC_REGNUM);
3360
3361 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3362}")
3363
3364(define_insn "*movsicc_insn"
3365 [(set (match_operand:SI 0 "register_operand" "=r,r")
3366 (if_then_else (match_operand 1 "comparison_operator" "")
3367 (match_operand:SI 2 "arm_not_operand" "rI,K")
3368 (match_operand:SI 3 "register_operand" "0,0")))]
3369 ""
3370 "@
3371 mov%d1\\t%0, %2
3372 mvn%d1\\t%0, #%B2"
3373 [(set_attr "type" "*,*")
3374 (set_attr "conds" "use,use")])
3375
3376(define_insn "*movsfcc_hard_insn"
3377 [(set (match_operand:SF 0 "register_operand" "=f")
3378 (if_then_else (match_operand 1 "comparison_operator" "")
3379 (match_operand:SF 2 "register_operand" "f")
3380 (match_operand:SF 3 "register_operand" "0")))]
3381 "TARGET_HARD_FLOAT"
3382 "mvf%d1s\\t%0, %2"
3383 [(set_attr "type" "ffarith")
3384 (set_attr "conds" "use")])
3385
3386(define_insn "*movsfcc_soft_insn"
3387 [(set (match_operand:SF 0 "register_operand" "=r")
3388 (if_then_else (match_operand 1 "comparison_operator" "")
3389 (match_operand:SF 2 "register_operand" "r")
3390 (match_operand:SF 3 "register_operand" "0")))]
3391 "TARGET_SOFT_FLOAT"
3392 "mov%d1\\t%0, %2"
3393 [(set_attr "type" "*")
3394 (set_attr "conds" "use")])
3395
3396(define_insn "*movdfcc_insn"
3397 [(set (match_operand:DF 0 "register_operand" "=f")
3398 (if_then_else (match_operand 1 "comparison_operator" "")
3399 (match_operand:DF 2 "register_operand" "f")
3400 (match_operand:DF 3 "register_operand" "0")))]
3401 "TARGET_HARD_FLOAT"
3402 "mvf%d1d\\t%0, %2"
3403 [(set_attr "type" "ffarith")
3404 (set_attr "conds" "use")])
3405\f
9c08d1fa 3406;; Jump and linkage insns
3407
3408(define_insn "jump"
3409 [(set (pc)
3410 (label_ref (match_operand 0 "" "")))]
3411 ""
3412 "*
3413{
3414 extern int arm_ccfsm_state;
3415
3416 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3417 {
3418 arm_ccfsm_state += 2;
3419 return \"\";
3420 }
40dbec34 3421 return \"b%?\\t%l0\";
9c08d1fa 3422}")
3423
d3373b54 3424(define_expand "call"
3425 [(parallel [(call (match_operand 0 "memory_operand" "")
3426 (match_operand 1 "general_operand" ""))
3427 (clobber (reg:SI 14))])]
3428 ""
3429 "")
3430
3431(define_insn ""
3432 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3433 (match_operand 1 "" "g"))
9c08d1fa 3434 (clobber (reg:SI 14))]
3435 ""
3436 "*
5565501b 3437 return output_call (operands);
9c08d1fa 3438"
3439[(set (attr "conds")
3440 (if_then_else (eq_attr "cpu" "arm6")
3441 (const_string "clob")
3442 (const_string "nocond")))
3443;; length is worst case, normally it is only two
094e994f 3444 (set_attr "length" "12")
9c08d1fa 3445 (set_attr "type" "call")])
3446
3447(define_insn ""
3448 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3449 (match_operand 1 "general_operand" "g"))
3450 (clobber (reg:SI 14))]
3451 ""
3452 "*
5565501b 3453 return output_call_mem (operands);
9c08d1fa 3454"
3455[(set (attr "conds")
3456 (if_then_else (eq_attr "cpu" "arm6")
3457 (const_string "clob")
3458 (const_string "nocond")))
094e994f 3459 (set_attr "length" "12")
9c08d1fa 3460 (set_attr "type" "call")])
3461
d3373b54 3462(define_expand "call_value"
3463 [(parallel [(set (match_operand 0 "" "=rf")
3464 (call (match_operand 1 "memory_operand" "m")
3465 (match_operand 2 "general_operand" "g")))
3466 (clobber (reg:SI 14))])]
3467 ""
3468 "")
3469
3470(define_insn ""
9c08d1fa 3471 [(set (match_operand 0 "" "=rf")
d3373b54 3472 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3473 (match_operand 2 "general_operand" "g")))
9c08d1fa 3474 (clobber (reg:SI 14))]
3475 ""
3476 "*
5565501b 3477 return output_call (&operands[1]);
9c08d1fa 3478"
3479[(set (attr "conds")
3480 (if_then_else (eq_attr "cpu" "arm6")
3481 (const_string "clob")
3482 (const_string "nocond")))
094e994f 3483 (set_attr "length" "12")
9c08d1fa 3484 (set_attr "type" "call")])
3485
3486(define_insn ""
3487 [(set (match_operand 0 "" "=rf")
3488 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3489 (match_operand 2 "general_operand" "g")))
3490 (clobber (reg:SI 14))]
3491 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3492 "*
5565501b 3493 return output_call_mem (&operands[1]);
9c08d1fa 3494"
3495[(set (attr "conds")
3496 (if_then_else (eq_attr "cpu" "arm6")
3497 (const_string "clob")
3498 (const_string "nocond")))
094e994f 3499 (set_attr "length" "12")
9c08d1fa 3500 (set_attr "type" "call")])
3501
3502;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3503;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3504
3505(define_insn ""
3506 [(call (mem:SI (match_operand:SI 0 "" "i"))
3507 (match_operand:SI 1 "general_operand" "g"))
3508 (clobber (reg:SI 14))]
3509 "GET_CODE (operands[0]) == SYMBOL_REF"
40dbec34 3510 "bl%?\\t%a0"
9c08d1fa 3511[(set (attr "conds")
3512 (if_then_else (eq_attr "cpu" "arm6")
3513 (const_string "clob")
3514 (const_string "nocond")))
3515 (set_attr "type" "call")])
3516
3517(define_insn ""
3518 [(set (match_operand 0 "s_register_operand" "=rf")
3519 (call (mem:SI (match_operand:SI 1 "" "i"))
3520 (match_operand:SI 2 "general_operand" "g")))
3521 (clobber (reg:SI 14))]
3522 "GET_CODE(operands[1]) == SYMBOL_REF"
40dbec34 3523 "bl%?\\t%a1"
9c08d1fa 3524[(set (attr "conds")
3525 (if_then_else (eq_attr "cpu" "arm6")
3526 (const_string "clob")
3527 (const_string "nocond")))
3528 (set_attr "type" "call")])
3529
3530;; Often the return insn will be the same as loading from memory, so set attr
3531(define_insn "return"
3532 [(return)]
3533 "USE_RETURN_INSN"
3534 "*
3535{
3536 extern int arm_ccfsm_state;
3537
3538 if (arm_ccfsm_state == 2)
3539 {
3540 arm_ccfsm_state += 2;
3541 return \"\";
3542 }
3543 return output_return_instruction (NULL, TRUE);
3544}"
3545[(set_attr "type" "load")])
3546
3547(define_insn ""
3548 [(set (pc)
3549 (if_then_else (match_operator 0 "comparison_operator"
3550 [(reg 24) (const_int 0)])
3551 (return)
3552 (pc)))]
3553 "USE_RETURN_INSN"
3554 "*
3555{
3556 extern int arm_ccfsm_state;
3557
3558 if (arm_ccfsm_state == 2)
3559 {
3560 arm_ccfsm_state += 2;
3561 return \"\";
3562 }
3563 return output_return_instruction (operands[0], TRUE);
3564}"
3565[(set_attr "conds" "use")
3566 (set_attr "type" "load")])
3567
3568(define_insn ""
3569 [(set (pc)
3570 (if_then_else (match_operator 0 "comparison_operator"
3571 [(reg 24) (const_int 0)])
3572 (pc)
3573 (return)))]
3574 "USE_RETURN_INSN"
3575 "*
3576{
3577 extern int arm_ccfsm_state;
3578
3579 if (arm_ccfsm_state == 2)
3580 {
3581 arm_ccfsm_state += 2;
3582 return \"\";
3583 }
3584 return output_return_instruction
3585 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3586 GET_MODE (operands[0]), XEXP (operands[0], 0),
3587 XEXP (operands[0], 1)),
3588 TRUE);
3589}"
3590[(set_attr "conds" "use")
3591 (set_attr "type" "load")])
3592
3593;; Call subroutine returning any type.
3594
3595(define_expand "untyped_call"
3596 [(parallel [(call (match_operand 0 "" "")
3597 (const_int 0))
3598 (match_operand 1 "" "")
3599 (match_operand 2 "" "")])]
3600 ""
3601 "
3602{
3603 int i;
3604
3605 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3606
3607 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3608 {
3609 rtx set = XVECEXP (operands[2], 0, i);
3610 emit_move_insn (SET_DEST (set), SET_SRC (set));
3611 }
3612
3613 /* The optimizer does not know that the call sets the function value
3614 registers we stored in the result block. We avoid problems by
3615 claiming that all hard registers are used and clobbered at this
3616 point. */
3617 emit_insn (gen_blockage ());
3618
3619 DONE;
3620}")
3621
3622;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3623;; all of memory. This blocks insns from being moved across this point.
3624
3625(define_insn "blockage"
3626 [(unspec_volatile [(const_int 0)] 0)]
3627 ""
3628 ""
3629[(set_attr "length" "0")
3630 (set_attr "type" "block")])
3631
3632(define_insn "tablejump"
3633 [(set (pc)
3634 (match_operand:SI 0 "s_register_operand" "r"))
3635 (use (label_ref (match_operand 1 "" "")))]
3636 ""
899850b0 3637 "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
9c08d1fa 3638
3639(define_insn ""
3640 [(set (pc)
3641 (match_operand:SI 0 "memory_operand" "m"))
3642 (use (label_ref (match_operand 1 "" "")))]
3643 ""
899850b0 3644 "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
9c08d1fa 3645[(set_attr "type" "load")])
3646
3647(define_insn "indirect_jump"
3648 [(set (pc)
3649 (match_operand:SI 0 "s_register_operand" "r"))]
3650 ""
899850b0 3651 "mov%?\\t%|pc, %0\\t%@ indirect jump")
9c08d1fa 3652
3653(define_insn ""
3654 [(set (pc)
3655 (match_operand:SI 0 "memory_operand" "m"))]
3656 ""
899850b0 3657 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
9c08d1fa 3658[(set_attr "type" "load")])
3659\f
3660;; Misc insns
3661
3662(define_insn "nop"
3663 [(const_int 0)]
3664 ""
40dbec34 3665 "mov%?\\tr0, r0\\t%@ nop")
9c08d1fa 3666\f
3667;; Patterns to allow combination of arithmetic, cond code and shifts
3668
3669(define_insn ""
3670 [(set (match_operand:SI 0 "s_register_operand" "=r")
3671 (match_operator:SI 1 "shiftable_operator"
3672 [(match_operator:SI 3 "shift_operator"
3673 [(match_operand:SI 4 "s_register_operand" "r")
87b22bf7 3674 (match_operand:SI 5 "reg_or_int_operand" "rI")])
9c08d1fa 3675 (match_operand:SI 2 "s_register_operand" "r")]))]
3676 ""
87b22bf7 3677 "%i1%?\\t%0, %2, %4%S3")
9c08d1fa 3678
3679(define_insn ""
3680 [(set (reg:CC_NOOV 24)
3681 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3682 [(match_operator:SI 3 "shift_operator"
3683 [(match_operand:SI 4 "s_register_operand" "r")
87b22bf7 3684 (match_operand:SI 5 "reg_or_int_operand" "rI")])
9c08d1fa 3685 (match_operand:SI 2 "s_register_operand" "r")])
3686 (const_int 0)))
3687 (set (match_operand:SI 0 "s_register_operand" "=r")
3688 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3689 (match_dup 2)]))]
3690 ""
87b22bf7 3691 "%i1%?s\\t%0, %2, %4%S3"
9c08d1fa 3692[(set_attr "conds" "set")])
3693
3694(define_insn ""
3695 [(set (reg:CC_NOOV 24)
3696 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3697 [(match_operator:SI 3 "shift_operator"
3698 [(match_operand:SI 4 "s_register_operand" "r")
87b22bf7 3699 (match_operand:SI 5 "reg_or_int_operand" "rI")])
9c08d1fa 3700 (match_operand:SI 2 "s_register_operand" "r")])
3701 (const_int 0)))
3702 (clobber (match_scratch:SI 0 "=r"))]
3703 ""
87b22bf7 3704 "%i1%?s\\t%0, %2, %4%S3"
9c08d1fa 3705[(set_attr "conds" "set")])
3706
3707(define_insn ""
3708 [(set (match_operand:SI 0 "s_register_operand" "=r")
3709 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3710 (match_operator:SI 2 "shift_operator"
3711 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 3712 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
9c08d1fa 3713 ""
87b22bf7 3714 "sub%?\\t%0, %1, %3%S2")
9c08d1fa 3715
3716(define_insn ""
3717 [(set (reg:CC_NOOV 24)
40dbec34 3718 (compare:CC_NOOV
3719 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3720 (match_operator:SI 2 "shift_operator"
3721 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 3722 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
40dbec34 3723 (const_int 0)))
9c08d1fa 3724 (set (match_operand:SI 0 "s_register_operand" "=r")
3725 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3726 (match_dup 4)])))]
3727 ""
87b22bf7 3728 "sub%?s\\t%0, %1, %3%S2"
9c08d1fa 3729[(set_attr "conds" "set")])
3730
3731(define_insn ""
3732 [(set (reg:CC_NOOV 24)
40dbec34 3733 (compare:CC_NOOV
3734 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3735 (match_operator:SI 2 "shift_operator"
3736 [(match_operand:SI 3 "s_register_operand" "r")
87b22bf7 3737 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
40dbec34 3738 (const_int 0)))
9c08d1fa 3739 (clobber (match_scratch:SI 0 "=r"))]
3740 ""
87b22bf7 3741 "sub%?s\\t%0, %1, %3%S2"
9c08d1fa 3742[(set_attr "conds" "set")])
3743
3744;; These variants of the above insns can occur if the first operand is the
3745;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3746;; seem to be a way around it. Most of the predicates have to be null
3747;; because the format can be generated part way through reload, so
3748;; if we don't match it as soon as it becomes available, reload doesn't know
3749;; how to reload pseudos that haven't got hard registers; the constraints will
3750;; sort everything out.
3751
3752(define_insn ""
3753 [(set (match_operand:SI 0 "" "=&r")
3754 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3755 [(match_operand:SI 3 "" "r")
87b22bf7 3756 (match_operand:SI 4 "" "rM")])
9c08d1fa 3757 (match_operand:SI 2 "" "r"))
3758 (match_operand:SI 1 "const_int_operand" "n")))]
3759 "reload_in_progress"
3760 "*
87b22bf7 3761 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
9c08d1fa 3762 operands[2] = operands[1];
3763 operands[1] = operands[0];
3764 return output_add_immediate (operands);
40dbec34 3765"
9c08d1fa 3766; we have no idea how long the add_immediate is, it could be up to 4.
094e994f 3767[(set_attr "length" "20")])
9c08d1fa 3768
3769(define_insn ""
3770 [(set (reg:CC_NOOV 24)
3771 (compare:CC_NOOV (plus:SI
3772 (plus:SI
3773 (match_operator:SI 5 "shift_operator"
3774 [(match_operand:SI 3 "" "r")
87b22bf7 3775 (match_operand:SI 4 "" "rM")])
9c08d1fa 3776 (match_operand:SI 1 "" "r"))
3777 (match_operand:SI 2 "const_int_operand" "n"))
3778 (const_int 0)))
3779 (set (match_operand:SI 0 "" "=&r")
3780 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3781 (match_dup 1))
3782 (match_dup 2)))]
3783 "reload_in_progress"
3784 "*
9c08d1fa 3785 output_add_immediate (operands);
87b22bf7 3786 return \"add%?s\\t%0, %0, %3%S5\";
40dbec34 3787"
9c08d1fa 3788[(set_attr "conds" "set")
094e994f 3789 (set_attr "length" "20")])
9c08d1fa 3790
3791(define_insn ""
3792 [(set (reg:CC_NOOV 24)
3793 (compare:CC_NOOV (plus:SI
3794 (plus:SI
3795 (match_operator:SI 5 "shift_operator"
3796 [(match_operand:SI 3 "" "r")
87b22bf7 3797 (match_operand:SI 4 "" "rM")])
9c08d1fa 3798 (match_operand:SI 1 "" "r"))
3799 (match_operand:SI 2 "const_int_operand" "n"))
3800 (const_int 0)))
3801 (clobber (match_scratch:SI 0 "=&r"))]
3802 "reload_in_progress"
3803 "*
9c08d1fa 3804 output_add_immediate (operands);
87b22bf7 3805 return \"add%?s\\t%0, %0, %3%S5\";
40dbec34 3806"
9c08d1fa 3807[(set_attr "conds" "set")
094e994f 3808 (set_attr "length" "20")])
12131158 3809
3810;; These are similar, but are needed when the mla pattern contains the
3811;; eliminated register as operand 3.
3812
3813(define_insn ""
3814 [(set (match_operand:SI 0 "" "=&r,&r")
3815 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3816 (match_operand:SI 2 "" "r,r"))
3817 (match_operand:SI 3 "" "r,r"))
3818 (match_operand:SI 4 "const_int_operand" "n,n")))]
3819 "reload_in_progress"
3820 "*
40dbec34 3821 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
12131158 3822 operands[2] = operands[4];
3823 operands[1] = operands[0];
3824 return output_add_immediate (operands);
3825"
094e994f 3826[(set_attr "length" "20")])
12131158 3827
3828(define_insn ""
3829 [(set (reg:CC_NOOV 24)
3830 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3831 (match_operand:SI 3 "" "r")
3832 (match_operand:SI 4 "" "r"))
3833 (match_operand:SI 1 "" "r"))
3834 (match_operand:SI 2 "const_int_operand" "n"))
3835 (const_int 0)))
3836 (set (match_operand:SI 0 "" "=&r")
3837 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3838 (match_dup 2)))]
3839 "reload_in_progress"
3840 "*
3841 output_add_immediate (operands);
40dbec34 3842 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
e2348bcb 3843 return \"\";
12131158 3844"
094e994f 3845[(set_attr "length" "20")
12131158 3846 (set_attr "conds" "set")])
3847
3848(define_insn ""
3849 [(set (reg:CC_NOOV 24)
3850 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3851 (match_operand:SI 3 "" "r")
3852 (match_operand:SI 4 "" "r"))
3853 (match_operand:SI 1 "" "r"))
3854 (match_operand:SI 2 "const_int_operand" "n"))
3855 (const_int 0)))
3856 (clobber (match_scratch:SI 0 "=&r"))]
3857 "reload_in_progress"
3858 "*
3859 output_add_immediate (operands);
40dbec34 3860 return \"mla%?s\\t%0, %3, %4, %0\";
12131158 3861"
094e994f 3862[(set_attr "length" "20")
12131158 3863 (set_attr "conds" "set")])
3864
3865
9c08d1fa 3866\f
3867
3868(define_insn ""
3869 [(set (match_operand:SI 0 "s_register_operand" "=r")
3870 (and:SI (match_operator 1 "comparison_operator"
4d61e570 3871 [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
9c08d1fa 3872 (match_operand:SI 2 "s_register_operand" "r")))]
3873 ""
e2348bcb 3874 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
9c08d1fa 3875[(set_attr "conds" "use")
094e994f 3876 (set_attr "length" "8")])
9c08d1fa 3877
3878(define_insn ""
3879 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3880 (ior:SI (match_operator 2 "comparison_operator"
3881 [(reg 24) (const_int 0)])
3882 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3883 ""
e2348bcb 3884 "@
899850b0 3885 orr%d2\\t%0, %1, #1
3886 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
9c08d1fa 3887[(set_attr "conds" "use")
094e994f 3888 (set_attr "length" "4,8")])
9c08d1fa 3889
3890(define_insn ""
5565501b 3891 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3892 (match_operator 1 "comparison_operator"
5565501b 3893 [(match_operand:SI 2 "s_register_operand" "r,r")
3894 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9c08d1fa 3895 (clobber (reg 24))]
3896 ""
3897 "*
f0e75574 3898 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
e2348bcb 3899 return \"mov\\t%0, %2, lsr #31\";
3900
9c08d1fa 3901 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
e2348bcb 3902 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3903
9c08d1fa 3904 if (GET_CODE (operands[1]) == NE)
3905 {
5565501b 3906 if (which_alternative == 1)
e2348bcb 3907 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3908 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
9c08d1fa 3909 }
5565501b 3910 if (which_alternative == 1)
e2348bcb 3911 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 3912 else
e2348bcb 3913 output_asm_insn (\"cmp\\t%2, %3\", operands);
3914 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
9c08d1fa 3915"
3916[(set_attr "conds" "clob")
094e994f 3917 (set_attr "length" "12")])
9c08d1fa 3918
3919(define_insn ""
3920 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3921 (ior:SI (match_operator 1 "comparison_operator"
3922 [(match_operand:SI 2 "s_register_operand" "r")
3923 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3924 (match_operator 4 "comparison_operator"
3925 [(match_operand:SI 5 "s_register_operand" "r")
3926 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3927 (clobber (reg 24))]
3928 ""
3929 "*
3930{
3931 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3932 GET_CODE (operands[1]));
3933
e2348bcb 3934 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3935 operands);
3936 output_asm_insn (\"mov\\t%0, #0\", operands);
9c08d1fa 3937 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3938 || comparison_dominates_p (GET_CODE (operands[1]),
3939 GET_CODE (operands[4]))
3940 || dominant)
e2348bcb 3941 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3942 operands);
9c08d1fa 3943 else
e2348bcb 3944 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3945 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
9c08d1fa 3946}
3947"
3948[(set_attr "conds" "clob")
3949; worst case length
094e994f 3950 (set_attr "length" "20")])
9c08d1fa 3951
3952(define_split
3953 [(set (pc)
5565501b 3954 (if_then_else
3955 (match_operator 5 "equality_operator"
3956 [(ior:SI (match_operator 6 "comparison_operator"
3957 [(match_operand:SI 0 "s_register_operand" "")
3958 (match_operand:SI 1 "arm_add_operand" "")])
3959 (match_operator 7 "comparison_operator"
3960 [(match_operand:SI 2 "s_register_operand" "")
3961 (match_operand:SI 3 "arm_add_operand" "")]))
3962 (const_int 0)])
3963 (label_ref (match_operand 4 "" ""))
3964 (pc)))
9c08d1fa 3965 (clobber (reg 24))]
3966 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3967 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3968 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3969 [(set (reg:CC 24)
3970 (compare:CC (ior:CC (match_op_dup 6
3971 [(match_dup 0) (match_dup 1)])
3972 (match_op_dup 7
3973 [(match_dup 2) (match_dup 3)]))
3974 (const_int 0)))
3975 (set (pc)
3976 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3977 (label_ref (match_dup 4))
3978 (pc)))]
3979 "
3980{
3981 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3982 GET_CODE (operands[7]))
3983 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3984
3985 if (GET_CODE (operands[5]) == NE)
3986 operands[5] = gen_rtx (code, CCmode,
3987 XEXP (operands[5], 0), XEXP (operands[5], 1));
3988 else
3989 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3990 XEXP (operands[5], 0), XEXP (operands[5], 1));
3991}
3992")
3993
3994;; Don't match these patterns if we can use a conditional compare, since they
01cc3b75 3995;; tell the final prescan branch eliminator code that full branch inlining
9c08d1fa 3996;; can't be done.
3997
3998(define_insn ""
3999 [(set (pc)
5565501b 4000 (if_then_else
4001 (ne (ior:SI (match_operator 5 "comparison_operator"
4002 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4003 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4004 (match_operator 6 "comparison_operator"
4005 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4006 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
4007 (const_int 0))
4008 (label_ref (match_operand 4 "" ""))
4009 (pc)))
9c08d1fa 4010 (clobber (reg 24))]
4011 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
4012 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
4013 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
4014 "*
4015{
4016 extern int arm_ccfsm_state;
4017
5565501b 4018 if (which_alternative & 1)
4019 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
9c08d1fa 4020 else
5565501b 4021 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
e2348bcb 4022
5565501b 4023 if (which_alternative >= 2)
e2348bcb 4024 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 4025 else
e2348bcb 4026 output_asm_insn (\"cmp\\t%2, %3\", operands);
4027
9c08d1fa 4028 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4029 {
4030 arm_ccfsm_state += 2;
4031 return \"\";
4032 }
e2348bcb 4033 return \"b%d6\\t%l4\";
9c08d1fa 4034}"
4035[(set_attr "conds" "jump_clob")
094e994f 4036 (set_attr "length" "16")])
9c08d1fa 4037
4038(define_insn ""
4039 [(set (reg:CC 24)
5565501b 4040 (compare:CC
4041 (ior:CC (match_operator 4 "comparison_operator"
4042 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4043 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4044 (match_operator 5 "comparison_operator"
4045 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4046 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
4047 (const_int 0)))]
9c08d1fa 4048 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
4049 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
4050 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
4051 "*
4052 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
4053 {
5565501b 4054 if (which_alternative >= 2)
e2348bcb 4055 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 4056 else
e2348bcb 4057 output_asm_insn (\"cmp\\t%2, %3\", operands);
4058
5565501b 4059 if (which_alternative & 1)
e2348bcb 4060 return \"cmn%D5\\t%0, #%n1\";
4061 return \"cmp%D5\\t%0, %1\";
9c08d1fa 4062 }
e2348bcb 4063
5565501b 4064 if (which_alternative & 1)
e2348bcb 4065 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
9c08d1fa 4066 else
e2348bcb 4067 output_asm_insn (\"cmp\\t%0, %1\", operands);
4068
5565501b 4069 if (which_alternative >= 2)
e2348bcb 4070 return \"cmn%D4\\t%2, #%n3\";
4071 return \"cmp%D4\\t%2, %3\";
9c08d1fa 4072"
4073[(set_attr "conds" "set")
094e994f 4074 (set_attr "length" "8")])
9c08d1fa 4075
4076(define_insn ""
4077 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4078 (if_then_else (match_operator 3 "equality_operator"
4079 [(match_operator 4 "comparison_operator"
4080 [(reg 24) (const_int 0)])
4081 (const_int 0)])
4082 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4083 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
4084 ""
4085 "*
4086 if (GET_CODE (operands[3]) == NE)
4087 {
9c08d1fa 4088 if (which_alternative != 1)
e2348bcb 4089 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4d61e570 4090 if (which_alternative != 0)
4091 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9c08d1fa 4092 return \"\";
4093 }
4094 if (which_alternative != 0)
e2348bcb 4095 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9c08d1fa 4096 if (which_alternative != 1)
e2348bcb 4097 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9c08d1fa 4098 return \"\";
4099"
4100[(set_attr "conds" "use")
094e994f 4101 (set_attr "length" "4,4,8")])
9c08d1fa 4102
4103(define_insn ""
4104 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4105 (match_operator:SI 5 "shiftable_operator"
4106 [(match_operator:SI 4 "comparison_operator"
4107 [(match_operand:SI 2 "s_register_operand" "r,r")
4108 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4109 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4110 (clobber (reg 24))]
4111 ""
4112 "*
9c08d1fa 4113 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
40dbec34 4114 return \"%i5\\t%0, %1, %2, lsr #31\";
4115
e2348bcb 4116 output_asm_insn (\"cmp\\t%2, %3\", operands);
9c08d1fa 4117 if (GET_CODE (operands[5]) == AND)
e2348bcb 4118 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9c08d1fa 4119 else if (which_alternative != 0)
e2348bcb 4120 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
40dbec34 4121 return \"%i5%d4\\t%0, %1, #1\";
9c08d1fa 4122"
4123[(set_attr "conds" "clob")
094e994f 4124 (set_attr "length" "12")])
9c08d1fa 4125
4126(define_insn ""
4127 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4128 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4129 (match_operator:SI 4 "comparison_operator"
4130 [(match_operand:SI 2 "s_register_operand" "r,r")
4131 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4132 (clobber (reg 24))]
4133 ""
4134 "*
e2348bcb 4135 output_asm_insn (\"cmp\\t%2, %3\", operands);
9c08d1fa 4136 if (which_alternative != 0)
e2348bcb 4137 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4138 return \"sub%d4\\t%0, %1, #1\";
9c08d1fa 4139"
4140[(set_attr "conds" "clob")
094e994f 4141 (set_attr "length" "8,12")])
9c08d1fa 4142
4143(define_insn ""
4144 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4145 (and:SI (match_operator 1 "comparison_operator"
4146 [(match_operand:SI 2 "s_register_operand" "r")
4147 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4148 (match_operator 4 "comparison_operator"
4149 [(match_operand:SI 5 "s_register_operand" "r")
4150 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4151 (clobber (reg 24))]
4152 ""
4153 "*
4154{
4155 int dominant =
4156 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4157 reverse_condition (GET_CODE (operands[4])))
4158 ? 1
4159 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4160 reverse_condition (GET_CODE (operands[1])))
4161 ? 2 : 0;
e2348bcb 4162 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
9c08d1fa 4163 operands);
e2348bcb 4164 output_asm_insn (\"mov\\t%0, #1\", operands);
9c08d1fa 4165 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4166 {
e2348bcb 4167 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
9c08d1fa 4168 : \"cmp%d1\\t%5, %6\", operands);
4169 }
4170 else
4171 {
e2348bcb 4172 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4173 output_asm_insn (\"cmp\\t%5, %6\", operands);
9c08d1fa 4174 }
e2348bcb 4175 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
9c08d1fa 4176}
4177"
4178[(set_attr "conds" "clob")
094e994f 4179 (set_attr "length" "20")])
9c08d1fa 4180
4181(define_split
4182 [(set (pc)
4183 (if_then_else (match_operator 1 "equality_operator"
4184 [(and:SI (match_operator 2 "comparison_operator"
5565501b 4185 [(match_operand:SI 3 "s_register_operand" "")
4186 (match_operand:SI 4 "arm_add_operand" "")])
9c08d1fa 4187 (match_operator 0 "comparison_operator"
5565501b 4188 [(match_operand:SI 5 "s_register_operand" "")
4189 (match_operand:SI 6 "arm_add_operand" "")]))
9c08d1fa 4190 (const_int 0)])
4191 (label_ref (match_operand 7 "" ""))
4192 (pc)))
4193 (clobber (reg 24))]
4194 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4195 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4196 reverse_condition (GET_CODE (operands[0])))
4197 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4198 reverse_condition (GET_CODE (operands[2]))))"
4199 [(set (reg:CC 24)
4200 (compare:CC (ior:CC (match_op_dup 2
4201 [(match_dup 3) (match_dup 4)])
4202 (match_op_dup 0
4203 [(match_dup 5) (match_dup 6)]))
4204 (const_int 0)))
4205 (set (pc)
4206 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4207 (label_ref (match_dup 7))
4208 (pc)))]
4209 "
4210{
4211 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4212 This is safe since we only do it for integer comparisons. */
4213 enum rtx_code code =
4214 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4215 reverse_condition (GET_CODE (operands[0])))
4216 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4217
4218 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4219 GET_MODE (operands[2]), operands[3], operands[4]);
4220 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4221 GET_MODE (operands[0]), operands[5], operands[6]);
4222 if (GET_CODE (operands[1]) == NE)
4223 operands[1] = gen_rtx (code, CCmode,
4224 XEXP (operands[1], 0), XEXP (operands[1], 1));
4225 else
4226 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4227 XEXP (operands[1], 0), XEXP (operands[1], 1));
4228}
4229")
4230
4231;; Don't match these patterns if we can use a conditional compare, since they
01cc3b75 4232;; tell the final prescan branch eliminator code that full branch inlining
9c08d1fa 4233;; can't be done.
4234
4235(define_insn ""
4236 [(set (pc)
5565501b 4237 (if_then_else
4238 (eq (and:SI (match_operator 1 "comparison_operator"
4239 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4240 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4241 (match_operator 4 "comparison_operator"
4242 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4243 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4244 (const_int 0))
4245 (label_ref (match_operand 0 "" ""))
4246 (pc)))
9c08d1fa 4247 (clobber (reg 24))]
4248 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4249 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4250 reverse_condition (GET_CODE (operands[4])))
4251 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4252 reverse_condition (GET_CODE (operands[1]))))"
4253 "*
4254{
4255 extern int arm_ccfsm_state;
4256
5565501b 4257 if (which_alternative & 1)
4258 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
9c08d1fa 4259 else
5565501b 4260 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4261
4262 if (which_alternative >= 2)
e2348bcb 4263 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
9c08d1fa 4264 else
e2348bcb 4265 output_asm_insn (\"cmp\\t%5, %6\", operands);
5565501b 4266
9c08d1fa 4267 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4268 {
4269 arm_ccfsm_state += 2;
4270 return \"\";
4271 }
e2348bcb 4272 return \"b%D4\\t%l0\";
9c08d1fa 4273}"
4274[(set_attr "conds" "jump_clob")
094e994f 4275 (set_attr "length" "16")])
9c08d1fa 4276
4277(define_insn ""
4278 [(set (match_operand:SI 0 "s_register_operand" "=r")
4279 (neg:SI (match_operator 3 "comparison_operator"
4280 [(match_operand:SI 1 "s_register_operand" "r")
4281 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4282 (clobber (reg 24))]
4283 ""
4284 "*
f0e75574 4285 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
e2348bcb 4286 return \"mov\\t%0, %1, asr #31\";
4287
9c08d1fa 4288 if (GET_CODE (operands[3]) == NE)
e2348bcb 4289 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4290
9c08d1fa 4291 if (GET_CODE (operands[3]) == GT)
e2348bcb 4292 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4293
4294 output_asm_insn (\"cmp\\t%1, %2\", operands);
4295 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4296 return \"mvn%d3\\t%0, #0\";
9c08d1fa 4297"
4298[(set_attr "conds" "clob")
094e994f 4299 (set_attr "length" "12")])
9c08d1fa 4300
4301(define_insn "movcond"
4302 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 4303 (if_then_else:SI
4304 (match_operator 5 "comparison_operator"
4305 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4306 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4307 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4308 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9c08d1fa 4309 (clobber (reg 24))]
4310 ""
4311 "*
4312 if (GET_CODE (operands[5]) == LT
4313 && (operands[4] == const0_rtx))
4314 {
5565501b 4315 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
9c08d1fa 4316 {
9c08d1fa 4317 if (operands[2] == const0_rtx)
e2348bcb 4318 return \"and\\t%0, %1, %3, asr #31\";
4319 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 4320 }
4321 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4322 {
9c08d1fa 4323 if (operands[1] == const0_rtx)
e2348bcb 4324 return \"bic\\t%0, %2, %3, asr #31\";
4325 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 4326 }
4327 /* The only case that falls through to here is when both ops 1 & 2
4328 are constants */
4329 }
e2348bcb 4330
9c08d1fa 4331 if (GET_CODE (operands[5]) == GE
4332 && (operands[4] == const0_rtx))
4333 {
4334 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4335 {
9c08d1fa 4336 if (operands[2] == const0_rtx)
e2348bcb 4337 return \"bic\\t%0, %1, %3, asr #31\";
4338 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 4339 }
4340 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4341 {
9c08d1fa 4342 if (operands[1] == const0_rtx)
e2348bcb 4343 return \"and\\t%0, %2, %3, asr #31\";
4344 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 4345 }
4346 /* The only case that falls through to here is when both ops 1 & 2
4347 are constants */
4348 }
4349 if (GET_CODE (operands[4]) == CONST_INT
4350 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 4351 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 4352 else
e2348bcb 4353 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 4354 if (which_alternative != 0)
e2348bcb 4355 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 4356 if (which_alternative != 1)
e2348bcb 4357 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 4358 return \"\";
4359"
4360[(set_attr "conds" "clob")
094e994f 4361 (set_attr "length" "8,8,12")])
9c08d1fa 4362
4363(define_insn ""
5565501b 4364 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 4365 (if_then_else:SI (match_operator 9 "comparison_operator"
5565501b 4366 [(match_operand:SI 5 "s_register_operand" "r,r")
4367 (match_operand:SI 6 "arm_add_operand" "rI,L")])
9c08d1fa 4368 (match_operator:SI 8 "shiftable_operator"
5565501b 4369 [(match_operand:SI 1 "s_register_operand" "r,r")
4370 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
9c08d1fa 4371 (match_operator:SI 7 "shiftable_operator"
5565501b 4372 [(match_operand:SI 3 "s_register_operand" "r,r")
4373 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
9c08d1fa 4374 (clobber (reg 24))]
4375 ""
5565501b 4376 "@
4377 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4378 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
9c08d1fa 4379[(set_attr "conds" "clob")
094e994f 4380 (set_attr "length" "12")])
9c08d1fa 4381
4382(define_insn ""
4383 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4384 (if_then_else:SI (match_operator 6 "comparison_operator"
4385 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 4386 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4387 (match_operator:SI 7 "shiftable_operator"
4388 [(match_operand:SI 4 "s_register_operand" "r,r")
4389 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4390 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4391 (clobber (reg 24))]
4392 ""
4393 "*
9c08d1fa 4394 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 4395 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 4396 everything is in registers then we can do this in two instructions */
4397 if (operands[3] == const0_rtx
4398 && GET_CODE (operands[7]) != AND
4399 && GET_CODE (operands[5]) == REG
4400 && GET_CODE (operands[1]) == REG
4401 && REGNO (operands[1]) == REGNO (operands[4])
4402 && REGNO (operands[4]) != REGNO (operands[0]))
4403 {
4404 if (GET_CODE (operands[6]) == LT)
40dbec34 4405 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 4406 else if (GET_CODE (operands[6]) == GE)
40dbec34 4407 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 4408 }
4409 if (GET_CODE (operands[3]) == CONST_INT
4410 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 4411 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 4412 else
e2348bcb 4413 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 4414 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 4415 if (which_alternative != 0)
4416 {
4417 if (GET_CODE (operands[1]) == MEM)
40dbec34 4418 return \"ldr%D6\\t%0, %1\";
9c08d1fa 4419 else
40dbec34 4420 return \"mov%D6\\t%0, %1\";
9c08d1fa 4421 }
4422 return \"\";
9c08d1fa 4423"
4424[(set_attr "conds" "clob")
094e994f 4425 (set_attr "length" "8,12")])
9c08d1fa 4426
4427(define_insn ""
4428 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4429 (if_then_else:SI (match_operator 6 "comparison_operator"
4430 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 4431 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4432 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4433 (match_operator:SI 7 "shiftable_operator"
4434 [(match_operand:SI 2 "s_register_operand" "r,r")
4435 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4436 (clobber (reg 24))]
4437 ""
4438 "*
9c08d1fa 4439 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 4440 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 4441 everything is in registers then we can do this in two instructions */
4442 if (operands[5] == const0_rtx
4443 && GET_CODE (operands[7]) != AND
4444 && GET_CODE (operands[3]) == REG
4445 && GET_CODE (operands[1]) == REG
4446 && REGNO (operands[1]) == REGNO (operands[2])
4447 && REGNO (operands[2]) != REGNO (operands[0]))
4448 {
4449 if (GET_CODE (operands[6]) == GE)
40dbec34 4450 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 4451 else if (GET_CODE (operands[6]) == LT)
40dbec34 4452 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 4453 }
40dbec34 4454
9c08d1fa 4455 if (GET_CODE (operands[5]) == CONST_INT
4456 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 4457 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 4458 else
e2348bcb 4459 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 4460
9c08d1fa 4461 if (which_alternative != 0)
4462 {
4463 if (GET_CODE (operands[1]) == MEM)
e2348bcb 4464 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
9c08d1fa 4465 else
e2348bcb 4466 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9c08d1fa 4467 }
40dbec34 4468 return \"%I7%D6\\t%0, %2, %3\";
9c08d1fa 4469"
4470[(set_attr "conds" "clob")
094e994f 4471 (set_attr "length" "8,12")])
9c08d1fa 4472
4473(define_insn ""
4474 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4475 (if_then_else:SI (match_operator 6 "comparison_operator"
4476 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 4477 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4478 (plus:SI
4479 (match_operand:SI 2 "s_register_operand" "r,r")
4480 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4481 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4482 (clobber (reg 24))]
4483 ""
4484 "*
4485{
4486 if (GET_CODE (operands[5]) == CONST_INT
4487 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 4488 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 4489 else
e2348bcb 4490 output_asm_insn (\"cmp\\t%4, %5\", operands);
9c08d1fa 4491 if (GET_CODE (operands[3]) == CONST_INT
4492 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 4493 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
9c08d1fa 4494 else
e2348bcb 4495 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
9c08d1fa 4496 if (which_alternative != 0)
4497 {
4498 if (GET_CODE (operands[1]) == MEM)
e2348bcb 4499 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
9c08d1fa 4500 else
e2348bcb 4501 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
9c08d1fa 4502 }
4503 return \"\";
4504}
4505"
4506[(set_attr "conds" "clob")
094e994f 4507 (set_attr "length" "8,12")])
9c08d1fa 4508
4509(define_insn ""
4510 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4511 (if_then_else:SI (match_operator 6 "comparison_operator"
4512 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 4513 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4514 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4515 (plus:SI
4516 (match_operand:SI 2 "s_register_operand" "r,r")
5565501b 4517 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9c08d1fa 4518 (clobber (reg 24))]
4519 ""
4520 "*
4521{
4522 if (GET_CODE (operands[5]) == CONST_INT
4523 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 4524 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 4525 else
e2348bcb 4526 output_asm_insn (\"cmp\\t%4, %5\", operands);
9c08d1fa 4527 if (GET_CODE (operands[3]) == CONST_INT
4528 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 4529 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
9c08d1fa 4530 else
e2348bcb 4531 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
9c08d1fa 4532 if (which_alternative != 0)
4533 {
4534 if (GET_CODE (operands[6]) == MEM)
e2348bcb 4535 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
9c08d1fa 4536 else
e2348bcb 4537 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9c08d1fa 4538 }
4539 return \"\";
4540}
4541"
4542[(set_attr "conds" "clob")
094e994f 4543 (set_attr "length" "8,12")])
9c08d1fa 4544
4545(define_insn ""
4546 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4547 (if_then_else:SI (match_operator 5 "comparison_operator"
4548 [(match_operand:SI 3 "s_register_operand" "r,r")
5565501b 4549 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9c08d1fa 4550 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4551 (not:SI
4552 (match_operand:SI 2 "s_register_operand" "r,r"))))
4553 (clobber (reg 24))]
4554 ""
4555 "#"
4556[(set_attr "conds" "clob")
094e994f 4557 (set_attr "length" "8,12")])
9c08d1fa 4558
9c08d1fa 4559(define_insn ""
5565501b 4560 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4561 (if_then_else:SI
4562 (match_operator 5 "comparison_operator"
4563 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4564 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4565 (not:SI
4566 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4567 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
9c08d1fa 4568 (clobber (reg 24))]
4569 ""
5565501b 4570 "@
4571 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4572 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4573 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4574 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
9c08d1fa 4575[(set_attr "conds" "clob")
5565501b 4576 (set_attr "length" "8,8,12,12")])
4577
4578(define_insn ""
4579 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4580 (if_then_else:SI
4581 (match_operator 6 "comparison_operator"
4582 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4583 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4584 (match_operator:SI 7 "shift_operator"
4585 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
87b22bf7 4586 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
5565501b 4587 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
9c08d1fa 4588 (clobber (reg 24))]
4589 ""
5565501b 4590 "@
87b22bf7 4591 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4592 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4593 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4594 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
9c08d1fa 4595[(set_attr "conds" "clob")
5565501b 4596 (set_attr "length" "8,8,12,12")])
4597
4598(define_insn ""
4599 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4600 (if_then_else:SI
4601 (match_operator 6 "comparison_operator"
4602 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4603 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4604 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4605 (match_operator:SI 7 "shift_operator"
4606 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
87b22bf7 4607 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
9c08d1fa 4608 (clobber (reg 24))]
4609 ""
5565501b 4610 "@
87b22bf7 4611 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4612 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4613 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4614 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
9c08d1fa 4615[(set_attr "conds" "clob")
5565501b 4616 (set_attr "length" "8,8,12,12")])
9c08d1fa 4617
4618(define_insn ""
5565501b 4619 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4620 (if_then_else:SI
4621 (match_operator 7 "comparison_operator"
4622 [(match_operand:SI 5 "s_register_operand" "r,r")
4623 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4624 (match_operator:SI 8 "shift_operator"
4625 [(match_operand:SI 1 "s_register_operand" "r,r")
87b22bf7 4626 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
5565501b 4627 (match_operator:SI 9 "shift_operator"
4628 [(match_operand:SI 3 "s_register_operand" "r,r")
4629 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
9c08d1fa 4630 (clobber (reg 24))]
4631 ""
5565501b 4632 "@
87b22bf7 4633 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4634 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
9c08d1fa 4635[(set_attr "conds" "clob")
094e994f 4636 (set_attr "length" "12")])
9c08d1fa 4637
4638(define_insn ""
5565501b 4639 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4640 (if_then_else:SI
4641 (match_operator 6 "comparison_operator"
4642 [(match_operand:SI 4 "s_register_operand" "r,r")
4643 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4644 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4645 (match_operator:SI 7 "shiftable_operator"
4646 [(match_operand:SI 2 "s_register_operand" "r,r")
4647 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9c08d1fa 4648 (clobber (reg 24))]
4649 ""
5565501b 4650 "@
4651 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4652 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
9c08d1fa 4653[(set_attr "conds" "clob")
094e994f 4654 (set_attr "length" "12")])
9c08d1fa 4655
4656(define_insn ""
5565501b 4657 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4658 (if_then_else:SI
4659 (match_operator 6 "comparison_operator"
4660 [(match_operand:SI 4 "s_register_operand" "r,r")
4661 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4662 (match_operator:SI 7 "shiftable_operator"
4663 [(match_operand:SI 2 "s_register_operand" "r,r")
4664 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4665 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
9c08d1fa 4666 (clobber (reg 24))]
4667 ""
5565501b 4668 "@
899850b0 4669 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4670 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
9c08d1fa 4671[(set_attr "conds" "clob")
094e994f 4672 (set_attr "length" "12")])
9c08d1fa 4673
4674(define_insn ""
5565501b 4675 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4676 (if_then_else:SI
4677 (match_operator 5 "comparison_operator"
4678 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4679 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4680 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4681 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
9c08d1fa 4682 (clobber (reg:CC 24))]
4683 ""
5565501b 4684 "@
4685 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4686 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4687 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4688 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
9c08d1fa 4689[(set_attr "conds" "clob")
5565501b 4690 (set_attr "length" "8,8,12,12")])
9c08d1fa 4691
4692(define_insn ""
5565501b 4693 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4694 (if_then_else:SI
4695 (match_operator 5 "comparison_operator"
4696 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4697 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4698 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4699 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
9c08d1fa 4700 (clobber (reg:CC 24))]
4701 ""
5565501b 4702 "@
4703 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4704 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4705 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4706 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
9c08d1fa 4707[(set_attr "conds" "clob")
5565501b 4708 (set_attr "length" "8,8,12,12")])
9c08d1fa 4709
4710(define_insn ""
4711 [(set (match_operand:SI 0 "s_register_operand" "=r")
4712 (match_operator:SI 1 "shiftable_operator"
4713 [(match_operand:SI 2 "memory_operand" "m")
4714 (match_operand:SI 3 "memory_operand" "m")]))
4715 (clobber (match_scratch:SI 4 "=r"))]
4716 "adjacent_mem_locations (operands[2], operands[3])"
4717 "*
4718{
4719 rtx ldm[3];
c7597b5d 4720 rtx arith[4];
9c08d1fa 4721 int val1 = 0, val2 = 0;
4722
9c08d1fa 4723 if (REGNO (operands[0]) > REGNO (operands[4]))
4724 {
4725 ldm[1] = operands[4];
4726 ldm[2] = operands[0];
4727 }
4728 else
4729 {
4730 ldm[1] = operands[0];
4731 ldm[2] = operands[4];
4732 }
4733 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4734 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4735 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4736 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4737 arith[0] = operands[0];
c7597b5d 4738 arith[3] = operands[1];
9c08d1fa 4739 if (val1 < val2)
4740 {
4741 arith[1] = ldm[1];
4742 arith[2] = ldm[2];
4743 }
4744 else
4745 {
4746 arith[1] = ldm[2];
4747 arith[2] = ldm[1];
4748 }
4749 if (val1 && val2)
4750 {
4751 rtx ops[3];
4752 ldm[0] = ops[0] = operands[4];
4753 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4754 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4755 output_add_immediate (ops);
4756 if (val1 < val2)
40dbec34 4757 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9c08d1fa 4758 else
40dbec34 4759 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9c08d1fa 4760 }
4761 else if (val1)
4762 {
4763 ldm[0] = XEXP (operands[3], 0);
4764 if (val1 < val2)
40dbec34 4765 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9c08d1fa 4766 else
40dbec34 4767 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9c08d1fa 4768 }
4769 else
4770 {
4771 ldm[0] = XEXP (operands[2], 0);
4772 if (val1 < val2)
40dbec34 4773 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9c08d1fa 4774 else
40dbec34 4775 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9c08d1fa 4776 }
c7597b5d 4777 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
e2348bcb 4778 return \"\";
9c08d1fa 4779}
4780"
094e994f 4781[(set_attr "length" "12")
9c08d1fa 4782 (set_attr "type" "load")])
4783
4784;; the arm can support extended pre-inc instructions
4785
4786;; In all these cases, we use operands 0 and 1 for the register being
4787;; incremented because those are the operands that local-alloc will
4788;; tie and these are the pair most likely to be tieable (and the ones
4789;; that will benefit the most).
4790
4791;; We reject the frame pointer if it occurs anywhere in these patterns since
4792;; elimination will cause too many headaches.
4793
4794(define_insn ""
4795 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4796 (match_operand:SI 2 "index_operand" "rJ")))
4797 (match_operand:QI 3 "s_register_operand" "r"))
4798 (set (match_operand:SI 0 "s_register_operand" "=r")
4799 (plus:SI (match_dup 1) (match_dup 2)))]
4800 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4801 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4802 && (GET_CODE (operands[2]) != REG
4803 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4804 "str%?b\\t%3, [%0, %2]!"
9c08d1fa 4805[(set_attr "type" "store1")])
4806
4807(define_insn ""
4808 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4809 (match_operand:SI 2 "s_register_operand" "r")))
4810 (match_operand:QI 3 "s_register_operand" "r"))
4811 (set (match_operand:SI 0 "s_register_operand" "=r")
4812 (minus:SI (match_dup 1) (match_dup 2)))]
4813 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4814 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4815 && (GET_CODE (operands[2]) != REG
4816 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4817 "str%?b\\t%3, [%0, -%2]!"
9c08d1fa 4818[(set_attr "type" "store1")])
4819
4820(define_insn ""
4821 [(set (match_operand:QI 3 "s_register_operand" "=r")
4822 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4823 (match_operand:SI 2 "index_operand" "rJ"))))
4824 (set (match_operand:SI 0 "s_register_operand" "=r")
4825 (plus:SI (match_dup 1) (match_dup 2)))]
4826 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4827 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4828 && (GET_CODE (operands[2]) != REG
4829 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4830 "ldr%?b\\t%3, [%0, %2]!"
9c08d1fa 4831[(set_attr "type" "load")])
4832
4833(define_insn ""
4834 [(set (match_operand:QI 3 "s_register_operand" "=r")
4835 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4836 (match_operand:SI 2 "s_register_operand" "r"))))
4837 (set (match_operand:SI 0 "s_register_operand" "=r")
4838 (minus:SI (match_dup 1) (match_dup 2)))]
4839 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4840 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4841 && (GET_CODE (operands[2]) != REG
4842 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4843 "ldr%?b\\t%3, [%0, -%2]!"
9c08d1fa 4844[(set_attr "type" "load")])
4845
4846(define_insn ""
4847 [(set (match_operand:SI 3 "s_register_operand" "=r")
4848 (zero_extend:SI
4849 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4850 (match_operand:SI 2 "index_operand" "rJ")))))
4851 (set (match_operand:SI 0 "s_register_operand" "=r")
4852 (plus:SI (match_dup 1) (match_dup 2)))]
4853 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4854 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4855 && (GET_CODE (operands[2]) != REG
4856 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4857 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9c08d1fa 4858[(set_attr "type" "load")])
4859
4860(define_insn ""
4861 [(set (match_operand:SI 3 "s_register_operand" "=r")
4862 (zero_extend:SI
4863 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4864 (match_operand:SI 2 "s_register_operand" "r")))))
4865 (set (match_operand:SI 0 "s_register_operand" "=r")
4866 (minus:SI (match_dup 1) (match_dup 2)))]
4867 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4868 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4869 && (GET_CODE (operands[2]) != REG
4870 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4871 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9c08d1fa 4872[(set_attr "type" "load")])
4873
4874(define_insn ""
4875 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4876 (match_operand:SI 2 "index_operand" "rJ")))
4877 (match_operand:SI 3 "s_register_operand" "r"))
4878 (set (match_operand:SI 0 "s_register_operand" "=r")
4879 (plus:SI (match_dup 1) (match_dup 2)))]
4880 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4881 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4882 && (GET_CODE (operands[2]) != REG
4883 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4884 "str%?\\t%3, [%0, %2]!"
9c08d1fa 4885[(set_attr "type" "store1")])
4886
4887(define_insn ""
4888 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4889 (match_operand:SI 2 "s_register_operand" "r")))
4890 (match_operand:SI 3 "s_register_operand" "r"))
4891 (set (match_operand:SI 0 "s_register_operand" "=r")
4892 (minus:SI (match_dup 1) (match_dup 2)))]
4893 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4894 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4895 && (GET_CODE (operands[2]) != REG
4896 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4897 "str%?\\t%3, [%0, -%2]!"
9c08d1fa 4898[(set_attr "type" "store1")])
4899
4900(define_insn ""
4901 [(set (match_operand:SI 3 "s_register_operand" "=r")
4902 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4903 (match_operand:SI 2 "index_operand" "rJ"))))
4904 (set (match_operand:SI 0 "s_register_operand" "=r")
4905 (plus:SI (match_dup 1) (match_dup 2)))]
4906 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4907 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4908 && (GET_CODE (operands[2]) != REG
4909 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4910 "ldr%?\\t%3, [%0, %2]!"
9c08d1fa 4911[(set_attr "type" "load")])
4912
4913(define_insn ""
4914 [(set (match_operand:SI 3 "s_register_operand" "=r")
4915 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4916 (match_operand:SI 2 "s_register_operand" "r"))))
4917 (set (match_operand:SI 0 "s_register_operand" "=r")
4918 (minus:SI (match_dup 1) (match_dup 2)))]
4919 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4920 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4921 && (GET_CODE (operands[2]) != REG
4922 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4923 "ldr%?\\t%3, [%0, -%2]!"
9c08d1fa 4924[(set_attr "type" "load")])
4925
4926(define_insn ""
4927 [(set (match_operand:HI 3 "s_register_operand" "=r")
4928 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4929 (match_operand:SI 2 "index_operand" "rJ"))))
4930 (set (match_operand:SI 0 "s_register_operand" "=r")
4931 (plus:SI (match_dup 1) (match_dup 2)))]
c7597b5d 4932 "(! BYTES_BIG_ENDIAN)
25f7a26e 4933 && ! TARGET_SHORT_BY_BYTES
c7597b5d 4934 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 4935 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4936 && (GET_CODE (operands[2]) != REG
4937 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4938 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
9c08d1fa 4939[(set_attr "type" "load")])
4940
4941(define_insn ""
4942 [(set (match_operand:HI 3 "s_register_operand" "=r")
4943 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4944 (match_operand:SI 2 "s_register_operand" "r"))))
4945 (set (match_operand:SI 0 "s_register_operand" "=r")
4946 (minus:SI (match_dup 1) (match_dup 2)))]
c7597b5d 4947 "(!BYTES_BIG_ENDIAN)
25f7a26e 4948 && ! TARGET_SHORT_BY_BYTES
c7597b5d 4949 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 4950 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4951 && (GET_CODE (operands[2]) != REG
4952 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
40dbec34 4953 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
9c08d1fa 4954[(set_attr "type" "load")])
4955
4956(define_insn ""
4957 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4958 [(match_operand:SI 3 "s_register_operand" "r")
4959 (match_operand:SI 4 "const_shift_operand" "n")])
4960 (match_operand:SI 1 "s_register_operand" "0")))
4961 (match_operand:QI 5 "s_register_operand" "r"))
4962 (set (match_operand:SI 0 "s_register_operand" "=r")
4963 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4964 (match_dup 1)))]
4965 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4966 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4967 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4968 "str%?b\\t%5, [%0, %3%S2]!"
9c08d1fa 4969[(set_attr "type" "store1")])
4970
4971(define_insn ""
4972 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4973 (match_operator:SI 2 "shift_operator"
4974 [(match_operand:SI 3 "s_register_operand" "r")
4975 (match_operand:SI 4 "const_shift_operand" "n")])))
4976 (match_operand:QI 5 "s_register_operand" "r"))
4977 (set (match_operand:SI 0 "s_register_operand" "=r")
4978 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4979 (match_dup 4)])))]
4980 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4981 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4982 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4983 "str%?b\\t%5, [%0, -%3%S2]!"
9c08d1fa 4984[(set_attr "type" "store1")])
4985
4986(define_insn ""
4987 [(set (match_operand:QI 5 "s_register_operand" "=r")
4988 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4989 [(match_operand:SI 3 "s_register_operand" "r")
4990 (match_operand:SI 4 "const_shift_operand" "n")])
4991 (match_operand:SI 1 "s_register_operand" "0"))))
4992 (set (match_operand:SI 0 "s_register_operand" "=r")
4993 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4994 (match_dup 1)))]
4995 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4996 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4997 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 4998 "ldr%?b\\t%5, [%0, %3%S2]!"
9c08d1fa 4999[(set_attr "type" "load")])
5000
5001(define_insn ""
5002 [(set (match_operand:QI 5 "s_register_operand" "=r")
5003 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5004 (match_operator:SI 2 "shift_operator"
5005 [(match_operand:SI 3 "s_register_operand" "r")
5006 (match_operand:SI 4 "const_shift_operand" "n")]))))
5007 (set (match_operand:SI 0 "s_register_operand" "=r")
5008 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5009 (match_dup 4)])))]
5010 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5011 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5012 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5013 "ldr%?b\\t%5, [%0, -%3%S2]!"
9c08d1fa 5014[(set_attr "type" "load")])
5015
5016(define_insn ""
5017 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5018 [(match_operand:SI 3 "s_register_operand" "r")
5019 (match_operand:SI 4 "const_shift_operand" "n")])
5020 (match_operand:SI 1 "s_register_operand" "0")))
5021 (match_operand:SI 5 "s_register_operand" "r"))
5022 (set (match_operand:SI 0 "s_register_operand" "=r")
5023 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5024 (match_dup 1)))]
5025 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5026 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5027 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5028 "str%?\\t%5, [%0, %3%S2]!"
9c08d1fa 5029[(set_attr "type" "store1")])
5030
5031(define_insn ""
5032 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5033 (match_operator:SI 2 "shift_operator"
5034 [(match_operand:SI 3 "s_register_operand" "r")
5035 (match_operand:SI 4 "const_shift_operand" "n")])))
5036 (match_operand:SI 5 "s_register_operand" "r"))
5037 (set (match_operand:SI 0 "s_register_operand" "=r")
5038 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5039 (match_dup 4)])))]
5040 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5041 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5042 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5043 "str%?\\t%5, [%0, -%3%S2]!"
9c08d1fa 5044[(set_attr "type" "store1")])
5045
5046(define_insn ""
5047 [(set (match_operand:SI 5 "s_register_operand" "=r")
5048 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5049 [(match_operand:SI 3 "s_register_operand" "r")
5050 (match_operand:SI 4 "const_shift_operand" "n")])
5051 (match_operand:SI 1 "s_register_operand" "0"))))
5052 (set (match_operand:SI 0 "s_register_operand" "=r")
5053 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5054 (match_dup 1)))]
5055 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5056 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5057 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5058 "ldr%?\\t%5, [%0, %3%S2]!"
9c08d1fa 5059[(set_attr "type" "load")])
5060
5061(define_insn ""
5062 [(set (match_operand:SI 5 "s_register_operand" "=r")
5063 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5064 (match_operator:SI 2 "shift_operator"
5065 [(match_operand:SI 3 "s_register_operand" "r")
5066 (match_operand:SI 4 "const_shift_operand" "n")]))))
5067 (set (match_operand:SI 0 "s_register_operand" "=r")
5068 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5069 (match_dup 4)])))]
5070 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5071 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5072 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5073 "ldr%?\\t%5, [%0, -%3%S2]!"
9c08d1fa 5074[(set_attr "type" "load")])
5075
5076(define_insn ""
5077 [(set (match_operand:HI 5 "s_register_operand" "=r")
5078 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5079 [(match_operand:SI 3 "s_register_operand" "r")
5080 (match_operand:SI 4 "const_shift_operand" "n")])
5081 (match_operand:SI 1 "s_register_operand" "0"))))
5082 (set (match_operand:SI 0 "s_register_operand" "=r")
5083 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5084 (match_dup 1)))]
c7597b5d 5085 "(! BYTES_BIG_ENDIAN)
25f7a26e 5086 && ! TARGET_SHORT_BY_BYTES
c7597b5d 5087 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 5088 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5089 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5090 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
9c08d1fa 5091[(set_attr "type" "load")])
5092
5093(define_insn ""
5094 [(set (match_operand:HI 5 "s_register_operand" "=r")
5095 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5096 (match_operator:SI 2 "shift_operator"
5097 [(match_operand:SI 3 "s_register_operand" "r")
5098 (match_operand:SI 4 "const_shift_operand" "n")]))))
5099 (set (match_operand:SI 0 "s_register_operand" "=r")
5100 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5101 (match_dup 4)])))]
c7597b5d 5102 "(! BYTES_BIG_ENDIAN)
25f7a26e 5103 && ! TARGET_SHORT_BY_BYTES
c7597b5d 5104 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9c08d1fa 5105 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5106 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
87b22bf7 5107 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
9c08d1fa 5108[(set_attr "type" "load")])
5109
5110; It can also support extended post-inc expressions, but combine doesn't
5111; try these....
5112; It doesn't seem worth adding peepholes for anything but the most common
5113; cases since, unlike combine, the increment must immediately follow the load
5114; for this pattern to match.
5115; When loading we must watch to see that the base register isn't trampled by
5116; the load. In such cases this isn't a post-inc expression.
5117
5118(define_peephole
5119 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5120 (match_operand:QI 2 "s_register_operand" "r"))
5121 (set (match_dup 0)
5122 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5123 ""
c7597b5d 5124 "str%?b\\t%2, [%0], %1")
9c08d1fa 5125
5126(define_peephole
5127 [(set (match_operand:QI 0 "s_register_operand" "=r")
5128 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5129 (set (match_dup 1)
5130 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5131 "REGNO(operands[0]) != REGNO(operands[1])
5132 && (GET_CODE (operands[2]) != REG
5133 || REGNO(operands[0]) != REGNO (operands[2]))"
40dbec34 5134 "ldr%?b\\t%0, [%1], %2")
9c08d1fa 5135
5136(define_peephole
5137 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5138 (match_operand:SI 2 "s_register_operand" "r"))
5139 (set (match_dup 0)
5140 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5141 ""
40dbec34 5142 "str%?\\t%2, [%0], %1")
9c08d1fa 5143
5144(define_peephole
5145 [(set (match_operand:HI 0 "s_register_operand" "=r")
5146 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5147 (set (match_dup 1)
5148 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
c7597b5d 5149 "(! BYTES_BIG_ENDIAN)
25f7a26e 5150 && ! TARGET_SHORT_BY_BYTES
c7597b5d 5151 && REGNO(operands[0]) != REGNO(operands[1])
9c08d1fa 5152 && (GET_CODE (operands[2]) != REG
5153 || REGNO(operands[0]) != REGNO (operands[2]))"
40dbec34 5154 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
9c08d1fa 5155
5156(define_peephole
5157 [(set (match_operand:SI 0 "s_register_operand" "=r")
5158 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5159 (set (match_dup 1)
5160 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5161 "REGNO(operands[0]) != REGNO(operands[1])
5162 && (GET_CODE (operands[2]) != REG
5163 || REGNO(operands[0]) != REGNO (operands[2]))"
40dbec34 5164 "ldr%?\\t%0, [%1], %2")
9c08d1fa 5165
c7597b5d 5166(define_peephole
5167 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5168 (match_operand:SI 1 "index_operand" "rJ")))
5169 (match_operand:QI 2 "s_register_operand" "r"))
5170 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5171 ""
5172 "str%?b\\t%2, [%0, %1]!")
5173
5174(define_peephole
5175 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5176 [(match_operand:SI 0 "s_register_operand" "r")
87b22bf7 5177 (match_operand:SI 1 "const_int_operand" "n")])
c7597b5d 5178 (match_operand:SI 2 "s_register_operand" "+r")))
5179 (match_operand:QI 3 "s_register_operand" "r"))
5180 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5181 (match_dup 2)))]
5182 ""
87b22bf7 5183 "str%?b\\t%3, [%2, %0%S4]!")
c7597b5d 5184
9c08d1fa 5185; This pattern is never tried by combine, so do it as a peephole
5186
5187(define_peephole
5188 [(set (match_operand:SI 0 "s_register_operand" "=r")
5189 (match_operand:SI 1 "s_register_operand" "r"))
5190 (set (match_operand 2 "cc_register" "")
5191 (compare (match_dup 1) (const_int 0)))]
5192 ""
40dbec34 5193 "sub%?s\\t%0, %1, #0"
9c08d1fa 5194[(set_attr "conds" "set")])
5195
5196; Peepholes to spot possible load- and store-multiples, if the ordering is
5197; reversed, check that the memory references aren't volatile.
5198
5199(define_peephole
5200 [(set (match_operand:SI 0 "s_register_operand" "=r")
5201 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5202 (const_int 12))))
5203 (set (match_operand:SI 2 "s_register_operand" "=r")
5204 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5205 (set (match_operand:SI 3 "s_register_operand" "=r")
5206 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5207 (set (match_operand:SI 4 "s_register_operand" "=r")
5208 (mem:SI (match_dup 1)))]
5209 "REGNO (operands[0]) > REGNO (operands[2])
5210 && REGNO (operands[2]) > REGNO (operands[3])
5211 && REGNO (operands[3]) > REGNO (operands[4])
5212 && !(REGNO (operands[1]) == REGNO (operands[0])
5213 || REGNO (operands[1]) == REGNO (operands[2])
5214 || REGNO (operands[1]) == REGNO (operands[3])
5215 || REGNO (operands[1]) == REGNO (operands[4]))
5216 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5217 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5218 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5219 (prev_nonnote_insn (insn)))))
5220 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5221 (prev_nonnote_insn
5222 (prev_nonnote_insn (insn))))))"
40dbec34 5223 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
9c08d1fa 5224
5225(define_peephole
5226 [(set (match_operand:SI 0 "s_register_operand" "=r")
5227 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5228 (const_int 8))))
5229 (set (match_operand:SI 2 "s_register_operand" "=r")
5230 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5231 (set (match_operand:SI 3 "s_register_operand" "=r")
5232 (mem:SI (match_dup 1)))]
5233 "REGNO (operands[0]) > REGNO (operands[2])
5234 && REGNO (operands[2]) > REGNO (operands[3])
5235 && !(REGNO (operands[1]) == REGNO (operands[0])
5236 || REGNO (operands[1]) == REGNO (operands[2])
5237 || REGNO (operands[1]) == REGNO (operands[3]))
5238 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5239 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5240 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5241 (prev_nonnote_insn (insn)))))"
40dbec34 5242 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
9c08d1fa 5243
5244(define_peephole
5245 [(set (match_operand:SI 0 "s_register_operand" "=r")
5246 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5247 (const_int 4))))
5248 (set (match_operand:SI 2 "s_register_operand" "=r")
5249 (mem:SI (match_dup 1)))]
5250 "REGNO (operands[0]) > REGNO (operands[2])
5251 && !(REGNO (operands[1]) == REGNO (operands[0])
5252 || REGNO (operands[1]) == REGNO (operands[2]))
5253 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5254 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
40dbec34 5255 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
9c08d1fa 5256
5257(define_peephole
5258 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5259 (const_int 12)))
5260 (match_operand:SI 0 "s_register_operand" "r"))
5261 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5262 (match_operand:SI 2 "s_register_operand" "r"))
5263 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5264 (match_operand:SI 3 "s_register_operand" "r"))
5265 (set (mem:SI (match_dup 1))
5266 (match_operand:SI 4 "s_register_operand" "r"))]
5267 "REGNO (operands[0]) > REGNO (operands[2])
5268 && REGNO (operands[2]) > REGNO (operands[3])
5269 && REGNO (operands[3]) > REGNO (operands[4])
5270 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5271 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5272 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5273 (prev_nonnote_insn (insn)))))
5274 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5275 (prev_nonnote_insn
5276 (prev_nonnote_insn (insn))))))"
40dbec34 5277 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
9c08d1fa 5278
5279(define_peephole
5280 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5281 (const_int 8)))
5282 (match_operand:SI 0 "s_register_operand" "r"))
5283 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5284 (match_operand:SI 2 "s_register_operand" "r"))
5285 (set (mem:SI (match_dup 1))
5286 (match_operand:SI 3 "s_register_operand" "r"))]
5287 "REGNO (operands[0]) > REGNO (operands[2])
5288 && REGNO (operands[2]) > REGNO (operands[3])
5289 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5290 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5291 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5292 (prev_nonnote_insn (insn)))))"
40dbec34 5293 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
9c08d1fa 5294
5295(define_peephole
5296 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5297 (const_int 4)))
5298 (match_operand:SI 0 "s_register_operand" "r"))
5299 (set (mem:SI (match_dup 1))
5300 (match_operand:SI 2 "s_register_operand" "r"))]
5301 "REGNO (operands[0]) > REGNO (operands[2])
5302 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5303 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
40dbec34 5304 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
9c08d1fa 5305
5306;; A call followed by return can be replaced by restoring the regs and
5307;; jumping to the subroutine, provided we aren't passing the address of
5308;; any of our local variables. If we call alloca then this is unsafe
5309;; since restoring the frame frees the memory, which is not what we want.
5310;; Sometimes the return might have been targeted by the final prescan:
01cc3b75 5311;; if so then emit a proper return insn as well.
9c08d1fa 5312;; Unfortunately, if the frame pointer is required, we don't know if the
5313;; current function has any implicit stack pointer adjustments that will
5314;; be restored by the return: we can't therefore do a tail call.
5315;; Another unfortunate that we can't handle is if current_function_args_size
5316;; is non-zero: in this case elimination of the argument pointer assumed
5317;; that lr was pushed onto the stack, so eliminating upsets the offset
5318;; calculations.
5319
5320(define_peephole
5321 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5322 (match_operand:SI 1 "general_operand" "g"))
5323 (clobber (reg:SI 14))])
5324 (return)]
5325 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5326 && !get_frame_size () && !current_function_calls_alloca
5327 && !frame_pointer_needed && !current_function_args_size)"
5328 "*
5329{
5330 extern rtx arm_target_insn;
5331 extern int arm_ccfsm_state, arm_current_cc;
5332
5333 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5334 {
5335 arm_current_cc ^= 1;
5336 output_return_instruction (NULL, TRUE);
5337 arm_ccfsm_state = 0;
5338 arm_target_insn = NULL;
5339 }
5340
5341 output_return_instruction (NULL, FALSE);
40dbec34 5342 return \"b%?\\t%a0\";
9c08d1fa 5343}"
5344[(set (attr "conds")
5345 (if_then_else (eq_attr "cpu" "arm6")
5346 (const_string "clob")
5347 (const_string "nocond")))
094e994f 5348 (set_attr "length" "8")])
9c08d1fa 5349
5350(define_peephole
5351 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5352 (call (mem:SI (match_operand:SI 1 "" "i"))
5353 (match_operand:SI 2 "general_operand" "g")))
5354 (clobber (reg:SI 14))])
5355 (return)]
5356 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5357 && !get_frame_size () && !current_function_calls_alloca
5358 && !frame_pointer_needed && !current_function_args_size)"
5359 "*
5360{
5361 extern rtx arm_target_insn;
5362 extern int arm_ccfsm_state, arm_current_cc;
5363
5364 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5365 {
5366 arm_current_cc ^= 1;
5367 output_return_instruction (NULL, TRUE);
5368 arm_ccfsm_state = 0;
5369 arm_target_insn = NULL;
5370 }
5371
5372 output_return_instruction (NULL, FALSE);
40dbec34 5373 return \"b%?\\t%a1\";
9c08d1fa 5374}"
5375[(set (attr "conds")
5376 (if_then_else (eq_attr "cpu" "arm6")
5377 (const_string "clob")
5378 (const_string "nocond")))
094e994f 5379 (set_attr "length" "8")])
9c08d1fa 5380
5381;; As above but when this function is not void, we must be returning the
5382;; result of the called subroutine.
5383
5384(define_peephole
5385 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5386 (call (mem:SI (match_operand:SI 1 "" "i"))
5387 (match_operand:SI 2 "general_operand" "g")))
5388 (clobber (reg:SI 14))])
5389 (use (match_dup 0))
5390 (return)]
5391 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5392 && !get_frame_size () && !current_function_calls_alloca
5393 && !frame_pointer_needed && !current_function_args_size)"
5394 "*
5395{
5396 extern rtx arm_target_insn;
5397 extern int arm_ccfsm_state, arm_current_cc;
5398
5399 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5400 {
5401 arm_current_cc ^= 1;
5402 output_return_instruction (NULL, TRUE);
5403 arm_ccfsm_state = 0;
5404 arm_target_insn = NULL;
5405 }
5406
5407 output_return_instruction (NULL, FALSE);
40dbec34 5408 return \"b%?\\t%a1\";
9c08d1fa 5409}"
5410[(set (attr "conds")
5411 (if_then_else (eq_attr "cpu" "arm6")
5412 (const_string "clob")
5413 (const_string "nocond")))
094e994f 5414 (set_attr "length" "8")])
9c08d1fa 5415
5416;; If calling a subroutine and then jumping back to somewhere else, but not
5417;; too far away, then we can set the link register with the branch address
5418;; and jump direct to the subroutine. On return from the subroutine
5419;; execution continues at the branch; this avoids a prefetch stall.
5420;; We use the length attribute (via short_branch ()) to establish whether or
01cc3b75 5421;; not this is possible, this is the same as the sparc does.
9c08d1fa 5422
5423(define_peephole
5424 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5425 (match_operand:SI 1 "general_operand" "g"))
5426 (clobber (reg:SI 14))])
5427 (set (pc)
5428 (label_ref (match_operand 2 "" "")))]
048b40f1 5429 "0 && GET_CODE (operands[0]) == SYMBOL_REF
9c08d1fa 5430 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5431 && arm_insn_not_targeted (insn)"
5432 "*
5433{
5434 int backward = arm_backwards_branch (INSN_UID (insn),
5435 INSN_UID (operands[2]));
5436
5437#if 0
5438 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5439 * above, leaving it out means that the code will still run on an arm 2 or 3
5440 */
5441 if (TARGET_6)
5442 {
5443 if (backward)
899850b0 5444 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
9c08d1fa 5445 else
899850b0 5446 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
9c08d1fa 5447 }
5448 else
5449#endif
5450 {
899850b0 5451 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
9c08d1fa 5452 if (backward)
899850b0 5453 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
9c08d1fa 5454 else
899850b0 5455 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
9c08d1fa 5456 }
40dbec34 5457 return \"b%?\\t%a0\";
9c08d1fa 5458}"
5459[(set (attr "conds")
5460 (if_then_else (eq_attr "cpu" "arm6")
5461 (const_string "clob")
5462 (const_string "nocond")))
5463 (set (attr "length")
5464 (if_then_else (eq_attr "cpu" "arm6")
094e994f 5465 (const_int 8)
5466 (const_int 12)))])
9c08d1fa 5467
5468(define_peephole
5469 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5470 (call (mem:SI (match_operand:SI 1 "" "i"))
5471 (match_operand:SI 2 "general_operand" "g")))
5472 (clobber (reg:SI 14))])
5473 (set (pc)
5474 (label_ref (match_operand 3 "" "")))]
048b40f1 5475 "0 && GET_CODE (operands[0]) == SYMBOL_REF
9c08d1fa 5476 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5477 && arm_insn_not_targeted (insn)"
5478 "*
5479{
5480 int backward = arm_backwards_branch (INSN_UID (insn),
5481 INSN_UID (operands[3]));
5482
5483#if 0
5484 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5485 * above, leaving it out means that the code will still run on an arm 2 or 3
5486 */
5487 if (TARGET_6)
5488 {
5489 if (backward)
899850b0 5490 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
9c08d1fa 5491 else
899850b0 5492 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
9c08d1fa 5493 }
5494 else
5495#endif
5496 {
899850b0 5497 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
9c08d1fa 5498 if (backward)
899850b0 5499 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
9c08d1fa 5500 else
899850b0 5501 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
9c08d1fa 5502 }
40dbec34 5503 return \"b%?\\t%a1\";
9c08d1fa 5504}"
5505[(set (attr "conds")
5506 (if_then_else (eq_attr "cpu" "arm6")
5507 (const_string "clob")
5508 (const_string "nocond")))
5509 (set (attr "length")
5510 (if_then_else (eq_attr "cpu" "arm6")
094e994f 5511 (const_int 8)
5512 (const_int 12)))])
9c08d1fa 5513
5514(define_split
5515 [(set (pc)
5516 (if_then_else (match_operator 0 "comparison_operator"
5517 [(match_operator:SI 1 "shift_operator"
5518 [(match_operand:SI 2 "s_register_operand" "r")
87b22bf7 5519 (match_operand:SI 3 "reg_or_int_operand" "rM")])
9c08d1fa 5520 (match_operand:SI 4 "s_register_operand" "r")])
5521 (label_ref (match_operand 5 "" ""))
5522 (pc)))
5523 (clobber (reg 24))]
5524 ""
5525 [(set (reg:CC 24)
5526 (compare:CC (match_dup 4)
5527 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5528 (set (pc)
5529 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5530 (label_ref (match_dup 5))
5531 (pc)))]
5532 "
5533 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5534 operands[1], operands[2]);
5535")
5536
5537(define_split
5538 [(set (match_operand:SI 0 "s_register_operand" "")
5539 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5540 (const_int 0))
5541 (neg:SI (match_operator:SI 2 "comparison_operator"
5542 [(match_operand:SI 3 "s_register_operand" "")
5543 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5544 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5545 ""
5546 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5547 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5548 (match_dup 5)))]
5549 "")
5550
5551;; This pattern can be used because cc_noov mode implies that the following
5552;; branch will be an equality (EQ or NE), so the sign extension is not
5553;; needed. Combine doesn't eliminate these because by the time it sees the
5554;; branch it no-longer knows that the data came from memory.
5555
5556(define_insn ""
5557 [(set (reg:CC_NOOV 24)
5558 (compare:CC_NOOV
5559 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5560 (const_int 24))
5561 (match_operand 1 "immediate_operand" "I")))
5562 (clobber (match_scratch:SI 2 "=r"))]
5563 "((unsigned long) INTVAL (operands[1]))
5564 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5565 "*
5566 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
40dbec34 5567 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5568 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
e2348bcb 5569 return \"\";
9c08d1fa 5570"
5571[(set_attr "conds" "set")
094e994f 5572 (set_attr "length" "8")
9c08d1fa 5573 (set_attr "type" "load")])
5574
87b22bf7 5575(define_expand "prologue"
5576 [(clobber (const_int 0))]
5577 ""
5578 "
5579 arm_expand_prologue ();
5580 DONE;
5581")
5582
9c08d1fa 5583;; This split is only used during output to reduce the number of patterns
5584;; that need assembler instructions adding to them. We allowed the setting
5585;; of the conditions to be implicit during rtl generation so that
5586;; the conditional compare patterns would work. However this conflicts to
5587;; some extend with the conditional data operations, so we have to split them
5588;; up again here.
5589
5590(define_split
5591 [(set (match_operand:SI 0 "s_register_operand" "")
5592 (if_then_else:SI (match_operator 1 "comparison_operator"
5593 [(match_operand 2 "" "") (match_operand 3 "" "")])
5594 (match_operand 4 "" "")
5595 (match_operand 5 "" "")))
5596 (clobber (reg 24))]
5597 "reload_completed"
5598 [(set (match_dup 6) (match_dup 7))
5599 (set (match_dup 0)
5600 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5601 (match_dup 4)
5602 (match_dup 5)))]
5603 "
5604{
5605 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5606 operands[3]);
5607
5608 operands[6] = gen_rtx (REG, mode, 24);
5609 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5610}
5611")
5612
5613
5614(define_insn ""
5615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5616 (if_then_else:SI (match_operator 4 "comparison_operator"
4d61e570 5617 [(match_operand 3 "reversible_cc_register" "")
5618 (const_int 0)])
9c08d1fa 5619 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5620 (not:SI
5621 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5622 ""
e2348bcb 5623 "@
899850b0 5624 mvn%D4\\t%0, %2
5625 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
9c08d1fa 5626[(set_attr "conds" "use")
094e994f 5627 (set_attr "length" "4,8")])
9c08d1fa 5628
5629;; The next two patterns occur when an AND operation is followed by a
5630;; scc insn sequence
5631
5632(define_insn ""
5633 [(set (match_operand:SI 0 "s_register_operand" "=r")
5634 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5635 (const_int 1)
5636 (match_operand:SI 2 "immediate_operand" "n")))]
5637 ""
5638 "*
5639 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
e2348bcb 5640 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5641 return \"mvnne\\t%0, #0\";
9c08d1fa 5642"
5643[(set_attr "conds" "clob")
094e994f 5644 (set_attr "length" "8")])
9c08d1fa 5645
5646(define_insn ""
5647 [(set (match_operand:SI 0 "s_register_operand" "=r")
5648 (not:SI
5649 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5650 (const_int 1)
5651 (match_operand:SI 2 "immediate_operand" "n"))))]
5652 ""
5653 "*
5654 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
e2348bcb 5655 output_asm_insn (\"tst\\t%1, %2\", operands);
5656 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5657 return \"movne\\t%0, #0\";
9c08d1fa 5658"
5659[(set_attr "conds" "clob")
094e994f 5660 (set_attr "length" "12")])
87b22bf7 5661
5662;; Push multiple registers to the stack. The first register is in the
5663;; unspec part of the insn; subsequent registers are in parallel (use ...)
5664;; expressions.
5665(define_insn ""
5666 [(match_parallel 2 "multi_register_push"
5667 [(set (match_operand:BLK 0 "memory_operand" "=m")
5668 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5669 ""
5670 "*
5671{
5672 char pattern[100];
5673 int i;
5674 extern int lr_save_eliminated;
5675
5676 if (lr_save_eliminated)
5677 {
5678 if (XVECLEN (operands[2], 0) > 1)
5679 abort ();
5680 return \"\";
5681 }
5682 strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5683 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5684 {
5685 strcat (pattern, \", %|\");
5686 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5687 0))]);
5688 }
5689 strcat (pattern, \"}\");
5690 output_asm_insn (pattern, operands);
5691 return \"\";
5692}"
5693[(set_attr "type" "store4")])