1 ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
2 ;; Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
7 ;; This file is part of GNU CC.
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)
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.
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.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; There are patterns in this file to support XFmode arithmetic.
26 ;; Unfortunately RISC iX doesn't work well with these so they are disabled.
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
34 ;; 2 `push multiple' operation: operand 0 is the first register. Subsequent
35 ;; registers are in parallel (use...) expressions.
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.
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
47 ; SET means that the purpose of the insn is to set the condition codes in a
48 ; well defined manner.
50 ; CLOB means that the condition codes are altered in an undefined manner, if
51 ; they are altered at all
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.
57 ; NOCOND means that the condition codes are niether altered nor affect the
60 (define_attr "conds" "use,set,clob,jump_clob,nocond"
61 (const_string "nocond"))
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.
67 (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
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).
73 (define_attr "fpu" "fpa,fpe" (const (symbol_ref "arm_fpu_attr")))
75 ; LENGTH of an instruction (in bytes)
76 (define_attr "length" "" (const_int 4))
78 ; An assembler sequence may clobber the condition codes without us knowing
79 (define_asm_attributes
80 [(set_attr "conds" "clob")
81 (set_attr "length" "4")])
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.
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)
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)
99 ; float_em a floating point arithmetic operation that is normally emulated
100 ; even on a machine with an fpa.
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
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"
116 (const_string "normal"))
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")
122 (const_string "no")))
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.
134 ;; (define_function_unit {name} {num-units} {n-users} {test}
135 ;; {ready-delay} {issue-delay} [{conflict-list}])
136 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
137 (eq_attr "type" "fdivx")) 71 69)
139 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
140 (eq_attr "type" "fdivd")) 59 57)
142 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
143 (eq_attr "type" "fdivs")) 31 29)
145 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
146 (eq_attr "type" "fmul")) 9 7)
148 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
149 (eq_attr "type" "ffmul")) 6 4)
151 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
152 (eq_attr "type" "farith")) 4 2)
154 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
155 (eq_attr "type" "ffarith")) 2 2)
157 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
158 (eq_attr "type" "r_2_f")) 5 3)
160 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
161 (eq_attr "type" "f_2_r")) 1 2)
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.
168 (define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
169 (eq_attr "type" "f_load")) 3 1)
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")])
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.
188 (define_insn "adddi3"
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))]
194 "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
195 [(set_attr "conds" "clob")
196 (set_attr "length" "8")])
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))]
205 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
206 [(set_attr "conds" "clob")
207 (set_attr "length" "8")])
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))]
216 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
217 [(set_attr "conds" "clob")
218 (set_attr "length" "8")])
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" "")))]
226 if (GET_CODE (operands[2]) == CONST_INT)
228 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
230 (reload_in_progress || reload_completed ? 0
231 : preserve_subexpressions_p ()));
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))]
244 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
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")))]
258 [(set_attr "length" "4,4,16")])
261 [(set (reg:CC_NOOV 24)
263 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
264 (match_operand:SI 2 "arm_add_operand" "rI,L"))
266 (set (match_operand:SI 0 "s_register_operand" "=r,r")
267 (plus:SI (match_dup 1) (match_dup 2)))]
271 sub%?s\\t%0, %1, #%n2"
272 [(set_attr "conds" "set")])
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")
279 (plus:SI (match_dup 1) (match_dup 2)))]
283 sub%?s\\t%0, %1, #%n2"
284 [(set_attr "conds" "set")])
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")))]
294 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
295 [(set_attr "conds" "use")
296 (set_attr "length" "4,8")])
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.
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)))]
312 unsigned int val = (unsigned) INTVAL (operands[2]);
316 /* this code is similar to the approach followed in movsi, but it must
317 generate exactly two insns */
319 for (i = 30; i >= 0; i -= 2)
325 if (const_ok_for_arm (temp = (val & ~(255 << i))))
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)
335 temp = ((val >> i) & 255) + 1;
337 if (const_ok_for_arm ((temp << i) - val))
340 temp = (unsigned) - (int) (i - val);
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);
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")))]
361 suf%?s\\t%0, %1, #%N2"
362 [(set_attr "type" "farith")])
364 (define_insn "adddf3"
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")))]
371 suf%?d\\t%0, %1, #%N2"
372 [(set_attr "type" "farith")])
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")))]
382 suf%?d\\t%0, %1, #%N2"
383 [(set_attr "type" "farith")])
386 [(set (match_operand:DF 0 "s_register_operand" "=f")
387 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
389 (match_operand:SF 2 "s_register_operand" "f"))))]
391 "adf%?d\\t%0, %1, %2"
392 [(set_attr "type" "farith")])
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"))
399 (match_operand:SF 2 "s_register_operand" "f"))))]
401 "adf%?d\\t%0, %1, %2"
402 [(set_attr "type" "farith")])
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")))]
411 suf%?e\\t%0, %1, #%N2"
412 [(set_attr "type" "farith")])
414 (define_insn "subdi3"
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))]
420 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
421 [(set_attr "conds" "clob")
422 (set_attr "length" "8")])
425 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
426 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
428 (match_operand:SI 2 "s_register_operand" "r,r"))))
429 (clobber (reg:CC 24))]
431 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
432 [(set_attr "conds" "clob")
433 (set_attr "length" "8")])
436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
437 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
439 (match_operand:SI 2 "s_register_operand" "r,r"))))
440 (clobber (reg:CC 24))]
442 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
443 [(set_attr "conds" "clob")
444 (set_attr "length" "8")])
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))]
453 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
454 [(set_attr "conds" "clob")
455 (set_attr "length" "8")])
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))]
464 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
465 [(set_attr "conds" "clob")
466 (set_attr "length" "8")])
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"))
473 (match_operand:SI 2 "s_register_operand" "r"))))
474 (clobber (reg:CC 24))]
476 "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
477 [(set_attr "conds" "clob")
478 (set_attr "length" "8")])
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" "")))]
486 if (GET_CODE (operands[1]) == CONST_INT)
488 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
490 (reload_in_progress || reload_completed ? 0
491 : preserve_subexpressions_p ()));
497 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
498 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
499 (match_operand:SI 2 "s_register_operand" "r,r")))]
504 [(set_attr "length" "4,16")])
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))]
513 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
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"))
523 (set (match_operand:SI 0 "s_register_operand" "=r,r")
524 (minus:SI (match_dup 1) (match_dup 2)))]
529 [(set_attr "conds" "set")])
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)])))]
539 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
540 [(set_attr "conds" "use")
541 (set_attr "length" "*,8")])
543 (define_insn "subsf3"
544 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
545 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
546 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
551 [(set_attr "type" "farith")])
553 (define_insn "subdf3"
554 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
555 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
556 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
561 [(set_attr "type" "farith")])
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")))]
569 "suf%?d\\t%0, %1, %2"
570 [(set_attr "type" "farith")])
573 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
574 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
576 (match_operand:SF 2 "s_register_operand" "f,f"))))]
581 [(set_attr "type" "farith")])
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"))
588 (match_operand:SF 2 "s_register_operand" "f"))))]
590 "suf%?d\\t%0, %1, %2"
591 [(set_attr "type" "farith")])
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")))]
601 [(set_attr "type" "farith")])
603 ;; Multiplication insns
605 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
606 (define_insn "mulsi3"
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")))]
611 "mul%?\\t%0, %2, %1")
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"))
619 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
620 (mult:SI (match_dup 2) (match_dup 1)))]
622 "mul%?s\\t%0, %2, %1"
623 [(set_attr "conds" "set")])
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"))
631 (clobber (match_scratch:SI 0 "=&r,&r"))]
633 "mul%?s\\t%0, %2, %1"
634 [(set_attr "conds" "set")])
636 ;; Unnamed templates to match MLA instruction.
639 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
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")))]
645 "mla%?\\t%0, %2, %1, %3")
648 [(set (reg:CC_NOOV 24)
649 (compare:CC_NOOV (plus: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"))
655 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
656 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
659 "mla%?s\\t%0, %2, %1, %3"
660 [(set_attr "conds" "set")])
663 [(set (reg:CC_NOOV 24)
664 (compare:CC_NOOV (plus: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"))
670 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
672 "mla%?s\\t%0, %2, %1, %3"
673 [(set_attr "conds" "set")])
675 (define_insn "mulsf3"
676 [(set (match_operand:SF 0 "s_register_operand" "=f")
677 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
678 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
680 "fml%?s\\t%0, %1, %2"
681 [(set_attr "type" "ffmul")])
683 (define_insn "muldf3"
684 [(set (match_operand:DF 0 "s_register_operand" "=f")
685 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
686 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
688 "muf%?d\\t%0, %1, %2"
689 [(set_attr "type" "fmul")])
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")))]
697 "muf%?d\\t%0, %1, %2"
698 [(set_attr "type" "fmul")])
701 [(set (match_operand:DF 0 "s_register_operand" "=f")
702 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
704 (match_operand:SF 2 "s_register_operand" "f"))))]
706 "muf%?d\\t%0, %1, %2"
707 [(set_attr "type" "fmul")])
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"))
714 (match_operand:SF 2 "s_register_operand" "f"))))]
716 "muf%?d\\t%0, %1, %2"
717 [(set_attr "type" "fmul")])
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")))]
724 "muf%?e\\t%0, %1, %2"
725 [(set_attr "type" "fmul")])
729 (define_insn "divsf3"
730 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
731 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
732 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
737 [(set_attr "type" "fdivs")])
739 (define_insn "divdf3"
740 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
741 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
742 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
747 [(set_attr "type" "fdivd")])
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")))]
755 "dvf%?d\\t%0, %1, %2"
756 [(set_attr "type" "fdivd")])
759 [(set (match_operand:DF 0 "s_register_operand" "=f")
760 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
762 (match_operand:SF 2 "s_register_operand" "f"))))]
764 "rdf%?d\\t%0, %2, %1"
765 [(set_attr "type" "fdivd")])
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"))
772 (match_operand:SF 2 "s_register_operand" "f"))))]
774 "dvf%?d\\t%0, %1, %2"
775 [(set_attr "type" "fdivd")])
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")))]
785 [(set_attr "type" "fdivx")])
789 (define_insn "modsf3"
790 [(set (match_operand:SF 0 "s_register_operand" "=f")
791 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
792 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
794 "rmf%?s\\t%0, %1, %2"
795 [(set_attr "type" "fdivs")])
797 (define_insn "moddf3"
798 [(set (match_operand:DF 0 "s_register_operand" "=f")
799 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
800 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
802 "rmf%?d\\t%0, %1, %2"
803 [(set_attr "type" "fdivd")])
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")))]
811 "rmf%?d\\t%0, %1, %2"
812 [(set_attr "type" "fdivd")])
815 [(set (match_operand:DF 0 "s_register_operand" "=f")
816 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
818 (match_operand:SF 2 "s_register_operand" "f"))))]
820 "rmf%?d\\t%0, %1, %2"
821 [(set_attr "type" "fdivd")])
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"))
828 (match_operand:SF 2 "s_register_operand" "f"))))]
830 "rmf%?d\\t%0, %1, %2"
831 [(set_attr "type" "fdivd")])
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")))]
838 "rmf%?e\\t%0, %1, %2"
839 [(set_attr "type" "fdivx")])
841 ;; Boolean and,ior,xor insns
843 (define_insn "anddi3"
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")))]
848 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
849 [(set_attr "length" "8")])
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")))]
857 "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
858 [(set_attr "length" "8")])
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")))]
866 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
867 [(set_attr "length" "8")])
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" "")))]
875 if (GET_CODE (operands[2]) == CONST_INT)
877 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
879 (reload_in_progress || reload_completed
880 ? 0 : preserve_subexpressions_p ()));
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")))]
894 [(set_attr "length" "4,4,16")])
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))]
904 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
910 [(set (reg:CC_NOOV 24)
912 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
913 (match_operand:SI 2 "arm_not_operand" "rI,K"))
915 (set (match_operand:SI 0 "s_register_operand" "=r,r")
916 (and:SI (match_dup 1) (match_dup 2)))]
920 bic%?s\\t%0, %1, #%B2"
921 [(set_attr "conds" "set")])
924 [(set (reg:CC_NOOV 24)
926 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
927 (match_operand:SI 1 "arm_not_operand" "rI,K"))
929 (clobber (match_scratch:SI 3 "=X,r"))]
933 bic%?s\\t%3, %0, #%B1"
934 [(set_attr "conds" "set")])
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"))
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"
949 unsigned int mask = 0;
950 int cnt = INTVAL (operands[1]);
953 mask = (mask << 1) | 1;
954 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
955 output_asm_insn (\"tst%?\\t%0, %1\", operands);
959 [(set_attr "conds" "set")])
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"))
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"
973 unsigned int mask = 0;
974 int cnt = INTVAL (operands[1]);
977 mask = (mask << 1) | 1;
978 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
979 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
980 output_asm_insn (\"tst%?\\t%3, %1\", operands);
984 [(set_attr "conds" "set")
985 (set_attr "length" "8")])
987 ;; constants for op 2 will never be given to these patterns.
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")))]
993 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
994 [(set_attr "length" "8")])
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")))
1000 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1004 bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1005 [(set_attr "length" "4,8")])
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")))]
1013 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
1014 [(set_attr "length" "8")])
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")))]
1021 "bic%?\\t%0, %1, %2")
1024 [(set (reg:CC_NOOV 24)
1026 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1027 (match_operand:SI 1 "s_register_operand" "r"))
1029 (set (match_operand:SI 0 "s_register_operand" "=r")
1030 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1032 "bic%?s\\t%0, %1, %2"
1033 [(set_attr "conds" "set")])
1036 [(set (reg:CC_NOOV 24)
1038 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1039 (match_operand:SI 1 "s_register_operand" "r"))
1041 (clobber (match_scratch:SI 0 "=r"))]
1043 "bic%?s\\t%0, %1, %2"
1044 [(set_attr "conds" "set")])
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")))]
1051 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
1052 [(set_attr "length" "8")])
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"))
1058 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1062 orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1063 [(set_attr "length" "4,8")])
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")))]
1071 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1072 [(set_attr "length" "8")])
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" "")))]
1080 if (GET_CODE (operands[2]) == CONST_INT)
1082 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1084 (reload_in_progress || reload_completed
1085 ? 0 : preserve_subexpressions_p ()));
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")))]
1098 [(set_attr "length" "4,16")])
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))]
1107 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
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"))
1117 (set (match_operand:SI 0 "s_register_operand" "=r")
1118 (ior:SI (match_dup 1) (match_dup 2)))]
1120 "orr%?s\\t%0, %1, %2"
1121 [(set_attr "conds" "set")])
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"))
1128 (clobber (match_scratch:SI 0 "=r"))]
1130 "orr%?s\\t%0, %1, %2"
1131 [(set_attr "conds" "set")])
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")))]
1138 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
1139 [(set_attr "length" "8")])
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"))
1145 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1149 eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1150 [(set_attr "length" "4,8")])
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")))]
1158 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1159 [(set_attr "length" "8")])
1161 (define_insn "xorsi3"
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")))]
1166 "eor%?\\t%0, %1, %2")
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"))
1173 (set (match_operand:SI 0 "s_register_operand" "=r")
1174 (xor:SI (match_dup 1) (match_dup 2)))]
1176 "eor%?s\\t%0, %1, %2"
1177 [(set_attr "conds" "set")])
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"))
1186 [(set_attr "conds" "set")])
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
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"))]
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)))]
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"))))]
1211 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1212 [(set_attr "length" "8")])
1216 ;; Minimum and maximum insns
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))]
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"
1228 [(set_attr "conds" "clob")
1229 (set_attr "length" "8,8,12")])
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))]
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"
1241 [(set_attr "conds" "clob")
1242 (set_attr "length" "8,8,12")])
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))]
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"
1254 [(set_attr "conds" "clob")
1255 (set_attr "length" "8,8,12")])
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))]
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"
1267 [(set_attr "conds" "clob")
1268 (set_attr "length" "8,8,12")])
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))]
1278 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
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);
1285 [(set_attr "conds" "clob")
1286 (set_attr "length" "12")
1287 (set_attr "type" "store1")])
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))]
1300 enum rtx_code code = GET_CODE (operands[4]);
1302 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1304 output_asm_insn (\"cmp\\t%2, %3\", operands);
1305 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1306 if (which_alternative != 0 || operands[3] != const0_rtx
1307 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1308 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1312 [(set_attr "conds" "clob")
1313 (set_attr "length" "12")])
1316 ;; Shift and rotation insns
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" "")))]
1324 if (GET_CODE (operands[2]) == CONST_INT
1325 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1327 emit_insn (gen_movsi (operands[0], const0_rtx));
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" "")))]
1338 if (GET_CODE (operands[2]) == CONST_INT
1339 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1340 operands[2] = GEN_INT (31);
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" "")))]
1349 if (GET_CODE (operands[2]) == CONST_INT
1350 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1352 emit_insn (gen_movsi (operands[0], const0_rtx));
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" "")))]
1363 if (GET_CODE (operands[2]) == CONST_INT)
1364 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1367 rtx reg = gen_reg_rtx (SImode);
1368 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
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" "")))]
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);
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")]))]
1390 "mov%?\\t%0, %1%S3")
1393 [(set (reg:CC_NOOV 24)
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")])
1398 (set (match_operand:SI 0 "s_register_operand" "=r")
1399 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1401 "mov%?s\\t%0, %1%S3"
1402 [(set_attr "conds" "set")])
1405 [(set (reg:CC_NOOV 24)
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")])
1410 (clobber (match_scratch:SI 0 "=r"))]
1412 "mov%?s\\t%0, %1%S3"
1413 [(set_attr "conds" "set")])
1416 [(set (match_operand:SI 0 "s_register_operand" "=r")
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")])))]
1421 "mvn%?\\t%0, %1%S3")
1424 [(set (reg:CC_NOOV 24)
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")]))
1429 (set (match_operand:SI 0 "s_register_operand" "=r")
1430 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1432 "mvn%?s\\t%0, %1%S3"
1433 [(set_attr "conds" "set")])
1436 [(set (reg:CC_NOOV 24)
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")]))
1441 (clobber (match_scratch:SI 0 "=r"))]
1443 "mvn%?s\\t%0, %1%S3"
1444 [(set_attr "conds" "set")])
1447 ;; Unary arithmetic insns
1449 (define_insn "negdi2"
1450 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1451 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1453 "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
1454 [(set_attr "conds" "clob")
1455 (set_attr "length" "8")])
1457 (define_insn "negsi2"
1458 [(set (match_operand:SI 0 "s_register_operand" "=r")
1459 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1461 "rsb%?\\t%0, %1, #0")
1463 (define_insn "negsf2"
1464 [(set (match_operand:SF 0 "s_register_operand" "=f")
1465 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1468 [(set_attr "type" "ffarith")])
1470 (define_insn "negdf2"
1471 [(set (match_operand:DF 0 "s_register_operand" "=f")
1472 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1475 [(set_attr "type" "ffarith")])
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"))))]
1483 [(set_attr "type" "ffarith")])
1485 (define_insn "negxf2"
1486 [(set (match_operand:XF 0 "s_register_operand" "=f")
1487 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1488 "ENABLE_XF_PATTERNS"
1490 [(set_attr "type" "ffarith")])
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
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")))
1503 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1504 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1505 [(set_attr "conds" "clob,*")
1506 (set_attr "length" "8")])
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"))))
1514 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1515 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1516 [(set_attr "conds" "clob,*")
1517 (set_attr "length" "8")])
1519 (define_insn "abssf2"
1520 [(set (match_operand:SF 0 "s_register_operand" "=f")
1521 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1524 [(set_attr "type" "ffarith")])
1526 (define_insn "absdf2"
1527 [(set (match_operand:DF 0 "s_register_operand" "=f")
1528 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1531 [(set_attr "type" "ffarith")])
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"))))]
1539 [(set_attr "type" "ffarith")])
1541 (define_insn "absxf2"
1542 [(set (match_operand:XF 0 "s_register_operand" "=f")
1543 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1544 "ENABLE_XF_PATTERNS"
1546 [(set_attr "type" "ffarith")])
1548 (define_insn "sqrtsf2"
1549 [(set (match_operand:SF 0 "s_register_operand" "=f")
1550 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1553 [(set_attr "type" "float_em")])
1555 (define_insn "sqrtdf2"
1556 [(set (match_operand:DF 0 "s_register_operand" "=f")
1557 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1560 [(set_attr "type" "float_em")])
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"))))]
1568 [(set_attr "type" "float_em")])
1570 (define_insn "sqrtxf2"
1571 [(set (match_operand:XF 0 "s_register_operand" "=f")
1572 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1573 "ENABLE_XF_PATTERNS"
1575 [(set_attr "type" "float_em")])
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))]
1582 [(set_attr "type" "float_em")])
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))]
1589 [(set_attr "type" "float_em")])
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))]
1597 [(set_attr "type" "float_em")])
1599 (define_insn "sinxf2"
1600 [(set (match_operand:XF 0 "s_register_operand" "=f")
1601 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1602 "ENABLE_XF_PATTERNS"
1604 [(set_attr "type" "float_em")])
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))]
1611 [(set_attr "type" "float_em")])
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))]
1618 [(set_attr "type" "float_em")])
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))]
1626 [(set_attr "type" "float_em")])
1628 (define_insn "cosxf2"
1629 [(set (match_operand:XF 0 "s_register_operand" "=f")
1630 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1631 "ENABLE_XF_PATTERNS"
1633 [(set_attr "type" "float_em")])
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")))]
1639 "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
1640 [(set_attr "length" "8")])
1642 (define_insn "one_cmplsi2"
1643 [(set (match_operand:SI 0 "s_register_operand" "=r")
1644 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1649 [(set (reg:CC_NOOV 24)
1650 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1652 (set (match_operand:SI 0 "s_register_operand" "=r")
1653 (not:SI (match_dup 1)))]
1656 [(set_attr "conds" "set")])
1659 [(set (reg:CC_NOOV 24)
1660 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1662 (clobber (match_scratch:SI 0 "=r"))]
1665 [(set_attr "conds" "set")])
1667 ;; Fixed <--> Floating conversion insns
1669 (define_insn "floatsisf2"
1670 [(set (match_operand:SF 0 "s_register_operand" "=f")
1671 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1674 [(set_attr "type" "r_2_f")])
1676 (define_insn "floatsidf2"
1677 [(set (match_operand:DF 0 "s_register_operand" "=f")
1678 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1681 [(set_attr "type" "r_2_f")])
1683 (define_insn "floatsixf2"
1684 [(set (match_operand:XF 0 "s_register_operand" "=f")
1685 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1686 "ENABLE_XF_PATTERNS"
1688 [(set_attr "type" "r_2_f")])
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")))]
1695 [(set_attr "type" "f_2_r")])
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")))]
1702 [(set_attr "type" "f_2_r")])
1704 (define_insn "fix_truncxfsi2"
1705 [(set (match_operand:SI 0 "s_register_operand" "=r")
1706 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1707 "ENABLE_XF_PATTERNS"
1709 [(set_attr "type" "f_2_r")])
1713 (define_insn "truncdfsf2"
1714 [(set (match_operand:SF 0 "s_register_operand" "=f")
1716 (match_operand:DF 1 "s_register_operand" "f")))]
1719 [(set_attr "type" "ffarith")])
1721 (define_insn "truncxfsf2"
1722 [(set (match_operand:SF 0 "s_register_operand" "=f")
1724 (match_operand:XF 1 "s_register_operand" "f")))]
1725 "ENABLE_XF_PATTERNS"
1727 [(set_attr "type" "ffarith")])
1729 (define_insn "truncxfdf2"
1730 [(set (match_operand:DF 0 "s_register_operand" "=f")
1732 (match_operand:XF 1 "s_register_operand" "f")))]
1733 "ENABLE_XF_PATTERNS"
1735 [(set_attr "type" "ffarith")])
1737 ;; Zero and sign extension instructions.
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")))]
1744 if (REGNO (operands[1]) != REGNO (operands[0]))
1745 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1746 return \"mov%?\\t%R0, #0\";
1748 [(set_attr "length" "8")])
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")))]
1755 and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
1756 ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
1757 [(set_attr "length" "8")
1758 (set_attr "type" "*,load")])
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")))]
1765 if (REGNO (operands[1]) != REGNO (operands[0]))
1766 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1767 return \"mov%?\\t%R0, %0, asr #31\";
1769 [(set_attr "length" "8")])
1771 (define_expand "zero_extendhisi2"
1772 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1774 (set (match_operand:SI 0 "s_register_operand" "")
1775 (lshiftrt:SI (match_dup 2) (const_int 16)))]
1778 { operands[1] = gen_lowpart (SImode, operands[1]);
1779 operands[2] = gen_reg_rtx (SImode);
1782 (define_expand "zero_extendqisi2"
1783 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1785 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1788 if (GET_CODE (operands[1]) != MEM)
1790 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
1797 [(set (match_operand:SI 0 "s_register_operand" "=r")
1798 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1800 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1801 [(set_attr "type" "load")])
1804 [(set (match_operand:SI 0 "s_register_operand" "")
1805 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
1806 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1807 "GET_CODE (operands[1]) != MEM"
1808 [(set (match_dup 2) (match_dup 1))
1809 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
1813 [(set (reg:CC_NOOV 24)
1814 (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1818 [(set_attr "conds" "set")])
1820 (define_expand "extendhisi2"
1822 (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1824 (set (match_operand:SI 0 "s_register_operand" "")
1825 (ashiftrt:SI (match_dup 2)
1829 { operands[1] = gen_lowpart (SImode, operands[1]);
1830 operands[2] = gen_reg_rtx (SImode); }")
1832 (define_expand "extendqihi2"
1834 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1836 (set (match_operand:HI 0 "s_register_operand" "")
1837 (ashiftrt:SI (match_dup 2)
1841 { operands[0] = gen_lowpart (SImode, operands[0]);
1842 operands[1] = gen_lowpart (SImode, operands[1]);
1843 operands[2] = gen_reg_rtx (SImode); }")
1845 (define_expand "extendqisi2"
1847 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1849 (set (match_operand:SI 0 "s_register_operand" "")
1850 (ashiftrt:SI (match_dup 2)
1854 { operands[1] = gen_lowpart (SImode, operands[1]);
1855 operands[2] = gen_reg_rtx (SImode); }")
1857 (define_insn "extendsfdf2"
1858 [(set (match_operand:DF 0 "s_register_operand" "=f")
1859 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
1862 [(set_attr "type" "ffarith")])
1864 (define_insn "extendsfxf2"
1865 [(set (match_operand:XF 0 "s_register_operand" "=f")
1866 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
1867 "ENABLE_XF_PATTERNS"
1869 [(set_attr "type" "ffarith")])
1871 (define_insn "extenddfxf2"
1872 [(set (match_operand:XF 0 "s_register_operand" "=f")
1873 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
1874 "ENABLE_XF_PATTERNS"
1876 [(set_attr "type" "ffarith")])
1879 ;; Move insns (including loads and stores)
1881 ;; XXX Just some ideas about movti.
1882 ;; I don't think these are a good idea on the arm, there just aren't enough
1884 ;;(define_expand "loadti"
1885 ;; [(set (match_operand:TI 0 "s_register_operand" "")
1886 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
1889 ;;(define_expand "storeti"
1890 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
1891 ;; (match_operand:TI 1 "s_register_operand" ""))]
1894 ;;(define_expand "movti"
1895 ;; [(set (match_operand:TI 0 "general_operand" "")
1896 ;; (match_operand:TI 1 "general_operand" ""))]
1902 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1903 ;; operands[1] = copy_to_reg (operands[1]);
1904 ;; if (GET_CODE (operands[0]) == MEM)
1905 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
1906 ;; else if (GET_CODE (operands[1]) == MEM)
1907 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
1911 ;; emit_insn (insn);
1915 ;; Recognise garbage generated above.
1918 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
1919 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
1923 ;; register mem = (which_alternative < 3);
1924 ;; register char *template;
1926 ;; operands[mem] = XEXP (operands[mem], 0);
1927 ;; switch (which_alternative)
1929 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
1930 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
1931 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
1932 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
1933 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
1934 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
1936 ;; output_asm_insn (template, operands);
1941 (define_insn "movdi"
1942 [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
1943 (match_operand:DI 1 "di_operand" "rIK,n,o<>,r,F"))]
1946 return (output_move_double (operands));
1948 [(set_attr "length" "8,32,8,8,32")
1949 (set_attr "type" "*,*,load,store2,*")])
1951 (define_expand "movsi"
1952 [(set (match_operand:SI 0 "general_operand" "")
1953 (match_operand:SI 1 "general_operand" ""))]
1956 /* Everything except mem = const or mem = mem can be done easily */
1957 if (GET_CODE (operands[0]) == MEM)
1958 operands[1] = force_reg (SImode, operands[1]);
1959 if (GET_CODE (operands[1]) == CONST_INT
1960 && !(const_ok_for_arm (INTVAL (operands[1]))
1961 || const_ok_for_arm (~INTVAL (operands[1]))))
1963 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
1965 (reload_in_progress || reload_completed ? 0
1966 : preserve_subexpressions_p ()));
1972 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r,r")
1973 (match_operand:SI 1 "general_operand" "R,m,K,rI,r,S,?n"))]
1974 "(register_operand (operands[0], SImode)
1975 && (GET_CODE (operands[1]) != SYMBOL_REF
1976 || CONSTANT_ADDRESS_P (operands[1])))
1977 || register_operand (operands[1], SImode)"
1979 switch (which_alternative)
1982 /* NB Calling get_attr_length may cause the insn to be re-extracted... */
1983 if (get_attr_length (insn) == 8)
1985 /* ... so modify the operands here. */
1986 operands[1] = XEXP (operands[1], 0);
1987 output_asm_insn (\"sub%?\\t%0, %|pc, #(8 + . - %a1) & ~4095\",
1989 output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
1995 operands[1] = XEXP (operands[1], 0);
1996 output_asm_insn (\"ldr%?\\t%0, [%|pc, %1 - . - 8]\", operands);
2001 if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2002 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
2004 return \"ldr%?\\t%0, %1\";
2007 return \"mov%?\\t%0, %1\";
2009 return \"mvn%?\\t%0, #%B1\";
2011 return \"str%?\\t%1, %0\";
2013 return output_load_symbol (insn, operands);
2018 [(set (attr "length")
2019 (cond [(eq_attr "alternative" "0")
2023 (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
2027 (ior (eq_attr "alternative" "5")
2028 (eq_attr "alternative" "6")) (const_int 16)]
2030 (set_attr "type" "load,load,*,*,store1,*,*")])
2033 [(set (match_operand:SI 0 "s_register_operand" "")
2034 (match_operand:SI 1 "const_int_operand" ""))]
2035 "! (const_ok_for_arm (INTVAL (operands[1]))
2036 || const_ok_for_arm (~INTVAL (operands[1])))"
2037 [(clobber (const_int 0))]
2039 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2044 ;; If copying one reg to another we can set the condition codes according to
2045 ;; its value. Such a move is common after a return from subroutine and the
2046 ;; result is being tested against zero.
2049 [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
2051 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2055 sub%?s\\t%0, %1, #0"
2056 [(set_attr "conds" "set")])
2058 ;; Subroutine to store a half word from a register into memory.
2059 ;; Operand 0 is the source register (HImode)
2060 ;; Operand 1 is the destination address in a register (SImode)
2062 ;; In both this routine and the next, we must be careful not to spill
2063 ;; a memory address of reg+large_const into a seperate PLUS insn, since this
2064 ;; can generate unrecognizable rtl.
2066 (define_expand "storehi"
2067 [;; store the low byte
2068 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2069 ;; extract the high byte
2071 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2072 ;; store the high byte
2073 (set (mem:QI (match_dup 4))
2074 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2078 enum rtx_code code = GET_CODE (operands[1]);
2080 if ((code == PLUS || code == MINUS)
2081 && (GET_CODE (XEXP (operands[1], 1)) == REG
2082 || GET_CODE (XEXP (operands[1], 0)) != REG))
2083 operands[1] = force_reg (SImode, operands[1]);
2084 operands[4] = plus_constant (operands[1], 1);
2085 operands[3] = gen_lowpart (QImode, operands[0]);
2086 operands[0] = gen_lowpart (SImode, operands[0]);
2087 operands[2] = gen_reg_rtx (SImode);
2091 (define_expand "storehi_bigend"
2092 [(set (mem:QI (match_dup 4)) (match_dup 3))
2094 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2095 (set (mem:QI (match_operand 1 "" ""))
2096 (subreg:QI (match_dup 2) 0))]
2100 enum rtx_code code = GET_CODE (operands[1]);
2101 if ((code == PLUS || code == MINUS)
2102 && (GET_CODE (XEXP (operands[1], 1)) == REG
2103 || GET_CODE (XEXP (operands[1], 0)) != REG))
2104 operands[1] = force_reg (SImode, operands[1]);
2106 operands[4] = plus_constant (operands[1], 1);
2107 operands[3] = gen_lowpart (QImode, operands[0]);
2108 operands[0] = gen_lowpart (SImode, operands[0]);
2109 operands[2] = gen_reg_rtx (SImode);
2113 ;; Subroutine to store a half word integer constant into memory.
2114 (define_expand "storeinthi"
2115 [(set (mem:QI (match_operand:SI 0 "" ""))
2116 (subreg:QI (match_operand 1 "" "") 0))
2117 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2121 HOST_WIDE_INT value = INTVAL (operands[1]);
2122 enum rtx_code code = GET_CODE (operands[0]);
2124 if ((code == PLUS || code == MINUS)
2125 && (GET_CODE (XEXP (operands[0], 1)) == REG
2126 || GET_CODE (XEXP (operands[0], 0)) != REG))
2127 operands[0] = force_reg (SImode, operands[0]);
2129 operands[1] = gen_reg_rtx (SImode);
2130 if (BYTES_BIG_ENDIAN)
2132 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2133 if ((value & 255) == ((value >> 8) & 255))
2134 operands[2] = operands[1];
2137 operands[2] = gen_reg_rtx (SImode);
2138 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2143 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2144 if ((value & 255) == ((value >> 8) & 255))
2145 operands[2] = operands[1];
2148 operands[2] = gen_reg_rtx (SImode);
2149 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2153 operands[3] = plus_constant (operands[0], 1);
2157 (define_expand "movhi"
2158 [(set (match_operand:HI 0 "general_operand" "")
2159 (match_operand:HI 1 "general_operand" ""))]
2165 if (! (reload_in_progress || reload_completed))
2167 if (GET_CODE (operands[0]) == MEM)
2169 if (GET_CODE (operands[1]) == CONST_INT)
2170 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
2173 if (GET_CODE (operands[1]) == MEM)
2174 operands[1] = force_reg (HImode, operands[1]);
2175 if (BYTES_BIG_ENDIAN)
2176 emit_insn (gen_storehi_bigend (operands[1],
2177 XEXP (operands[0], 0)));
2179 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
2183 /* Sign extend a constant, and keep it in an SImode reg. */
2184 else if (GET_CODE (operands[1]) == CONST_INT)
2186 rtx reg = gen_reg_rtx (SImode);
2187 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2189 /* If the constant is already valid, leave it alone. */
2190 if (! const_ok_for_arm (val))
2192 /* If setting all the top bits will make the constant
2193 loadable in a single instruction, then set them.
2194 Otherwise, sign extend the number. */
2196 if (const_ok_for_arm (~ (val | ~0xffff)))
2198 else if (val & 0x8000)
2202 emit_insn (gen_movsi (reg, GEN_INT (val)));
2203 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2205 else if (BYTES_BIG_ENDIAN && GET_CODE (operands[1]) == MEM)
2207 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2214 (define_expand "movhi_bigend"
2216 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2219 (ashiftrt:SI (match_dup 2) (const_int 16)))
2220 (set (match_operand:HI 0 "s_register_operand" "")
2221 (subreg:HI (match_dup 3) 0))]
2224 operands[2] = gen_reg_rtx (SImode);
2225 operands[3] = gen_reg_rtx (SImode);
2228 ;; Pattern to recognise insn generated default case above
2231 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2232 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2233 "(! BYTES_BIG_ENDIAN)
2234 && (GET_CODE (operands[1]) != CONST_INT
2235 || const_ok_for_arm (INTVAL (operands[1]))
2236 || const_ok_for_arm (~INTVAL (operands[1])))"
2238 mov%?\\t%0, %1\\t%@ movhi
2239 mvn%?\\t%0, #%B1\\t%@ movhi
2240 ldr%?\\t%0, %1\\t%@ movhi"
2241 [(set_attr "type" "*,*,load")])
2244 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2245 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2247 && (GET_CODE (operands[1]) != CONST_INT
2248 || const_ok_for_arm (INTVAL (operands[1]))
2249 || const_ok_for_arm (~INTVAL (operands[1])))"
2251 mov%?\\t%0, %1\\t%@ movhi
2252 mvn%?\\t%0, #%B1\\t%@ movhi
2253 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2254 [(set_attr "type" "*,*,load")
2255 (set_attr "length" "4,4,8")])
2258 [(set (match_operand:SI 0 "s_register_operand" "=r")
2259 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2262 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2263 [(set_attr "type" "load")])
2265 (define_expand "reload_outhi"
2266 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2267 (match_operand:HI 1 "s_register_operand" "r")
2268 (match_operand:SI 2 "s_register_operand" "=&r")])]
2271 arm_reload_out_hi (operands);
2275 (define_expand "movqi"
2276 [(set (match_operand:QI 0 "general_operand" "")
2277 (match_operand:QI 1 "general_operand" ""))]
2280 /* Everything except mem = const or mem = mem can be done easily */
2282 if (!(reload_in_progress || reload_completed))
2284 if (GET_CODE (operands[1]) == CONST_INT)
2286 rtx reg = gen_reg_rtx (SImode);
2288 emit_insn (gen_movsi (reg, operands[1]));
2289 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2291 if (GET_CODE (operands[0]) == MEM)
2292 operands[1] = force_reg (QImode, operands[1]);
2298 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2299 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
2300 "register_operand (operands[0], QImode)
2301 || register_operand (operands[1], QImode)"
2307 [(set_attr "type" "*,*,load,store1")])
2309 (define_expand "movsf"
2310 [(set (match_operand:SF 0 "general_operand" "")
2311 (match_operand:SF 1 "general_operand" ""))]
2314 if (GET_CODE (operands[1]) == CONST_DOUBLE
2315 && ((GET_CODE (operands[0]) == REG
2316 && REGNO (operands[0]) < 16)
2317 || ! (const_double_rtx_ok_for_fpu (operands[1])
2318 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2320 extern int optimize;
2321 rtx mem = force_const_mem (SFmode, operands[1]);
2322 rtx addr = gen_reg_rtx (SImode);
2325 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2326 emit_insn (gen_movsi (addr, ptr));
2329 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2330 operands[1] = gen_rtx (MEM, SFmode, addr);
2332 if (GET_CODE (operands[0]) == MEM)
2333 operands[1] = force_reg (SFmode, operands[1]);
2337 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2338 (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
2339 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode)"
2345 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2346 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
2348 ldr%?\\t%0, %1\\t%@ float
2349 str%?\\t%1, %0\\t%@ float"
2350 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2352 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2354 (define_expand "movdf"
2355 [(set (match_operand:DF 0 "general_operand" "")
2356 (match_operand:DF 1 "general_operand" ""))]
2359 if (GET_CODE (operands[1]) == CONST_DOUBLE
2360 && ((GET_CODE (operands[0]) == REG
2361 && REGNO (operands[0]) < 16)
2362 || ! (const_double_rtx_ok_for_fpu (operands[1])
2363 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2365 extern int optimize;
2366 rtx mem = force_const_mem (DFmode, operands[1]);
2367 rtx addr = gen_reg_rtx (SImode);
2370 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2371 emit_insn (gen_movsi (addr, ptr));
2374 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2375 operands[1] = gen_rtx (MEM, DFmode, addr);
2377 if (GET_CODE (operands[0]) == MEM)
2378 operands[1] = force_reg (DFmode, operands[1]);
2381 ;; Reloading a df mode value stored in integer regs to memory can require a
2383 (define_expand "reload_outdf"
2384 [(match_operand:DF 0 "reload_memory_operand" "=o")
2385 (match_operand:DF 1 "s_register_operand" "r")
2386 (match_operand:SI 2 "s_register_operand" "=&r")]
2389 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2390 XEXP (XEXP (operands[0], 0), 1)));
2391 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2397 [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
2398 (match_operand:DF 1 "general_operand"
2399 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
2400 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2405 switch (which_alternative)
2408 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2411 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2414 ops[0] = operands[0];
2415 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2416 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2417 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2418 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2420 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2421 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2425 return \"mvf%?d\\t%0, %1\";
2427 case 5: return \"mnf%?d\\t%0, #%N1\";
2428 case 6: return \"ldf%?d\\t%0, %1\";
2429 case 7: return \"stf%?d\\t%1, %0\";
2430 case 8: return output_mov_double_fpu_from_arm (operands);
2431 case 9: return output_mov_double_arm_from_fpu (operands);
2432 case 10: return output_move_double (operands);
2436 [(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
2438 "load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2440 (define_expand "movxf"
2441 [(set (match_operand:XF 0 "general_operand" "")
2442 (match_operand:XF 1 "general_operand" ""))]
2443 "ENABLE_XF_PATTERNS"
2446 ;; Even when the XFmode patterns aren't enabled, we enable this after
2447 ;; reloading so that we can push floating point registers in the prologue.
2450 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2451 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2452 "ENABLE_XF_PATTERNS || reload_completed"
2454 switch (which_alternative)
2456 case 0: return \"mvf%?e\\t%0, %1\";
2457 case 1: return \"mnf%?e\\t%0, #%N1\";
2458 case 2: return \"ldf%?e\\t%0, %1\";
2459 case 3: return \"stf%?e\\t%1, %0\";
2460 case 4: return output_mov_long_double_fpu_from_arm (operands);
2461 case 5: return output_mov_long_double_arm_from_fpu (operands);
2462 case 6: return output_mov_long_double_arm_from_arm (operands);
2465 [(set_attr "length" "4,4,4,4,8,8,12")
2466 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2469 ;; load- and store-multiple insns
2470 ;; The arm can load/store any set of registers, provided that they are in
2471 ;; ascending order; but that is beyond GCC so stick with what it knows.
2473 (define_expand "load_multiple"
2474 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2475 (match_operand:SI 1 "" ""))
2476 (use (match_operand:SI 2 "" ""))])]
2479 /* Support only fixed point registers */
2480 if (GET_CODE (operands[2]) != CONST_INT
2481 || INTVAL (operands[2]) > 14
2482 || INTVAL (operands[2]) < 2
2483 || GET_CODE (operands[1]) != MEM
2484 || GET_CODE (operands[0]) != REG
2485 || REGNO (operands[0]) > 14
2486 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2490 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2491 force_reg (SImode, XEXP (operands[1], 0)),
2495 ;; Load multiple with write-back
2498 [(match_parallel 0 "load_multiple_operation"
2499 [(set (match_operand:SI 1 "s_register_operand" "+r")
2500 (plus:SI (match_dup 1)
2501 (match_operand:SI 2 "immediate_operand" "n")))
2502 (set (match_operand:SI 3 "s_register_operand" "=r")
2503 (mem:SI (match_dup 1)))])]
2504 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2508 int count = XVECLEN (operands[0], 0);
2510 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2511 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2512 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2514 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2518 [(set_attr "type" "load")])
2520 ;; Ordinary load multiple
2523 [(match_parallel 0 "load_multiple_operation"
2524 [(set (match_operand:SI 1 "s_register_operand" "=r")
2525 (match_operand:SI 2 "indirect_operand" "Q"))])]
2530 int count = XVECLEN (operands[0], 0);
2532 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2533 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2534 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2536 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2540 [(set_attr "type" "load")])
2542 (define_expand "store_multiple"
2543 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2544 (match_operand:SI 1 "" ""))
2545 (use (match_operand:SI 2 "" ""))])]
2548 /* Support only fixed point registers */
2549 if (GET_CODE (operands[2]) != CONST_INT
2550 || INTVAL (operands[2]) > 14
2551 || INTVAL (operands[2]) < 2
2552 || GET_CODE (operands[1]) != REG
2553 || GET_CODE (operands[0]) != MEM
2554 || REGNO (operands[1]) > 14
2555 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2559 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2560 force_reg (SImode, XEXP (operands[0], 0)),
2564 ;; Store multiple with write-back
2567 [(match_parallel 0 "store_multiple_operation"
2568 [(set (match_operand:SI 1 "s_register_operand" "+r")
2569 (plus:SI (match_dup 1)
2570 (match_operand:SI 2 "immediate_operand" "n")))
2571 (set (mem:SI (match_dup 1))
2572 (match_operand:SI 3 "s_register_operand" "r"))])]
2573 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2577 int count = XVECLEN (operands[0], 0);
2579 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2580 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2581 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2583 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2588 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2589 (const_string "store2")
2590 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2591 (const_string "store3")]
2592 (const_string "store4")))])
2594 ;; Ordinary store multiple
2597 [(match_parallel 0 "store_multiple_operation"
2598 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2599 (match_operand:SI 1 "s_register_operand" "r"))])]
2604 int count = XVECLEN (operands[0], 0);
2606 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2607 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2608 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2610 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2615 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2616 (const_string "store2")
2617 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2618 (const_string "store3")]
2619 (const_string "store4")))])
2621 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2622 ;; We could let this apply for blocks of less than this, but it clobbers so
2623 ;; many registers that there is then probably a better way.
2625 (define_expand "movstrqi"
2626 [(match_operand:BLK 0 "general_operand" "")
2627 (match_operand:BLK 1 "general_operand" "")
2628 (match_operand:SI 2 "const_int_operand" "")
2629 (match_operand:SI 3 "const_int_operand" "")]
2632 if (arm_gen_movstrqi (operands))
2638 ;; Comparison and test insns
2640 (define_expand "cmpsi"
2642 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2643 (match_operand:SI 1 "arm_add_operand" "")))]
2647 arm_compare_op0 = operands[0];
2648 arm_compare_op1 = operands[1];
2654 (define_expand "cmpsf"
2656 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2657 (match_operand:SF 1 "fpu_rhs_operand" "")))]
2661 arm_compare_op0 = operands[0];
2662 arm_compare_op1 = operands[1];
2668 (define_expand "cmpdf"
2670 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2671 (match_operand:DF 1 "fpu_rhs_operand" "")))]
2675 arm_compare_op0 = operands[0];
2676 arm_compare_op1 = operands[1];
2682 (define_expand "cmpxf"
2684 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2685 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2686 "ENABLE_XF_PATTERNS"
2689 arm_compare_op0 = operands[0];
2690 arm_compare_op1 = operands[1];
2697 [(set (match_operand 0 "cc_register" "")
2698 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2699 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
2704 [(set_attr "conds" "set")])
2707 [(set (match_operand 0 "cc_register" "")
2708 (compare (match_operand:SI 1 "s_register_operand" "r")
2709 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2712 [(set_attr "conds" "set")])
2715 [(set (match_operand 0 "cc_register" "")
2716 (compare (match_operand:SI 1 "s_register_operand" "r")
2717 (match_operator:SI 2 "shift_operator"
2718 [(match_operand:SI 3 "s_register_operand" "r")
2719 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
2722 [(set_attr "conds" "set")])
2725 [(set (match_operand 0 "cc_register" "")
2726 (compare (match_operand:SI 1 "s_register_operand" "r")
2727 (neg:SI (match_operator:SI 2 "shift_operator"
2728 [(match_operand:SI 3 "s_register_operand" "r")
2729 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
2732 [(set_attr "conds" "set")])
2736 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2737 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2742 [(set_attr "conds" "set")
2743 (set_attr "type" "f_2_r")])
2747 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2748 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2753 [(set_attr "conds" "set")
2754 (set_attr "type" "f_2_r")])
2758 (compare:CCFP (float_extend:DF
2759 (match_operand:SF 0 "s_register_operand" "f,f"))
2760 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2765 [(set_attr "conds" "set")
2766 (set_attr "type" "f_2_r")])
2770 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2772 (match_operand:SF 1 "s_register_operand" "f"))))]
2775 [(set_attr "conds" "set")
2776 (set_attr "type" "f_2_r")])
2780 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2781 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2782 "ENABLE_XF_PATTERNS"
2786 [(set_attr "conds" "set")
2787 (set_attr "type" "f_2_r")])
2790 [(set (reg:CCFPE 24)
2791 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2792 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2797 [(set_attr "conds" "set")
2798 (set_attr "type" "f_2_r")])
2801 [(set (reg:CCFPE 24)
2802 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2803 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2808 [(set_attr "conds" "set")
2809 (set_attr "type" "f_2_r")])
2812 [(set (reg:CCFPE 24)
2813 (compare:CCFPE (float_extend:DF
2814 (match_operand:SF 0 "s_register_operand" "f,f"))
2815 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2820 [(set_attr "conds" "set")
2821 (set_attr "type" "f_2_r")])
2824 [(set (reg:CCFPE 24)
2825 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2827 (match_operand:SF 1 "s_register_operand" "f"))))]
2830 [(set_attr "conds" "set")
2831 (set_attr "type" "f_2_r")])
2834 [(set (reg:CCFPE 24)
2835 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2836 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2837 "ENABLE_XF_PATTERNS"
2841 [(set_attr "conds" "set")
2842 (set_attr "type" "f_2_r")])
2844 ; This insn allows redundant compares to be removed by cse, nothing should
2845 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2846 ; is deleted later on. The match_dup will match the mode here, so that
2847 ; mode changes of the condition codes aren't lost by this even though we don't
2848 ; specify what they are.
2851 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2853 "\\t%@ deleted compare"
2854 [(set_attr "conds" "set")
2855 (set_attr "length" "0")])
2858 ;; Conditional branch insns
2860 (define_expand "beq"
2862 (if_then_else (eq (match_dup 1) (const_int 0))
2863 (label_ref (match_operand 0 "" ""))
2868 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2873 (define_expand "bne"
2875 (if_then_else (ne (match_dup 1) (const_int 0))
2876 (label_ref (match_operand 0 "" ""))
2881 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
2886 (define_expand "bgt"
2888 (if_then_else (gt (match_dup 1) (const_int 0))
2889 (label_ref (match_operand 0 "" ""))
2894 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
2899 (define_expand "ble"
2901 (if_then_else (le (match_dup 1) (const_int 0))
2902 (label_ref (match_operand 0 "" ""))
2907 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
2912 (define_expand "bge"
2914 (if_then_else (ge (match_dup 1) (const_int 0))
2915 (label_ref (match_operand 0 "" ""))
2920 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
2925 (define_expand "blt"
2927 (if_then_else (lt (match_dup 1) (const_int 0))
2928 (label_ref (match_operand 0 "" ""))
2933 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
2938 (define_expand "bgtu"
2940 (if_then_else (gtu (match_dup 1) (const_int 0))
2941 (label_ref (match_operand 0 "" ""))
2946 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
2951 (define_expand "bleu"
2953 (if_then_else (leu (match_dup 1) (const_int 0))
2954 (label_ref (match_operand 0 "" ""))
2959 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
2964 (define_expand "bgeu"
2966 (if_then_else (geu (match_dup 1) (const_int 0))
2967 (label_ref (match_operand 0 "" ""))
2972 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
2977 (define_expand "bltu"
2979 (if_then_else (ltu (match_dup 1) (const_int 0))
2980 (label_ref (match_operand 0 "" ""))
2985 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
2990 ;; patterns to match conditional branch insns
2994 (if_then_else (match_operator 1 "comparison_operator"
2995 [(reg 24) (const_int 0)])
2996 (label_ref (match_operand 0 "" ""))
3001 extern int arm_ccfsm_state;
3003 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3005 arm_ccfsm_state += 2;
3008 return \"b%d1\\t%l0\";
3010 [(set_attr "conds" "use")])
3014 (if_then_else (match_operator 1 "comparison_operator"
3015 [(reg 24) (const_int 0)])
3017 (label_ref (match_operand 0 "" ""))))]
3018 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3021 extern int arm_ccfsm_state;
3023 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3025 arm_ccfsm_state += 2;
3028 return \"b%D1\\t%l0\";
3030 [(set_attr "conds" "use")])
3035 (define_expand "seq"
3036 [(set (match_operand:SI 0 "s_register_operand" "=r")
3037 (eq:SI (match_dup 1) (const_int 0)))]
3041 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3046 (define_expand "sne"
3047 [(set (match_operand:SI 0 "s_register_operand" "=r")
3048 (ne:SI (match_dup 1) (const_int 0)))]
3052 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3057 (define_expand "sgt"
3058 [(set (match_operand:SI 0 "s_register_operand" "=r")
3059 (gt:SI (match_dup 1) (const_int 0)))]
3063 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3068 (define_expand "sle"
3069 [(set (match_operand:SI 0 "s_register_operand" "=r")
3070 (le:SI (match_dup 1) (const_int 0)))]
3074 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3079 (define_expand "sge"
3080 [(set (match_operand:SI 0 "s_register_operand" "=r")
3081 (ge:SI (match_dup 1) (const_int 0)))]
3085 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3090 (define_expand "slt"
3091 [(set (match_operand:SI 0 "s_register_operand" "=r")
3092 (lt:SI (match_dup 1) (const_int 0)))]
3096 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3101 (define_expand "sgtu"
3102 [(set (match_operand:SI 0 "s_register_operand" "=r")
3103 (gtu:SI (match_dup 1) (const_int 0)))]
3107 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3112 (define_expand "sleu"
3113 [(set (match_operand:SI 0 "s_register_operand" "=r")
3114 (leu:SI (match_dup 1) (const_int 0)))]
3118 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3123 (define_expand "sgeu"
3124 [(set (match_operand:SI 0 "s_register_operand" "=r")
3125 (geu:SI (match_dup 1) (const_int 0)))]
3129 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3134 (define_expand "sltu"
3135 [(set (match_operand:SI 0 "s_register_operand" "=r")
3136 (ltu:SI (match_dup 1) (const_int 0)))]
3140 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3146 [(set (match_operand:SI 0 "s_register_operand" "=r")
3147 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3149 "mov%d1\\t%0, #1\;mov%D1\\t%0, #0"
3150 [(set_attr "conds" "use")
3151 (set_attr "length" "8")])
3154 [(set (match_operand:SI 0 "s_register_operand" "=r")
3155 (neg:SI (match_operator:SI 1 "comparison_operator"
3156 [(reg 24) (const_int 0)])))]
3158 "mvn%d1\\t%0, #0\;mov%D1\\t%0, #0"
3159 [(set_attr "conds" "use")
3160 (set_attr "length" "8")])
3163 [(set (match_operand:SI 0 "s_register_operand" "=r")
3164 (not:SI (match_operator:SI 1 "comparison_operator"
3165 [(reg 24) (const_int 0)])))]
3167 "mvn%d1\\t%0, #1\;mov%D1\\t%0, #0"
3168 [(set_attr "conds" "use")
3169 (set_attr "length" "8")])
3172 ;; Jump and linkage insns
3176 (label_ref (match_operand 0 "" "")))]
3180 extern int arm_ccfsm_state;
3182 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3184 arm_ccfsm_state += 2;
3187 return \"b%?\\t%l0\";
3190 (define_expand "call"
3191 [(parallel [(call (match_operand 0 "memory_operand" "")
3192 (match_operand 1 "general_operand" ""))
3193 (clobber (reg:SI 14))])]
3198 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3199 (match_operand 1 "" "g"))
3200 (clobber (reg:SI 14))]
3203 return output_call (operands);
3205 [(set (attr "conds")
3206 (if_then_else (eq_attr "cpu" "arm6")
3207 (const_string "clob")
3208 (const_string "nocond")))
3209 ;; length is worst case, normally it is only two
3210 (set_attr "length" "12")
3211 (set_attr "type" "call")])
3214 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3215 (match_operand 1 "general_operand" "g"))
3216 (clobber (reg:SI 14))]
3219 return output_call_mem (operands);
3221 [(set (attr "conds")
3222 (if_then_else (eq_attr "cpu" "arm6")
3223 (const_string "clob")
3224 (const_string "nocond")))
3225 (set_attr "length" "12")
3226 (set_attr "type" "call")])
3228 (define_expand "call_value"
3229 [(parallel [(set (match_operand 0 "" "=rf")
3230 (call (match_operand 1 "memory_operand" "m")
3231 (match_operand 2 "general_operand" "g")))
3232 (clobber (reg:SI 14))])]
3237 [(set (match_operand 0 "" "=rf")
3238 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3239 (match_operand 2 "general_operand" "g")))
3240 (clobber (reg:SI 14))]
3243 return output_call (&operands[1]);
3245 [(set (attr "conds")
3246 (if_then_else (eq_attr "cpu" "arm6")
3247 (const_string "clob")
3248 (const_string "nocond")))
3249 (set_attr "length" "12")
3250 (set_attr "type" "call")])
3253 [(set (match_operand 0 "" "=rf")
3254 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3255 (match_operand 2 "general_operand" "g")))
3256 (clobber (reg:SI 14))]
3257 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3259 return output_call_mem (&operands[1]);
3261 [(set (attr "conds")
3262 (if_then_else (eq_attr "cpu" "arm6")
3263 (const_string "clob")
3264 (const_string "nocond")))
3265 (set_attr "length" "12")
3266 (set_attr "type" "call")])
3268 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3269 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3272 [(call (mem:SI (match_operand:SI 0 "" "i"))
3273 (match_operand:SI 1 "general_operand" "g"))
3274 (clobber (reg:SI 14))]
3275 "GET_CODE (operands[0]) == SYMBOL_REF"
3277 [(set (attr "conds")
3278 (if_then_else (eq_attr "cpu" "arm6")
3279 (const_string "clob")
3280 (const_string "nocond")))
3281 (set_attr "type" "call")])
3284 [(set (match_operand 0 "s_register_operand" "=rf")
3285 (call (mem:SI (match_operand:SI 1 "" "i"))
3286 (match_operand:SI 2 "general_operand" "g")))
3287 (clobber (reg:SI 14))]
3288 "GET_CODE(operands[1]) == SYMBOL_REF"
3290 [(set (attr "conds")
3291 (if_then_else (eq_attr "cpu" "arm6")
3292 (const_string "clob")
3293 (const_string "nocond")))
3294 (set_attr "type" "call")])
3296 ;; Often the return insn will be the same as loading from memory, so set attr
3297 (define_insn "return"
3302 extern int arm_ccfsm_state;
3304 if (arm_ccfsm_state == 2)
3306 arm_ccfsm_state += 2;
3309 return output_return_instruction (NULL, TRUE);
3311 [(set_attr "type" "load")])
3315 (if_then_else (match_operator 0 "comparison_operator"
3316 [(reg 24) (const_int 0)])
3322 extern int arm_ccfsm_state;
3324 if (arm_ccfsm_state == 2)
3326 arm_ccfsm_state += 2;
3329 return output_return_instruction (operands[0], TRUE);
3331 [(set_attr "conds" "use")
3332 (set_attr "type" "load")])
3336 (if_then_else (match_operator 0 "comparison_operator"
3337 [(reg 24) (const_int 0)])
3343 extern int arm_ccfsm_state;
3345 if (arm_ccfsm_state == 2)
3347 arm_ccfsm_state += 2;
3350 return output_return_instruction
3351 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3352 GET_MODE (operands[0]), XEXP (operands[0], 0),
3353 XEXP (operands[0], 1)),
3356 [(set_attr "conds" "use")
3357 (set_attr "type" "load")])
3359 ;; Call subroutine returning any type.
3361 (define_expand "untyped_call"
3362 [(parallel [(call (match_operand 0 "" "")
3364 (match_operand 1 "" "")
3365 (match_operand 2 "" "")])]
3371 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3373 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3375 rtx set = XVECEXP (operands[2], 0, i);
3376 emit_move_insn (SET_DEST (set), SET_SRC (set));
3379 /* The optimizer does not know that the call sets the function value
3380 registers we stored in the result block. We avoid problems by
3381 claiming that all hard registers are used and clobbered at this
3383 emit_insn (gen_blockage ());
3388 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3389 ;; all of memory. This blocks insns from being moved across this point.
3391 (define_insn "blockage"
3392 [(unspec_volatile [(const_int 0)] 0)]
3395 [(set_attr "length" "0")
3396 (set_attr "type" "block")])
3398 (define_insn "tablejump"
3400 (match_operand:SI 0 "s_register_operand" "r"))
3401 (use (label_ref (match_operand 1 "" "")))]
3403 "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
3407 (match_operand:SI 0 "memory_operand" "m"))
3408 (use (label_ref (match_operand 1 "" "")))]
3410 "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
3411 [(set_attr "type" "load")])
3413 (define_insn "indirect_jump"
3415 (match_operand:SI 0 "s_register_operand" "r"))]
3417 "mov%?\\t%|pc, %0\\t%@ indirect jump")
3421 (match_operand:SI 0 "memory_operand" "m"))]
3423 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3424 [(set_attr "type" "load")])
3431 "mov%?\\tr0, r0\\t%@ nop")
3433 ;; Patterns to allow combination of arithmetic, cond code and shifts
3436 [(set (match_operand:SI 0 "s_register_operand" "=r")
3437 (match_operator:SI 1 "shiftable_operator"
3438 [(match_operator:SI 3 "shift_operator"
3439 [(match_operand:SI 4 "s_register_operand" "r")
3440 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3441 (match_operand:SI 2 "s_register_operand" "r")]))]
3443 "%i1%?\\t%0, %2, %4%S3")
3446 [(set (reg:CC_NOOV 24)
3447 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3448 [(match_operator:SI 3 "shift_operator"
3449 [(match_operand:SI 4 "s_register_operand" "r")
3450 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3451 (match_operand:SI 2 "s_register_operand" "r")])
3453 (set (match_operand:SI 0 "s_register_operand" "=r")
3454 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3457 "%i1%?s\\t%0, %2, %4%S3"
3458 [(set_attr "conds" "set")])
3461 [(set (reg:CC_NOOV 24)
3462 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3463 [(match_operator:SI 3 "shift_operator"
3464 [(match_operand:SI 4 "s_register_operand" "r")
3465 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3466 (match_operand:SI 2 "s_register_operand" "r")])
3468 (clobber (match_scratch:SI 0 "=r"))]
3470 "%i1%?s\\t%0, %2, %4%S3"
3471 [(set_attr "conds" "set")])
3474 [(set (match_operand:SI 0 "s_register_operand" "=r")
3475 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3476 (match_operator:SI 2 "shift_operator"
3477 [(match_operand:SI 3 "s_register_operand" "r")
3478 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
3480 "sub%?\\t%0, %1, %3%S2")
3483 [(set (reg:CC_NOOV 24)
3485 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3486 (match_operator:SI 2 "shift_operator"
3487 [(match_operand:SI 3 "s_register_operand" "r")
3488 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3490 (set (match_operand:SI 0 "s_register_operand" "=r")
3491 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3494 "sub%?s\\t%0, %1, %3%S2"
3495 [(set_attr "conds" "set")])
3498 [(set (reg:CC_NOOV 24)
3500 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3501 (match_operator:SI 2 "shift_operator"
3502 [(match_operand:SI 3 "s_register_operand" "r")
3503 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3505 (clobber (match_scratch:SI 0 "=r"))]
3507 "sub%?s\\t%0, %1, %3%S2"
3508 [(set_attr "conds" "set")])
3510 ;; These variants of the above insns can occur if the first operand is the
3511 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3512 ;; seem to be a way around it. Most of the predicates have to be null
3513 ;; because the format can be generated part way through reload, so
3514 ;; if we don't match it as soon as it becomes available, reload doesn't know
3515 ;; how to reload pseudos that haven't got hard registers; the constraints will
3516 ;; sort everything out.
3519 [(set (match_operand:SI 0 "" "=&r")
3520 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3521 [(match_operand:SI 3 "" "r")
3522 (match_operand:SI 4 "" "rM")])
3523 (match_operand:SI 2 "" "r"))
3524 (match_operand:SI 1 "const_int_operand" "n")))]
3525 "reload_in_progress"
3527 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
3528 operands[2] = operands[1];
3529 operands[1] = operands[0];
3530 return output_add_immediate (operands);
3532 ; we have no idea how long the add_immediate is, it could be up to 4.
3533 [(set_attr "length" "20")])
3536 [(set (reg:CC_NOOV 24)
3537 (compare:CC_NOOV (plus:SI
3539 (match_operator:SI 5 "shift_operator"
3540 [(match_operand:SI 3 "" "r")
3541 (match_operand:SI 4 "" "rM")])
3542 (match_operand:SI 1 "" "r"))
3543 (match_operand:SI 2 "const_int_operand" "n"))
3545 (set (match_operand:SI 0 "" "=&r")
3546 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3549 "reload_in_progress"
3551 output_add_immediate (operands);
3552 return \"add%?s\\t%0, %0, %3%S5\";
3554 [(set_attr "conds" "set")
3555 (set_attr "length" "20")])
3558 [(set (reg:CC_NOOV 24)
3559 (compare:CC_NOOV (plus:SI
3561 (match_operator:SI 5 "shift_operator"
3562 [(match_operand:SI 3 "" "r")
3563 (match_operand:SI 4 "" "rM")])
3564 (match_operand:SI 1 "" "r"))
3565 (match_operand:SI 2 "const_int_operand" "n"))
3567 (clobber (match_scratch:SI 0 "=&r"))]
3568 "reload_in_progress"
3570 output_add_immediate (operands);
3571 return \"add%?s\\t%0, %0, %3%S5\";
3573 [(set_attr "conds" "set")
3574 (set_attr "length" "20")])
3576 ;; These are similar, but are needed when the mla pattern contains the
3577 ;; eliminated register as operand 3.
3580 [(set (match_operand:SI 0 "" "=&r,&r")
3581 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3582 (match_operand:SI 2 "" "r,r"))
3583 (match_operand:SI 3 "" "r,r"))
3584 (match_operand:SI 4 "const_int_operand" "n,n")))]
3585 "reload_in_progress"
3587 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3588 operands[2] = operands[4];
3589 operands[1] = operands[0];
3590 return output_add_immediate (operands);
3592 [(set_attr "length" "20")])
3595 [(set (reg:CC_NOOV 24)
3596 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3597 (match_operand:SI 3 "" "r")
3598 (match_operand:SI 4 "" "r"))
3599 (match_operand:SI 1 "" "r"))
3600 (match_operand:SI 2 "const_int_operand" "n"))
3602 (set (match_operand:SI 0 "" "=&r")
3603 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3605 "reload_in_progress"
3607 output_add_immediate (operands);
3608 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3611 [(set_attr "length" "20")
3612 (set_attr "conds" "set")])
3615 [(set (reg:CC_NOOV 24)
3616 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3617 (match_operand:SI 3 "" "r")
3618 (match_operand:SI 4 "" "r"))
3619 (match_operand:SI 1 "" "r"))
3620 (match_operand:SI 2 "const_int_operand" "n"))
3622 (clobber (match_scratch:SI 0 "=&r"))]
3623 "reload_in_progress"
3625 output_add_immediate (operands);
3626 return \"mla%?s\\t%0, %3, %4, %0\";
3628 [(set_attr "length" "20")
3629 (set_attr "conds" "set")])
3635 [(set (match_operand:SI 0 "s_register_operand" "=r")
3636 (and:SI (match_operator 1 "comparison_operator"
3637 [(reg 24) (const_int 0)])
3638 (match_operand:SI 2 "s_register_operand" "r")))]
3640 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3641 [(set_attr "conds" "use")
3642 (set_attr "length" "8")])
3645 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3646 (ior:SI (match_operator 2 "comparison_operator"
3647 [(reg 24) (const_int 0)])
3648 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3652 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3653 [(set_attr "conds" "use")
3654 (set_attr "length" "4,8")])
3657 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3658 (match_operator 1 "comparison_operator"
3659 [(match_operand:SI 2 "s_register_operand" "r,r")
3660 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
3664 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3665 return \"mov\\t%0, %2, lsr #31\";
3667 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3668 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3670 if (GET_CODE (operands[1]) == NE)
3672 if (which_alternative == 1)
3673 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3674 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3676 if (which_alternative == 1)
3677 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3679 output_asm_insn (\"cmp\\t%2, %3\", operands);
3680 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3682 [(set_attr "conds" "clob")
3683 (set_attr "length" "12")])
3686 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3687 (ior:SI (match_operator 1 "comparison_operator"
3688 [(match_operand:SI 2 "s_register_operand" "r")
3689 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3690 (match_operator 4 "comparison_operator"
3691 [(match_operand:SI 5 "s_register_operand" "r")
3692 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3697 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3698 GET_CODE (operands[1]));
3700 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3702 output_asm_insn (\"mov\\t%0, #0\", operands);
3703 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3704 || comparison_dominates_p (GET_CODE (operands[1]),
3705 GET_CODE (operands[4]))
3707 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3710 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3711 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3714 [(set_attr "conds" "clob")
3716 (set_attr "length" "20")])
3721 (match_operator 5 "equality_operator"
3722 [(ior:SI (match_operator 6 "comparison_operator"
3723 [(match_operand:SI 0 "s_register_operand" "")
3724 (match_operand:SI 1 "arm_add_operand" "")])
3725 (match_operator 7 "comparison_operator"
3726 [(match_operand:SI 2 "s_register_operand" "")
3727 (match_operand:SI 3 "arm_add_operand" "")]))
3729 (label_ref (match_operand 4 "" ""))
3732 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3733 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3734 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3736 (compare:CC (ior:CC (match_op_dup 6
3737 [(match_dup 0) (match_dup 1)])
3739 [(match_dup 2) (match_dup 3)]))
3742 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3743 (label_ref (match_dup 4))
3747 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3748 GET_CODE (operands[7]))
3749 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3751 if (GET_CODE (operands[5]) == NE)
3752 operands[5] = gen_rtx (code, CCmode,
3753 XEXP (operands[5], 0), XEXP (operands[5], 1));
3755 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3756 XEXP (operands[5], 0), XEXP (operands[5], 1));
3760 ;; Don't match these patterns if we can use a conditional compare, since they
3761 ;; tell the final prescan branch elimator code that full branch inlining
3767 (ne (ior:SI (match_operator 5 "comparison_operator"
3768 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3769 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3770 (match_operator 6 "comparison_operator"
3771 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3772 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
3774 (label_ref (match_operand 4 "" ""))
3777 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3778 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3779 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3782 extern int arm_ccfsm_state;
3784 if (which_alternative & 1)
3785 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
3787 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
3789 if (which_alternative >= 2)
3790 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3792 output_asm_insn (\"cmp\\t%2, %3\", operands);
3794 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3796 arm_ccfsm_state += 2;
3799 return \"b%d6\\t%l4\";
3801 [(set_attr "conds" "jump_clob")
3802 (set_attr "length" "16")])
3807 (ior:CC (match_operator 4 "comparison_operator"
3808 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3809 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3810 (match_operator 5 "comparison_operator"
3811 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3812 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
3814 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3815 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3816 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3818 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3820 if (which_alternative >= 2)
3821 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3823 output_asm_insn (\"cmp\\t%2, %3\", operands);
3825 if (which_alternative & 1)
3826 return \"cmn%D5\\t%0, #%n1\";
3827 return \"cmp%D5\\t%0, %1\";
3830 if (which_alternative & 1)
3831 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3833 output_asm_insn (\"cmp\\t%0, %1\", operands);
3835 if (which_alternative >= 2)
3836 return \"cmn%D4\\t%2, #%n3\";
3837 return \"cmp%D4\\t%2, %3\";
3839 [(set_attr "conds" "set")
3840 (set_attr "length" "8")])
3843 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3844 (if_then_else (match_operator 3 "equality_operator"
3845 [(match_operator 4 "comparison_operator"
3846 [(reg 24) (const_int 0)])
3848 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3849 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3852 if (GET_CODE (operands[3]) == NE)
3854 if (which_alternative != 0)
3855 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3856 if (which_alternative != 1)
3857 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3860 if (which_alternative != 0)
3861 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3862 if (which_alternative != 1)
3863 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
3866 [(set_attr "conds" "use")
3867 (set_attr "length" "4,4,8")])
3870 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3871 (match_operator:SI 5 "shiftable_operator"
3872 [(match_operator:SI 4 "comparison_operator"
3873 [(match_operand:SI 2 "s_register_operand" "r,r")
3874 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3875 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3879 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
3880 return \"%i5\\t%0, %1, %2, lsr #31\";
3882 output_asm_insn (\"cmp\\t%2, %3\", operands);
3883 if (GET_CODE (operands[5]) == AND)
3884 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
3885 else if (which_alternative != 0)
3886 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3887 return \"%i5%d4\\t%0, %1, #1\";
3889 [(set_attr "conds" "clob")
3890 (set_attr "length" "12")])
3893 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3894 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
3895 (match_operator:SI 4 "comparison_operator"
3896 [(match_operand:SI 2 "s_register_operand" "r,r")
3897 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
3901 output_asm_insn (\"cmp\\t%2, %3\", operands);
3902 if (which_alternative != 0)
3903 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3904 return \"sub%d4\\t%0, %1, #1\";
3906 [(set_attr "conds" "clob")
3907 (set_attr "length" "8,12")])
3910 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3911 (and:SI (match_operator 1 "comparison_operator"
3912 [(match_operand:SI 2 "s_register_operand" "r")
3913 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3914 (match_operator 4 "comparison_operator"
3915 [(match_operand:SI 5 "s_register_operand" "r")
3916 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3922 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
3923 reverse_condition (GET_CODE (operands[4])))
3925 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
3926 reverse_condition (GET_CODE (operands[1])))
3928 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3930 output_asm_insn (\"mov\\t%0, #1\", operands);
3931 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
3933 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
3934 : \"cmp%d1\\t%5, %6\", operands);
3938 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
3939 output_asm_insn (\"cmp\\t%5, %6\", operands);
3941 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
3944 [(set_attr "conds" "clob")
3945 (set_attr "length" "20")])
3949 (if_then_else (match_operator 1 "equality_operator"
3950 [(and:SI (match_operator 2 "comparison_operator"
3951 [(match_operand:SI 3 "s_register_operand" "")
3952 (match_operand:SI 4 "arm_add_operand" "")])
3953 (match_operator 0 "comparison_operator"
3954 [(match_operand:SI 5 "s_register_operand" "")
3955 (match_operand:SI 6 "arm_add_operand" "")]))
3957 (label_ref (match_operand 7 "" ""))
3960 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
3961 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
3962 reverse_condition (GET_CODE (operands[0])))
3963 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
3964 reverse_condition (GET_CODE (operands[2]))))"
3966 (compare:CC (ior:CC (match_op_dup 2
3967 [(match_dup 3) (match_dup 4)])
3969 [(match_dup 5) (match_dup 6)]))
3972 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
3973 (label_ref (match_dup 7))
3977 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
3978 This is safe since we only do it for integer comparisons. */
3979 enum rtx_code code =
3980 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
3981 reverse_condition (GET_CODE (operands[0])))
3982 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
3984 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
3985 GET_MODE (operands[2]), operands[3], operands[4]);
3986 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
3987 GET_MODE (operands[0]), operands[5], operands[6]);
3988 if (GET_CODE (operands[1]) == NE)
3989 operands[1] = gen_rtx (code, CCmode,
3990 XEXP (operands[1], 0), XEXP (operands[1], 1));
3992 operands[1] = gen_rtx (reverse_condition (code), CCmode,
3993 XEXP (operands[1], 0), XEXP (operands[1], 1));
3997 ;; Don't match these patterns if we can use a conditional compare, since they
3998 ;; tell the final prescan branch elimator code that full branch inlining
4004 (eq (and:SI (match_operator 1 "comparison_operator"
4005 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4006 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4007 (match_operator 4 "comparison_operator"
4008 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4009 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4011 (label_ref (match_operand 0 "" ""))
4014 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4015 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4016 reverse_condition (GET_CODE (operands[4])))
4017 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4018 reverse_condition (GET_CODE (operands[1]))))"
4021 extern int arm_ccfsm_state;
4023 if (which_alternative & 1)
4024 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
4026 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4028 if (which_alternative >= 2)
4029 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4031 output_asm_insn (\"cmp\\t%5, %6\", operands);
4033 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4035 arm_ccfsm_state += 2;
4038 return \"b%D4\\t%l0\";
4040 [(set_attr "conds" "jump_clob")
4041 (set_attr "length" "16")])
4044 [(set (match_operand:SI 0 "s_register_operand" "=r")
4045 (neg:SI (match_operator 3 "comparison_operator"
4046 [(match_operand:SI 1 "s_register_operand" "r")
4047 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4051 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4052 return \"mov\\t%0, %1, asr #31\";
4054 if (GET_CODE (operands[3]) == NE)
4055 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4057 if (GET_CODE (operands[3]) == GT)
4058 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4060 output_asm_insn (\"cmp\\t%1, %2\", operands);
4061 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4062 return \"mvn%d3\\t%0, #0\";
4064 [(set_attr "conds" "clob")
4065 (set_attr "length" "12")])
4067 (define_insn "movcond"
4068 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4070 (match_operator 5 "comparison_operator"
4071 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4072 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4073 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4074 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4078 if (GET_CODE (operands[5]) == LT
4079 && (operands[4] == const0_rtx))
4081 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4083 if (operands[2] == const0_rtx)
4084 return \"and\\t%0, %1, %3, asr #31\";
4085 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4087 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4089 if (operands[1] == const0_rtx)
4090 return \"bic\\t%0, %2, %3, asr #31\";
4091 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4093 /* The only case that falls through to here is when both ops 1 & 2
4097 if (GET_CODE (operands[5]) == GE
4098 && (operands[4] == const0_rtx))
4100 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4102 if (operands[2] == const0_rtx)
4103 return \"bic\\t%0, %1, %3, asr #31\";
4104 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4106 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4108 if (operands[1] == const0_rtx)
4109 return \"and\\t%0, %2, %3, asr #31\";
4110 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4112 /* The only case that falls through to here is when both ops 1 & 2
4115 if (GET_CODE (operands[4]) == CONST_INT
4116 && !const_ok_for_arm (INTVAL (operands[4])))
4117 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4119 output_asm_insn (\"cmp\\t%3, %4\", operands);
4120 if (which_alternative != 0)
4121 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4122 if (which_alternative != 1)
4123 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4126 [(set_attr "conds" "clob")
4127 (set_attr "length" "8,8,12")])
4130 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4131 (if_then_else:SI (match_operator 9 "comparison_operator"
4132 [(match_operand:SI 5 "s_register_operand" "r,r")
4133 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4134 (match_operator:SI 8 "shiftable_operator"
4135 [(match_operand:SI 1 "s_register_operand" "r,r")
4136 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4137 (match_operator:SI 7 "shiftable_operator"
4138 [(match_operand:SI 3 "s_register_operand" "r,r")
4139 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4143 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4144 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4145 [(set_attr "conds" "clob")
4146 (set_attr "length" "12")])
4149 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4150 (if_then_else:SI (match_operator 6 "comparison_operator"
4151 [(match_operand:SI 2 "s_register_operand" "r,r")
4152 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4153 (match_operator:SI 7 "shiftable_operator"
4154 [(match_operand:SI 4 "s_register_operand" "r,r")
4155 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4156 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4160 /* If we have an operation where (op x 0) is the identity operation and
4161 the condtional operator is LT or GE and we are comparing against zero and
4162 everything is in registers then we can do this in two instructions */
4163 if (operands[3] == const0_rtx
4164 && GET_CODE (operands[7]) != AND
4165 && GET_CODE (operands[5]) == REG
4166 && GET_CODE (operands[1]) == REG
4167 && REGNO (operands[1]) == REGNO (operands[4])
4168 && REGNO (operands[4]) != REGNO (operands[0]))
4170 if (GET_CODE (operands[6]) == LT)
4171 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4172 else if (GET_CODE (operands[6]) == GE)
4173 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4175 if (GET_CODE (operands[3]) == CONST_INT
4176 && !const_ok_for_arm (INTVAL (operands[3])))
4177 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4179 output_asm_insn (\"cmp\\t%2, %3\", operands);
4180 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4181 if (which_alternative != 0)
4183 if (GET_CODE (operands[1]) == MEM)
4184 return \"ldr%D6\\t%0, %1\";
4186 return \"mov%D6\\t%0, %1\";
4190 [(set_attr "conds" "clob")
4191 (set_attr "length" "8,12")])
4194 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4195 (if_then_else:SI (match_operator 6 "comparison_operator"
4196 [(match_operand:SI 4 "s_register_operand" "r,r")
4197 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4198 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4199 (match_operator:SI 7 "shiftable_operator"
4200 [(match_operand:SI 2 "s_register_operand" "r,r")
4201 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4205 /* If we have an operation where (op x 0) is the identity operation and
4206 the condtional operator is LT or GE and we are comparing against zero and
4207 everything is in registers then we can do this in two instructions */
4208 if (operands[5] == const0_rtx
4209 && GET_CODE (operands[7]) != AND
4210 && GET_CODE (operands[3]) == REG
4211 && GET_CODE (operands[1]) == REG
4212 && REGNO (operands[1]) == REGNO (operands[2])
4213 && REGNO (operands[2]) != REGNO (operands[0]))
4215 if (GET_CODE (operands[6]) == GE)
4216 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4217 else if (GET_CODE (operands[6]) == LT)
4218 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4221 if (GET_CODE (operands[5]) == CONST_INT
4222 && !const_ok_for_arm (INTVAL (operands[5])))
4223 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4225 output_asm_insn (\"cmp\\t%4, %5\", operands);
4227 if (which_alternative != 0)
4229 if (GET_CODE (operands[1]) == MEM)
4230 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4232 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4234 return \"%I7%D6\\t%0, %2, %3\";
4236 [(set_attr "conds" "clob")
4237 (set_attr "length" "8,12")])
4240 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4241 (if_then_else:SI (match_operator 6 "comparison_operator"
4242 [(match_operand:SI 4 "s_register_operand" "r,r")
4243 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4245 (match_operand:SI 2 "s_register_operand" "r,r")
4246 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4247 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4252 if (GET_CODE (operands[5]) == CONST_INT
4253 && !const_ok_for_arm (INTVAL (operands[5])))
4254 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4256 output_asm_insn (\"cmp\\t%4, %5\", operands);
4257 if (GET_CODE (operands[3]) == CONST_INT
4258 && !const_ok_for_arm (INTVAL (operands[3])))
4259 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4261 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4262 if (which_alternative != 0)
4264 if (GET_CODE (operands[1]) == MEM)
4265 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4267 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4272 [(set_attr "conds" "clob")
4273 (set_attr "length" "8,12")])
4276 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4277 (if_then_else:SI (match_operator 6 "comparison_operator"
4278 [(match_operand:SI 4 "s_register_operand" "r,r")
4279 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4280 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4282 (match_operand:SI 2 "s_register_operand" "r,r")
4283 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4288 if (GET_CODE (operands[5]) == CONST_INT
4289 && !const_ok_for_arm (INTVAL (operands[5])))
4290 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4292 output_asm_insn (\"cmp\\t%4, %5\", operands);
4293 if (GET_CODE (operands[3]) == CONST_INT
4294 && !const_ok_for_arm (INTVAL (operands[3])))
4295 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4297 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4298 if (which_alternative != 0)
4300 if (GET_CODE (operands[6]) == MEM)
4301 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4303 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4308 [(set_attr "conds" "clob")
4309 (set_attr "length" "8,12")])
4312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4313 (if_then_else:SI (match_operator 5 "comparison_operator"
4314 [(match_operand:SI 3 "s_register_operand" "r,r")
4315 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4316 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4318 (match_operand:SI 2 "s_register_operand" "r,r"))))
4322 [(set_attr "conds" "clob")
4323 (set_attr "length" "8,12")])
4326 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4328 (match_operator 5 "comparison_operator"
4329 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4330 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4332 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4333 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4337 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4338 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4339 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4340 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4341 [(set_attr "conds" "clob")
4342 (set_attr "length" "8,8,12,12")])
4345 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4347 (match_operator 6 "comparison_operator"
4348 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4349 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4350 (match_operator:SI 7 "shift_operator"
4351 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4352 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4353 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4357 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4358 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4359 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4360 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4361 [(set_attr "conds" "clob")
4362 (set_attr "length" "8,8,12,12")])
4365 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4367 (match_operator 6 "comparison_operator"
4368 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4369 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4370 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4371 (match_operator:SI 7 "shift_operator"
4372 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4373 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4377 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4378 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4379 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4380 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4381 [(set_attr "conds" "clob")
4382 (set_attr "length" "8,8,12,12")])
4385 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4387 (match_operator 7 "comparison_operator"
4388 [(match_operand:SI 5 "s_register_operand" "r,r")
4389 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4390 (match_operator:SI 8 "shift_operator"
4391 [(match_operand:SI 1 "s_register_operand" "r,r")
4392 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4393 (match_operator:SI 9 "shift_operator"
4394 [(match_operand:SI 3 "s_register_operand" "r,r")
4395 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4399 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4400 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4401 [(set_attr "conds" "clob")
4402 (set_attr "length" "12")])
4405 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4407 (match_operator 6 "comparison_operator"
4408 [(match_operand:SI 4 "s_register_operand" "r,r")
4409 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4410 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4411 (match_operator:SI 7 "shiftable_operator"
4412 [(match_operand:SI 2 "s_register_operand" "r,r")
4413 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4417 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4418 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4419 [(set_attr "conds" "clob")
4420 (set_attr "length" "12")])
4423 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4425 (match_operator 6 "comparison_operator"
4426 [(match_operand:SI 4 "s_register_operand" "r,r")
4427 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4428 (match_operator:SI 7 "shiftable_operator"
4429 [(match_operand:SI 2 "s_register_operand" "r,r")
4430 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4431 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4435 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4436 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4437 [(set_attr "conds" "clob")
4438 (set_attr "length" "12")])
4441 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4443 (match_operator 5 "comparison_operator"
4444 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4445 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4446 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4447 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4448 (clobber (reg:CC 24))]
4451 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4452 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4453 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4454 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4455 [(set_attr "conds" "clob")
4456 (set_attr "length" "8,8,12,12")])
4459 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4461 (match_operator 5 "comparison_operator"
4462 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4463 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4464 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4465 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4466 (clobber (reg:CC 24))]
4469 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4470 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4471 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4472 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4473 [(set_attr "conds" "clob")
4474 (set_attr "length" "8,8,12,12")])
4477 [(set (match_operand:SI 0 "s_register_operand" "=r")
4478 (match_operator:SI 1 "shiftable_operator"
4479 [(match_operand:SI 2 "memory_operand" "m")
4480 (match_operand:SI 3 "memory_operand" "m")]))
4481 (clobber (match_scratch:SI 4 "=r"))]
4482 "adjacent_mem_locations (operands[2], operands[3])"
4487 int val1 = 0, val2 = 0;
4489 if (REGNO (operands[0]) > REGNO (operands[4]))
4491 ldm[1] = operands[4];
4492 ldm[2] = operands[0];
4496 ldm[1] = operands[0];
4497 ldm[2] = operands[4];
4499 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4500 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4501 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4502 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4503 arith[0] = operands[0];
4504 arith[3] = operands[1];
4518 ldm[0] = ops[0] = operands[4];
4519 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4520 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4521 output_add_immediate (ops);
4523 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4525 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4529 ldm[0] = XEXP (operands[3], 0);
4531 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4533 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4537 ldm[0] = XEXP (operands[2], 0);
4539 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4541 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4543 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4547 [(set_attr "length" "12")
4548 (set_attr "type" "load")])
4550 ;; the arm can support extended pre-inc instructions
4552 ;; In all these cases, we use operands 0 and 1 for the register being
4553 ;; incremented because those are the operands that local-alloc will
4554 ;; tie and these are the pair most likely to be tieable (and the ones
4555 ;; that will benefit the most).
4557 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4558 ;; elimination will cause too many headaches.
4561 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4562 (match_operand:SI 2 "index_operand" "rJ")))
4563 (match_operand:QI 3 "s_register_operand" "r"))
4564 (set (match_operand:SI 0 "s_register_operand" "=r")
4565 (plus:SI (match_dup 1) (match_dup 2)))]
4566 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4567 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4568 && (GET_CODE (operands[2]) != REG
4569 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4570 "str%?b\\t%3, [%0, %2]!"
4571 [(set_attr "type" "store1")])
4574 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4575 (match_operand:SI 2 "s_register_operand" "r")))
4576 (match_operand:QI 3 "s_register_operand" "r"))
4577 (set (match_operand:SI 0 "s_register_operand" "=r")
4578 (minus:SI (match_dup 1) (match_dup 2)))]
4579 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4580 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4581 && (GET_CODE (operands[2]) != REG
4582 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4583 "str%?b\\t%3, [%0, -%2]!"
4584 [(set_attr "type" "store1")])
4587 [(set (match_operand:QI 3 "s_register_operand" "=r")
4588 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4589 (match_operand:SI 2 "index_operand" "rJ"))))
4590 (set (match_operand:SI 0 "s_register_operand" "=r")
4591 (plus:SI (match_dup 1) (match_dup 2)))]
4592 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4593 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4594 && (GET_CODE (operands[2]) != REG
4595 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4596 "ldr%?b\\t%3, [%0, %2]!"
4597 [(set_attr "type" "load")])
4600 [(set (match_operand:QI 3 "s_register_operand" "=r")
4601 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4602 (match_operand:SI 2 "s_register_operand" "r"))))
4603 (set (match_operand:SI 0 "s_register_operand" "=r")
4604 (minus:SI (match_dup 1) (match_dup 2)))]
4605 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4606 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4607 && (GET_CODE (operands[2]) != REG
4608 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4609 "ldr%?b\\t%3, [%0, -%2]!"
4610 [(set_attr "type" "load")])
4613 [(set (match_operand:SI 3 "s_register_operand" "=r")
4615 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4616 (match_operand:SI 2 "index_operand" "rJ")))))
4617 (set (match_operand:SI 0 "s_register_operand" "=r")
4618 (plus:SI (match_dup 1) (match_dup 2)))]
4619 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4620 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4621 && (GET_CODE (operands[2]) != REG
4622 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4623 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4624 [(set_attr "type" "load")])
4627 [(set (match_operand:SI 3 "s_register_operand" "=r")
4629 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4630 (match_operand:SI 2 "s_register_operand" "r")))))
4631 (set (match_operand:SI 0 "s_register_operand" "=r")
4632 (minus:SI (match_dup 1) (match_dup 2)))]
4633 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4634 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4635 && (GET_CODE (operands[2]) != REG
4636 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4637 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4638 [(set_attr "type" "load")])
4641 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4642 (match_operand:SI 2 "index_operand" "rJ")))
4643 (match_operand:SI 3 "s_register_operand" "r"))
4644 (set (match_operand:SI 0 "s_register_operand" "=r")
4645 (plus:SI (match_dup 1) (match_dup 2)))]
4646 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4647 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4648 && (GET_CODE (operands[2]) != REG
4649 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4650 "str%?\\t%3, [%0, %2]!"
4651 [(set_attr "type" "store1")])
4654 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4655 (match_operand:SI 2 "s_register_operand" "r")))
4656 (match_operand:SI 3 "s_register_operand" "r"))
4657 (set (match_operand:SI 0 "s_register_operand" "=r")
4658 (minus:SI (match_dup 1) (match_dup 2)))]
4659 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4660 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4661 && (GET_CODE (operands[2]) != REG
4662 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4663 "str%?\\t%3, [%0, -%2]!"
4664 [(set_attr "type" "store1")])
4667 [(set (match_operand:SI 3 "s_register_operand" "=r")
4668 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4669 (match_operand:SI 2 "index_operand" "rJ"))))
4670 (set (match_operand:SI 0 "s_register_operand" "=r")
4671 (plus:SI (match_dup 1) (match_dup 2)))]
4672 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4673 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4674 && (GET_CODE (operands[2]) != REG
4675 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4676 "ldr%?\\t%3, [%0, %2]!"
4677 [(set_attr "type" "load")])
4680 [(set (match_operand:SI 3 "s_register_operand" "=r")
4681 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4682 (match_operand:SI 2 "s_register_operand" "r"))))
4683 (set (match_operand:SI 0 "s_register_operand" "=r")
4684 (minus:SI (match_dup 1) (match_dup 2)))]
4685 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4686 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4687 && (GET_CODE (operands[2]) != REG
4688 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4689 "ldr%?\\t%3, [%0, -%2]!"
4690 [(set_attr "type" "load")])
4693 [(set (match_operand:HI 3 "s_register_operand" "=r")
4694 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4695 (match_operand:SI 2 "index_operand" "rJ"))))
4696 (set (match_operand:SI 0 "s_register_operand" "=r")
4697 (plus:SI (match_dup 1) (match_dup 2)))]
4698 "(! BYTES_BIG_ENDIAN)
4699 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4700 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4701 && (GET_CODE (operands[2]) != REG
4702 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4703 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4704 [(set_attr "type" "load")])
4707 [(set (match_operand:HI 3 "s_register_operand" "=r")
4708 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4709 (match_operand:SI 2 "s_register_operand" "r"))))
4710 (set (match_operand:SI 0 "s_register_operand" "=r")
4711 (minus:SI (match_dup 1) (match_dup 2)))]
4712 "(!BYTES_BIG_ENDIAN)
4713 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4714 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4715 && (GET_CODE (operands[2]) != REG
4716 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4717 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4718 [(set_attr "type" "load")])
4721 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4722 [(match_operand:SI 3 "s_register_operand" "r")
4723 (match_operand:SI 4 "const_shift_operand" "n")])
4724 (match_operand:SI 1 "s_register_operand" "0")))
4725 (match_operand:QI 5 "s_register_operand" "r"))
4726 (set (match_operand:SI 0 "s_register_operand" "=r")
4727 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4729 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4730 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4731 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4732 "str%?b\\t%5, [%0, %3%S2]!"
4733 [(set_attr "type" "store1")])
4736 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4737 (match_operator:SI 2 "shift_operator"
4738 [(match_operand:SI 3 "s_register_operand" "r")
4739 (match_operand:SI 4 "const_shift_operand" "n")])))
4740 (match_operand:QI 5 "s_register_operand" "r"))
4741 (set (match_operand:SI 0 "s_register_operand" "=r")
4742 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4744 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4745 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4746 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4747 "str%?b\\t%5, [%0, -%3%S2]!"
4748 [(set_attr "type" "store1")])
4751 [(set (match_operand:QI 5 "s_register_operand" "=r")
4752 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4753 [(match_operand:SI 3 "s_register_operand" "r")
4754 (match_operand:SI 4 "const_shift_operand" "n")])
4755 (match_operand:SI 1 "s_register_operand" "0"))))
4756 (set (match_operand:SI 0 "s_register_operand" "=r")
4757 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4759 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4760 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4761 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4762 "ldr%?b\\t%5, [%0, %3%S2]!"
4763 [(set_attr "type" "load")])
4766 [(set (match_operand:QI 5 "s_register_operand" "=r")
4767 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4768 (match_operator:SI 2 "shift_operator"
4769 [(match_operand:SI 3 "s_register_operand" "r")
4770 (match_operand:SI 4 "const_shift_operand" "n")]))))
4771 (set (match_operand:SI 0 "s_register_operand" "=r")
4772 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4774 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4775 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4776 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4777 "ldr%?b\\t%5, [%0, -%3%S2]!"
4778 [(set_attr "type" "load")])
4781 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4782 [(match_operand:SI 3 "s_register_operand" "r")
4783 (match_operand:SI 4 "const_shift_operand" "n")])
4784 (match_operand:SI 1 "s_register_operand" "0")))
4785 (match_operand:SI 5 "s_register_operand" "r"))
4786 (set (match_operand:SI 0 "s_register_operand" "=r")
4787 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4789 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4790 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4791 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4792 "str%?\\t%5, [%0, %3%S2]!"
4793 [(set_attr "type" "store1")])
4796 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4797 (match_operator:SI 2 "shift_operator"
4798 [(match_operand:SI 3 "s_register_operand" "r")
4799 (match_operand:SI 4 "const_shift_operand" "n")])))
4800 (match_operand:SI 5 "s_register_operand" "r"))
4801 (set (match_operand:SI 0 "s_register_operand" "=r")
4802 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4804 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4805 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4806 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4807 "str%?\\t%5, [%0, -%3%S2]!"
4808 [(set_attr "type" "store1")])
4811 [(set (match_operand:SI 5 "s_register_operand" "=r")
4812 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4813 [(match_operand:SI 3 "s_register_operand" "r")
4814 (match_operand:SI 4 "const_shift_operand" "n")])
4815 (match_operand:SI 1 "s_register_operand" "0"))))
4816 (set (match_operand:SI 0 "s_register_operand" "=r")
4817 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4819 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4820 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4821 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4822 "ldr%?\\t%5, [%0, %3%S2]!"
4823 [(set_attr "type" "load")])
4826 [(set (match_operand:SI 5 "s_register_operand" "=r")
4827 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4828 (match_operator:SI 2 "shift_operator"
4829 [(match_operand:SI 3 "s_register_operand" "r")
4830 (match_operand:SI 4 "const_shift_operand" "n")]))))
4831 (set (match_operand:SI 0 "s_register_operand" "=r")
4832 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4834 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4835 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4836 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4837 "ldr%?\\t%5, [%0, -%3%S2]!"
4838 [(set_attr "type" "load")])
4841 [(set (match_operand:HI 5 "s_register_operand" "=r")
4842 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
4843 [(match_operand:SI 3 "s_register_operand" "r")
4844 (match_operand:SI 4 "const_shift_operand" "n")])
4845 (match_operand:SI 1 "s_register_operand" "0"))))
4846 (set (match_operand:SI 0 "s_register_operand" "=r")
4847 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4849 "(! BYTES_BIG_ENDIAN)
4850 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4851 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4852 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4853 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
4854 [(set_attr "type" "load")])
4857 [(set (match_operand:HI 5 "s_register_operand" "=r")
4858 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4859 (match_operator:SI 2 "shift_operator"
4860 [(match_operand:SI 3 "s_register_operand" "r")
4861 (match_operand:SI 4 "const_shift_operand" "n")]))))
4862 (set (match_operand:SI 0 "s_register_operand" "=r")
4863 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4865 "(! BYTES_BIG_ENDIAN)
4866 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4867 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4868 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4869 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
4870 [(set_attr "type" "load")])
4872 ; It can also support extended post-inc expressions, but combine doesn't
4874 ; It doesn't seem worth adding peepholes for anything but the most common
4875 ; cases since, unlike combine, the increment must immediately follow the load
4876 ; for this pattern to match.
4877 ; When loading we must watch to see that the base register isn't trampled by
4878 ; the load. In such cases this isn't a post-inc expression.
4881 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
4882 (match_operand:QI 2 "s_register_operand" "r"))
4884 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4886 "str%?b\\t%2, [%0], %1")
4889 [(set (match_operand:QI 0 "s_register_operand" "=r")
4890 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
4892 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
4893 "REGNO(operands[0]) != REGNO(operands[1])
4894 && (GET_CODE (operands[2]) != REG
4895 || REGNO(operands[0]) != REGNO (operands[2]))"
4896 "ldr%?b\\t%0, [%1], %2")
4899 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
4900 (match_operand:SI 2 "s_register_operand" "r"))
4902 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4904 "str%?\\t%2, [%0], %1")
4907 [(set (match_operand:HI 0 "s_register_operand" "=r")
4908 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
4910 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
4911 "(! BYTES_BIG_ENDIAN)
4912 && REGNO(operands[0]) != REGNO(operands[1])
4913 && (GET_CODE (operands[2]) != REG
4914 || REGNO(operands[0]) != REGNO (operands[2]))"
4915 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
4918 [(set (match_operand:SI 0 "s_register_operand" "=r")
4919 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
4921 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
4922 "REGNO(operands[0]) != REGNO(operands[1])
4923 && (GET_CODE (operands[2]) != REG
4924 || REGNO(operands[0]) != REGNO (operands[2]))"
4925 "ldr%?\\t%0, [%1], %2")
4928 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
4929 (match_operand:SI 1 "index_operand" "rJ")))
4930 (match_operand:QI 2 "s_register_operand" "r"))
4931 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
4933 "str%?b\\t%2, [%0, %1]!")
4936 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
4937 [(match_operand:SI 0 "s_register_operand" "r")
4938 (match_operand:SI 1 "const_int_operand" "n")])
4939 (match_operand:SI 2 "s_register_operand" "+r")))
4940 (match_operand:QI 3 "s_register_operand" "r"))
4941 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
4944 "str%?b\\t%3, [%2, %0%S4]!")
4946 ; This pattern is never tried by combine, so do it as a peephole
4949 [(set (match_operand:SI 0 "s_register_operand" "=r")
4950 (match_operand:SI 1 "s_register_operand" "r"))
4951 (set (match_operand 2 "cc_register" "")
4952 (compare (match_dup 1) (const_int 0)))]
4954 "sub%?s\\t%0, %1, #0"
4955 [(set_attr "conds" "set")])
4957 ; Peepholes to spot possible load- and store-multiples, if the ordering is
4958 ; reversed, check that the memory references aren't volatile.
4961 [(set (match_operand:SI 0 "s_register_operand" "=r")
4962 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
4964 (set (match_operand:SI 2 "s_register_operand" "=r")
4965 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
4966 (set (match_operand:SI 3 "s_register_operand" "=r")
4967 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
4968 (set (match_operand:SI 4 "s_register_operand" "=r")
4969 (mem:SI (match_dup 1)))]
4970 "REGNO (operands[0]) > REGNO (operands[2])
4971 && REGNO (operands[2]) > REGNO (operands[3])
4972 && REGNO (operands[3]) > REGNO (operands[4])
4973 && !(REGNO (operands[1]) == REGNO (operands[0])
4974 || REGNO (operands[1]) == REGNO (operands[2])
4975 || REGNO (operands[1]) == REGNO (operands[3])
4976 || REGNO (operands[1]) == REGNO (operands[4]))
4977 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
4978 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
4979 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
4980 (prev_nonnote_insn (insn)))))
4981 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
4983 (prev_nonnote_insn (insn))))))"
4984 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
4987 [(set (match_operand:SI 0 "s_register_operand" "=r")
4988 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
4990 (set (match_operand:SI 2 "s_register_operand" "=r")
4991 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
4992 (set (match_operand:SI 3 "s_register_operand" "=r")
4993 (mem:SI (match_dup 1)))]
4994 "REGNO (operands[0]) > REGNO (operands[2])
4995 && REGNO (operands[2]) > REGNO (operands[3])
4996 && !(REGNO (operands[1]) == REGNO (operands[0])
4997 || REGNO (operands[1]) == REGNO (operands[2])
4998 || REGNO (operands[1]) == REGNO (operands[3]))
4999 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5000 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5001 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5002 (prev_nonnote_insn (insn)))))"
5003 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5006 [(set (match_operand:SI 0 "s_register_operand" "=r")
5007 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5009 (set (match_operand:SI 2 "s_register_operand" "=r")
5010 (mem:SI (match_dup 1)))]
5011 "REGNO (operands[0]) > REGNO (operands[2])
5012 && !(REGNO (operands[1]) == REGNO (operands[0])
5013 || REGNO (operands[1]) == REGNO (operands[2]))
5014 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5015 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5016 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5019 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5021 (match_operand:SI 0 "s_register_operand" "r"))
5022 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5023 (match_operand:SI 2 "s_register_operand" "r"))
5024 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5025 (match_operand:SI 3 "s_register_operand" "r"))
5026 (set (mem:SI (match_dup 1))
5027 (match_operand:SI 4 "s_register_operand" "r"))]
5028 "REGNO (operands[0]) > REGNO (operands[2])
5029 && REGNO (operands[2]) > REGNO (operands[3])
5030 && REGNO (operands[3]) > REGNO (operands[4])
5031 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5032 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5033 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5034 (prev_nonnote_insn (insn)))))
5035 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5037 (prev_nonnote_insn (insn))))))"
5038 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5041 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5043 (match_operand:SI 0 "s_register_operand" "r"))
5044 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5045 (match_operand:SI 2 "s_register_operand" "r"))
5046 (set (mem:SI (match_dup 1))
5047 (match_operand:SI 3 "s_register_operand" "r"))]
5048 "REGNO (operands[0]) > REGNO (operands[2])
5049 && REGNO (operands[2]) > REGNO (operands[3])
5050 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5051 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5052 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5053 (prev_nonnote_insn (insn)))))"
5054 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5057 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5059 (match_operand:SI 0 "s_register_operand" "r"))
5060 (set (mem:SI (match_dup 1))
5061 (match_operand:SI 2 "s_register_operand" "r"))]
5062 "REGNO (operands[0]) > REGNO (operands[2])
5063 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5064 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5065 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5067 ;; A call followed by return can be replaced by restoring the regs and
5068 ;; jumping to the subroutine, provided we aren't passing the address of
5069 ;; any of our local variables. If we call alloca then this is unsafe
5070 ;; since restoring the frame frees the memory, which is not what we want.
5071 ;; Sometimes the return might have been targeted by the final prescan:
5072 ;; if so then emit a propper return insn as well.
5073 ;; Unfortunately, if the frame pointer is required, we don't know if the
5074 ;; current function has any implicit stack pointer adjustments that will
5075 ;; be restored by the return: we can't therefore do a tail call.
5076 ;; Another unfortunate that we can't handle is if current_function_args_size
5077 ;; is non-zero: in this case elimination of the argument pointer assumed
5078 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5082 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5083 (match_operand:SI 1 "general_operand" "g"))
5084 (clobber (reg:SI 14))])
5086 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5087 && !get_frame_size () && !current_function_calls_alloca
5088 && !frame_pointer_needed && !current_function_args_size)"
5091 extern rtx arm_target_insn;
5092 extern int arm_ccfsm_state, arm_current_cc;
5094 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5096 arm_current_cc ^= 1;
5097 output_return_instruction (NULL, TRUE);
5098 arm_ccfsm_state = 0;
5099 arm_target_insn = NULL;
5102 output_return_instruction (NULL, FALSE);
5103 return \"b%?\\t%a0\";
5105 [(set (attr "conds")
5106 (if_then_else (eq_attr "cpu" "arm6")
5107 (const_string "clob")
5108 (const_string "nocond")))
5109 (set_attr "length" "8")])
5112 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5113 (call (mem:SI (match_operand:SI 1 "" "i"))
5114 (match_operand:SI 2 "general_operand" "g")))
5115 (clobber (reg:SI 14))])
5117 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5118 && !get_frame_size () && !current_function_calls_alloca
5119 && !frame_pointer_needed && !current_function_args_size)"
5122 extern rtx arm_target_insn;
5123 extern int arm_ccfsm_state, arm_current_cc;
5125 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5127 arm_current_cc ^= 1;
5128 output_return_instruction (NULL, TRUE);
5129 arm_ccfsm_state = 0;
5130 arm_target_insn = NULL;
5133 output_return_instruction (NULL, FALSE);
5134 return \"b%?\\t%a1\";
5136 [(set (attr "conds")
5137 (if_then_else (eq_attr "cpu" "arm6")
5138 (const_string "clob")
5139 (const_string "nocond")))
5140 (set_attr "length" "8")])
5142 ;; As above but when this function is not void, we must be returning the
5143 ;; result of the called subroutine.
5146 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5147 (call (mem:SI (match_operand:SI 1 "" "i"))
5148 (match_operand:SI 2 "general_operand" "g")))
5149 (clobber (reg:SI 14))])
5152 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5153 && !get_frame_size () && !current_function_calls_alloca
5154 && !frame_pointer_needed && !current_function_args_size)"
5157 extern rtx arm_target_insn;
5158 extern int arm_ccfsm_state, arm_current_cc;
5160 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5162 arm_current_cc ^= 1;
5163 output_return_instruction (NULL, TRUE);
5164 arm_ccfsm_state = 0;
5165 arm_target_insn = NULL;
5168 output_return_instruction (NULL, FALSE);
5169 return \"b%?\\t%a1\";
5171 [(set (attr "conds")
5172 (if_then_else (eq_attr "cpu" "arm6")
5173 (const_string "clob")
5174 (const_string "nocond")))
5175 (set_attr "length" "8")])
5177 ;; If calling a subroutine and then jumping back to somewhere else, but not
5178 ;; too far away, then we can set the link register with the branch address
5179 ;; and jump direct to the subroutine. On return from the subroutine
5180 ;; execution continues at the branch; this avoids a prefetch stall.
5181 ;; We use the length attribute (via short_branch ()) to establish whether or
5182 ;; not this is possible, this is the same asthe sparc does.
5185 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5186 (match_operand:SI 1 "general_operand" "g"))
5187 (clobber (reg:SI 14))])
5189 (label_ref (match_operand 2 "" "")))]
5190 "GET_CODE (operands[0]) == SYMBOL_REF
5191 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5192 && arm_insn_not_targeted (insn)"
5195 int backward = arm_backwards_branch (INSN_UID (insn),
5196 INSN_UID (operands[2]));
5199 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5200 * above, leaving it out means that the code will still run on an arm 2 or 3
5205 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5207 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5212 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5214 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5216 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5218 return \"b%?\\t%a0\";
5220 [(set (attr "conds")
5221 (if_then_else (eq_attr "cpu" "arm6")
5222 (const_string "clob")
5223 (const_string "nocond")))
5224 (set (attr "length")
5225 (if_then_else (eq_attr "cpu" "arm6")
5230 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5231 (call (mem:SI (match_operand:SI 1 "" "i"))
5232 (match_operand:SI 2 "general_operand" "g")))
5233 (clobber (reg:SI 14))])
5235 (label_ref (match_operand 3 "" "")))]
5236 "GET_CODE (operands[0]) == SYMBOL_REF
5237 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5238 && arm_insn_not_targeted (insn)"
5241 int backward = arm_backwards_branch (INSN_UID (insn),
5242 INSN_UID (operands[3]));
5245 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5246 * above, leaving it out means that the code will still run on an arm 2 or 3
5251 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5253 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5258 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5260 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5262 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5264 return \"b%?\\t%a1\";
5266 [(set (attr "conds")
5267 (if_then_else (eq_attr "cpu" "arm6")
5268 (const_string "clob")
5269 (const_string "nocond")))
5270 (set (attr "length")
5271 (if_then_else (eq_attr "cpu" "arm6")
5277 (if_then_else (match_operator 0 "comparison_operator"
5278 [(match_operator:SI 1 "shift_operator"
5279 [(match_operand:SI 2 "s_register_operand" "r")
5280 (match_operand:SI 3 "reg_or_int_operand" "rM")])
5281 (match_operand:SI 4 "s_register_operand" "r")])
5282 (label_ref (match_operand 5 "" ""))
5287 (compare:CC (match_dup 4)
5288 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5290 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5291 (label_ref (match_dup 5))
5294 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5295 operands[1], operands[2]);
5299 [(set (match_operand:SI 0 "s_register_operand" "")
5300 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5302 (neg:SI (match_operator:SI 2 "comparison_operator"
5303 [(match_operand:SI 3 "s_register_operand" "")
5304 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5305 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5307 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5308 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5312 ;; This pattern can be used because cc_noov mode implies that the following
5313 ;; branch will be an equality (EQ or NE), so the sign extension is not
5314 ;; needed. Combine doesn't eliminate these because by the time it sees the
5315 ;; branch it no-longer knows that the data came from memory.
5318 [(set (reg:CC_NOOV 24)
5320 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5322 (match_operand 1 "immediate_operand" "I")))
5323 (clobber (match_scratch:SI 2 "=r"))]
5324 "((unsigned long) INTVAL (operands[1]))
5325 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5327 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5328 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5329 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5332 [(set_attr "conds" "set")
5333 (set_attr "length" "8")
5334 (set_attr "type" "load")])
5336 (define_expand "prologue"
5337 [(clobber (const_int 0))]
5340 arm_expand_prologue ();
5344 (define_expand "save_stack_nonlocal"
5345 [(match_operand:DI 0 "memory_operand" "")
5346 (match_operand:SI 1 "s_register_operand" "")]
5350 /* We also need to save the frame pointer for non-local gotos */
5351 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
5352 hard_frame_pointer_rtx);
5353 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
5357 (define_expand "restore_stack_nonlocal"
5358 [(match_operand:SI 0 "s_register_operand" "")
5359 (match_operand:DI 1 "memory_operand" "")]
5363 /* Restore the frame pointer first, the stack pointer second. */
5364 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
5365 emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0,
5370 ;; This split is only used during output to reduce the number of patterns
5371 ;; that need assembler instructions adding to them. We allowed the setting
5372 ;; of the conditions to be implicit during rtl generation so that
5373 ;; the conditional compare patterns would work. However this conflicts to
5374 ;; some extend with the conditional data operations, so we have to split them
5378 [(set (match_operand:SI 0 "s_register_operand" "")
5379 (if_then_else:SI (match_operator 1 "comparison_operator"
5380 [(match_operand 2 "" "") (match_operand 3 "" "")])
5381 (match_operand 4 "" "")
5382 (match_operand 5 "" "")))
5385 [(set (match_dup 6) (match_dup 7))
5387 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5392 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5395 operands[6] = gen_rtx (REG, mode, 24);
5396 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5402 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5403 (if_then_else:SI (match_operator 4 "comparison_operator"
5404 [(match_operand 3 "cc_register" "") (const_int 0)])
5405 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5407 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5411 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5412 [(set_attr "conds" "use")
5413 (set_attr "length" "4,8")])
5415 ;; The next two patterns occur when an AND operation is followed by a
5416 ;; scc insn sequence
5419 [(set (match_operand:SI 0 "s_register_operand" "=r")
5420 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5422 (match_operand:SI 2 "immediate_operand" "n")))]
5425 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5426 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5427 return \"mvnne\\t%0, #0\";
5429 [(set_attr "conds" "clob")
5430 (set_attr "length" "8")])
5433 [(set (match_operand:SI 0 "s_register_operand" "=r")
5435 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5437 (match_operand:SI 2 "immediate_operand" "n"))))]
5440 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5441 output_asm_insn (\"tst\\t%1, %2\", operands);
5442 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5443 return \"movne\\t%0, #0\";
5445 [(set_attr "conds" "clob")
5446 (set_attr "length" "12")])
5448 ;; Push multiple registers to the stack. The first register is in the
5449 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5452 [(match_parallel 2 "multi_register_push"
5453 [(set (match_operand:BLK 0 "memory_operand" "=m")
5454 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5460 extern int lr_save_eliminated;
5462 if (lr_save_eliminated)
5464 if (XVECLEN (operands[2], 0) > 1)
5468 strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5469 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5471 strcat (pattern, \", %|\");
5472 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5475 strcat (pattern, \"}\");
5476 output_asm_insn (pattern, operands);
5479 [(set_attr "type" "store4")])