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 "nonimmediate_operand" "")
1774 (set (match_operand:SI 0 "s_register_operand" "")
1775 (lshiftrt:SI (match_dup 2) (const_int 16)))]
1779 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1781 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
1784 if (! s_register_operand (operands[1], HImode))
1785 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1786 operands[1] = gen_lowpart (SImode, operands[1]);
1787 operands[2] = gen_reg_rtx (SImode);
1790 (define_expand "zero_extendqisi2"
1791 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1793 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1796 if (GET_CODE (operands[1]) != MEM)
1798 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
1805 [(set (match_operand:SI 0 "s_register_operand" "=r")
1806 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1808 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1809 [(set_attr "type" "load")])
1812 [(set (match_operand:SI 0 "s_register_operand" "")
1813 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
1814 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1815 "GET_CODE (operands[1]) != MEM"
1816 [(set (match_dup 2) (match_dup 1))
1817 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
1821 [(set (reg:CC_NOOV 24)
1822 (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1826 [(set_attr "conds" "set")])
1828 (define_expand "extendhisi2"
1830 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
1832 (set (match_operand:SI 0 "s_register_operand" "")
1833 (ashiftrt:SI (match_dup 2)
1838 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1840 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
1843 if (! s_register_operand (operands[1], HImode))
1844 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1845 operands[1] = gen_lowpart (SImode, operands[1]);
1846 operands[2] = gen_reg_rtx (SImode);
1849 (define_expand "extendhisi2_mem"
1850 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
1852 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
1853 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
1854 (set (match_operand:SI 0 "" "")
1855 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
1858 operands[0] = gen_lowpart (SImode, operands[0]);
1859 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1860 operands[2] = gen_reg_rtx (SImode);
1861 operands[3] = gen_reg_rtx (SImode);
1862 operands[6] = gen_reg_rtx (SImode);
1864 if (BYTES_BIG_ENDIAN)
1866 operands[4] = operands[2];
1867 operands[5] = operands[3];
1871 operands[4] = operands[3];
1872 operands[5] = operands[2];
1876 (define_expand "extendqihi2"
1878 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1880 (set (match_operand:HI 0 "s_register_operand" "")
1881 (ashiftrt:SI (match_dup 2)
1885 { operands[0] = gen_lowpart (SImode, operands[0]);
1886 operands[1] = gen_lowpart (SImode, operands[1]);
1887 operands[2] = gen_reg_rtx (SImode); }")
1889 (define_expand "extendqisi2"
1891 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1893 (set (match_operand:SI 0 "s_register_operand" "")
1894 (ashiftrt:SI (match_dup 2)
1898 { operands[1] = gen_lowpart (SImode, operands[1]);
1899 operands[2] = gen_reg_rtx (SImode); }")
1901 (define_insn "extendsfdf2"
1902 [(set (match_operand:DF 0 "s_register_operand" "=f")
1903 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
1906 [(set_attr "type" "ffarith")])
1908 (define_insn "extendsfxf2"
1909 [(set (match_operand:XF 0 "s_register_operand" "=f")
1910 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
1911 "ENABLE_XF_PATTERNS"
1913 [(set_attr "type" "ffarith")])
1915 (define_insn "extenddfxf2"
1916 [(set (match_operand:XF 0 "s_register_operand" "=f")
1917 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
1918 "ENABLE_XF_PATTERNS"
1920 [(set_attr "type" "ffarith")])
1923 ;; Move insns (including loads and stores)
1925 ;; XXX Just some ideas about movti.
1926 ;; I don't think these are a good idea on the arm, there just aren't enough
1928 ;;(define_expand "loadti"
1929 ;; [(set (match_operand:TI 0 "s_register_operand" "")
1930 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
1933 ;;(define_expand "storeti"
1934 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
1935 ;; (match_operand:TI 1 "s_register_operand" ""))]
1938 ;;(define_expand "movti"
1939 ;; [(set (match_operand:TI 0 "general_operand" "")
1940 ;; (match_operand:TI 1 "general_operand" ""))]
1946 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1947 ;; operands[1] = copy_to_reg (operands[1]);
1948 ;; if (GET_CODE (operands[0]) == MEM)
1949 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
1950 ;; else if (GET_CODE (operands[1]) == MEM)
1951 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
1955 ;; emit_insn (insn);
1959 ;; Recognise garbage generated above.
1962 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
1963 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
1967 ;; register mem = (which_alternative < 3);
1968 ;; register char *template;
1970 ;; operands[mem] = XEXP (operands[mem], 0);
1971 ;; switch (which_alternative)
1973 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
1974 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
1975 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
1976 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
1977 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
1978 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
1980 ;; output_asm_insn (template, operands);
1985 (define_insn "movdi"
1986 [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
1987 (match_operand:DI 1 "di_operand" "rIK,n,o<>,r,F"))]
1990 return (output_move_double (operands));
1992 [(set_attr "length" "8,32,8,8,32")
1993 (set_attr "type" "*,*,load,store2,*")])
1995 (define_expand "movsi"
1996 [(set (match_operand:SI 0 "general_operand" "")
1997 (match_operand:SI 1 "general_operand" ""))]
2000 /* Everything except mem = const or mem = mem can be done easily */
2001 if (GET_CODE (operands[0]) == MEM)
2002 operands[1] = force_reg (SImode, operands[1]);
2003 if (GET_CODE (operands[1]) == CONST_INT
2004 && !(const_ok_for_arm (INTVAL (operands[1]))
2005 || const_ok_for_arm (~INTVAL (operands[1]))))
2007 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2009 (reload_in_progress || reload_completed ? 0
2010 : preserve_subexpressions_p ()));
2016 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r,r")
2017 (match_operand:SI 1 "general_operand" "R,m,K,rI,r,S,?n"))]
2018 "(register_operand (operands[0], SImode)
2019 && (GET_CODE (operands[1]) != SYMBOL_REF
2020 || CONSTANT_ADDRESS_P (operands[1])))
2021 || register_operand (operands[1], SImode)"
2023 switch (which_alternative)
2026 /* NB Calling get_attr_length may cause the insn to be re-extracted... */
2027 if (get_attr_length (insn) == 8)
2029 /* ... so modify the operands here. */
2030 operands[1] = XEXP (operands[1], 0);
2031 output_asm_insn (\"sub%?\\t%0, %|pc, #(8 + . - %a1) & ~4095\",
2033 output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
2039 operands[1] = XEXP (operands[1], 0);
2040 output_asm_insn (\"ldr%?\\t%0, [%|pc, %1 - . - 8]\", operands);
2045 if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2046 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
2048 return \"ldr%?\\t%0, %1\";
2051 return \"mov%?\\t%0, %1\";
2053 return \"mvn%?\\t%0, #%B1\";
2055 return \"str%?\\t%1, %0\";
2057 return output_load_symbol (insn, operands);
2062 [(set (attr "length")
2063 (cond [(eq_attr "alternative" "0")
2067 (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
2071 (ior (eq_attr "alternative" "5")
2072 (eq_attr "alternative" "6")) (const_int 16)]
2074 (set_attr "type" "load,load,*,*,store1,*,*")])
2077 [(set (match_operand:SI 0 "s_register_operand" "")
2078 (match_operand:SI 1 "const_int_operand" ""))]
2079 "! (const_ok_for_arm (INTVAL (operands[1]))
2080 || const_ok_for_arm (~INTVAL (operands[1])))"
2081 [(clobber (const_int 0))]
2083 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2088 ;; If copying one reg to another we can set the condition codes according to
2089 ;; its value. Such a move is common after a return from subroutine and the
2090 ;; result is being tested against zero.
2093 [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
2095 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2099 sub%?s\\t%0, %1, #0"
2100 [(set_attr "conds" "set")])
2102 ;; Subroutine to store a half word from a register into memory.
2103 ;; Operand 0 is the source register (HImode)
2104 ;; Operand 1 is the destination address in a register (SImode)
2106 ;; In both this routine and the next, we must be careful not to spill
2107 ;; a memory address of reg+large_const into a seperate PLUS insn, since this
2108 ;; can generate unrecognizable rtl.
2110 (define_expand "storehi"
2111 [;; store the low byte
2112 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2113 ;; extract the high byte
2115 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2116 ;; store the high byte
2117 (set (mem:QI (match_dup 4))
2118 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2122 enum rtx_code code = GET_CODE (operands[1]);
2124 if ((code == PLUS || code == MINUS)
2125 && (GET_CODE (XEXP (operands[1], 1)) == REG
2126 || GET_CODE (XEXP (operands[1], 0)) != REG))
2127 operands[1] = force_reg (SImode, operands[1]);
2128 operands[4] = plus_constant (operands[1], 1);
2129 operands[3] = gen_lowpart (QImode, operands[0]);
2130 operands[0] = gen_lowpart (SImode, operands[0]);
2131 operands[2] = gen_reg_rtx (SImode);
2135 (define_expand "storehi_bigend"
2136 [(set (mem:QI (match_dup 4)) (match_dup 3))
2138 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2139 (set (mem:QI (match_operand 1 "" ""))
2140 (subreg:QI (match_dup 2) 0))]
2144 enum rtx_code code = GET_CODE (operands[1]);
2145 if ((code == PLUS || code == MINUS)
2146 && (GET_CODE (XEXP (operands[1], 1)) == REG
2147 || GET_CODE (XEXP (operands[1], 0)) != REG))
2148 operands[1] = force_reg (SImode, operands[1]);
2150 operands[4] = plus_constant (operands[1], 1);
2151 operands[3] = gen_lowpart (QImode, operands[0]);
2152 operands[0] = gen_lowpart (SImode, operands[0]);
2153 operands[2] = gen_reg_rtx (SImode);
2157 ;; Subroutine to store a half word integer constant into memory.
2158 (define_expand "storeinthi"
2159 [(set (mem:QI (match_operand:SI 0 "" ""))
2160 (subreg:QI (match_operand 1 "" "") 0))
2161 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2165 HOST_WIDE_INT value = INTVAL (operands[1]);
2166 enum rtx_code code = GET_CODE (operands[0]);
2168 if ((code == PLUS || code == MINUS)
2169 && (GET_CODE (XEXP (operands[0], 1)) == REG
2170 || GET_CODE (XEXP (operands[0], 0)) != REG))
2171 operands[0] = force_reg (SImode, operands[0]);
2173 operands[1] = gen_reg_rtx (SImode);
2174 if (BYTES_BIG_ENDIAN)
2176 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2177 if ((value & 255) == ((value >> 8) & 255))
2178 operands[2] = operands[1];
2181 operands[2] = gen_reg_rtx (SImode);
2182 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2187 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2188 if ((value & 255) == ((value >> 8) & 255))
2189 operands[2] = operands[1];
2192 operands[2] = gen_reg_rtx (SImode);
2193 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2197 operands[3] = plus_constant (operands[0], 1);
2201 (define_expand "movhi"
2202 [(set (match_operand:HI 0 "general_operand" "")
2203 (match_operand:HI 1 "general_operand" ""))]
2209 if (! (reload_in_progress || reload_completed))
2211 if (GET_CODE (operands[0]) == MEM)
2213 if (GET_CODE (operands[1]) == CONST_INT)
2214 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
2217 if (GET_CODE (operands[1]) == MEM)
2218 operands[1] = force_reg (HImode, operands[1]);
2219 if (BYTES_BIG_ENDIAN)
2220 emit_insn (gen_storehi_bigend (operands[1],
2221 XEXP (operands[0], 0)));
2223 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
2227 /* Sign extend a constant, and keep it in an SImode reg. */
2228 else if (GET_CODE (operands[1]) == CONST_INT)
2230 rtx reg = gen_reg_rtx (SImode);
2231 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2233 /* If the constant is already valid, leave it alone. */
2234 if (! const_ok_for_arm (val))
2236 /* If setting all the top bits will make the constant
2237 loadable in a single instruction, then set them.
2238 Otherwise, sign extend the number. */
2240 if (const_ok_for_arm (~ (val | ~0xffff)))
2242 else if (val & 0x8000)
2246 emit_insn (gen_movsi (reg, GEN_INT (val)));
2247 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2249 else if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2251 rtx reg = gen_reg_rtx (SImode);
2252 emit_insn (gen_movhi_bytes (reg, operands[1]));
2253 operands[1] = gen_lowpart (HImode, reg);
2255 else if (BYTES_BIG_ENDIAN && GET_CODE (operands[1]) == MEM)
2257 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2264 (define_expand "movhi_bytes"
2265 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2267 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2268 (set (match_operand:SI 0 "" "")
2269 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
2272 operands[0] = gen_lowpart (SImode, operands[0]);
2273 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2274 operands[2] = gen_reg_rtx (SImode);
2275 operands[3] = gen_reg_rtx (SImode);
2277 if (BYTES_BIG_ENDIAN)
2279 operands[4] = operands[2];
2280 operands[5] = operands[3];
2284 operands[4] = operands[3];
2285 operands[5] = operands[2];
2289 (define_expand "movhi_bigend"
2291 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2294 (ashiftrt:SI (match_dup 2) (const_int 16)))
2295 (set (match_operand:HI 0 "s_register_operand" "")
2296 (subreg:HI (match_dup 3) 0))]
2299 operands[2] = gen_reg_rtx (SImode);
2300 operands[3] = gen_reg_rtx (SImode);
2303 ;; Pattern to recognise insn generated default case above
2306 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2307 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2309 && ! TARGET_SHORT_BY_BYTES
2310 && (GET_CODE (operands[1]) != CONST_INT
2311 || const_ok_for_arm (INTVAL (operands[1]))
2312 || const_ok_for_arm (~INTVAL (operands[1])))"
2314 mov%?\\t%0, %1\\t%@ movhi
2315 mvn%?\\t%0, #%B1\\t%@ movhi
2316 ldr%?\\t%0, %1\\t%@ movhi"
2317 [(set_attr "type" "*,*,load")])
2320 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2321 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2323 && ! TARGET_SHORT_BY_BYTES
2324 && (GET_CODE (operands[1]) != CONST_INT
2325 || const_ok_for_arm (INTVAL (operands[1]))
2326 || const_ok_for_arm (~INTVAL (operands[1])))"
2328 mov%?\\t%0, %1\\t%@ movhi
2329 mvn%?\\t%0, #%B1\\t%@ movhi
2330 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2331 [(set_attr "type" "*,*,load")
2332 (set_attr "length" "4,4,8")])
2335 [(set (match_operand:SI 0 "s_register_operand" "=r")
2336 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2339 && ! TARGET_SHORT_BY_BYTES"
2340 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2341 [(set_attr "type" "load")])
2344 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
2345 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
2346 "TARGET_SHORT_BY_BYTES"
2348 mov%?\\t%0, %1\\t%@ movhi
2349 mvn%?\\t%0, #%B1\\t%@ movhi")
2352 (define_expand "reload_outhi"
2353 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2354 (match_operand:HI 1 "s_register_operand" "r")
2355 (match_operand:SI 2 "s_register_operand" "=&r")])]
2358 arm_reload_out_hi (operands);
2362 (define_expand "reload_inhi"
2363 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
2364 (match_operand:HI 1 "reload_memory_operand" "o")
2365 (match_operand:SI 2 "s_register_operand" "=&r")])]
2366 "TARGET_SHORT_BY_BYTES"
2368 arm_reload_in_hi (operands);
2372 (define_expand "movqi"
2373 [(set (match_operand:QI 0 "general_operand" "")
2374 (match_operand:QI 1 "general_operand" ""))]
2377 /* Everything except mem = const or mem = mem can be done easily */
2379 if (!(reload_in_progress || reload_completed))
2381 if (GET_CODE (operands[1]) == CONST_INT)
2383 rtx reg = gen_reg_rtx (SImode);
2385 emit_insn (gen_movsi (reg, operands[1]));
2386 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2388 if (GET_CODE (operands[0]) == MEM)
2389 operands[1] = force_reg (QImode, operands[1]);
2395 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2396 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
2397 "register_operand (operands[0], QImode)
2398 || register_operand (operands[1], QImode)"
2404 [(set_attr "type" "*,*,load,store1")])
2406 (define_expand "movsf"
2407 [(set (match_operand:SF 0 "general_operand" "")
2408 (match_operand:SF 1 "general_operand" ""))]
2411 if (GET_CODE (operands[1]) == CONST_DOUBLE
2412 && ((GET_CODE (operands[0]) == REG
2413 && REGNO (operands[0]) < 16)
2414 || ! (const_double_rtx_ok_for_fpu (operands[1])
2415 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2417 extern int optimize;
2418 rtx mem = force_const_mem (SFmode, operands[1]);
2421 if (reload_in_progress || reload_completed)
2422 addr = gen_rtx (REG, SImode, REGNO (operands[0]));
2424 addr = gen_reg_rtx (SImode);
2427 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2428 emit_insn (gen_movsi (addr, ptr));
2431 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2432 operands[1] = gen_rtx (MEM, SFmode, addr);
2434 if (GET_CODE (operands[0]) == MEM)
2435 operands[1] = force_reg (SFmode, operands[1]);
2439 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2440 (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
2441 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode)"
2447 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2448 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
2450 ldr%?\\t%0, %1\\t%@ float
2451 str%?\\t%1, %0\\t%@ float"
2452 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2454 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2456 (define_expand "movdf"
2457 [(set (match_operand:DF 0 "general_operand" "")
2458 (match_operand:DF 1 "general_operand" ""))]
2461 if (GET_CODE (operands[1]) == CONST_DOUBLE
2462 && ((GET_CODE (operands[0]) == REG
2463 && REGNO (operands[0]) < 16)
2464 || ! (const_double_rtx_ok_for_fpu (operands[1])
2465 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2467 extern int optimize;
2468 rtx mem = force_const_mem (DFmode, operands[1]);
2471 if (reload_in_progress || reload_completed)
2472 addr = gen_rtx (REG, SImode, REGNO (operands[0]));
2474 addr = gen_reg_rtx (SImode);
2477 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2478 emit_insn (gen_movsi (addr, ptr));
2481 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2482 operands[1] = gen_rtx (MEM, DFmode, addr);
2484 if (GET_CODE (operands[0]) == MEM)
2485 operands[1] = force_reg (DFmode, operands[1]);
2488 ;; Reloading a df mode value stored in integer regs to memory can require a
2490 (define_expand "reload_outdf"
2491 [(match_operand:DF 0 "reload_memory_operand" "=o")
2492 (match_operand:DF 1 "s_register_operand" "r")
2493 (match_operand:SI 2 "s_register_operand" "=&r")]
2496 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2497 operands[2] = XEXP (operands[0], 0);
2499 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2500 XEXP (XEXP (operands[0], 0), 1)));
2501 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2507 [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
2508 (match_operand:DF 1 "general_operand"
2509 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
2510 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2515 switch (which_alternative)
2518 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2521 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2524 ops[0] = operands[0];
2525 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2526 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2527 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2528 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2530 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2531 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2535 return \"mvf%?d\\t%0, %1\";
2537 case 5: return \"mnf%?d\\t%0, #%N1\";
2538 case 6: return \"ldf%?d\\t%0, %1\";
2539 case 7: return \"stf%?d\\t%1, %0\";
2540 case 8: return output_mov_double_fpu_from_arm (operands);
2541 case 9: return output_mov_double_arm_from_fpu (operands);
2542 case 10: return output_move_double (operands);
2546 [(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
2548 "load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2550 (define_expand "movxf"
2551 [(set (match_operand:XF 0 "general_operand" "")
2552 (match_operand:XF 1 "general_operand" ""))]
2553 "ENABLE_XF_PATTERNS"
2556 ;; Even when the XFmode patterns aren't enabled, we enable this after
2557 ;; reloading so that we can push floating point registers in the prologue.
2560 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2561 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2562 "ENABLE_XF_PATTERNS || reload_completed"
2564 switch (which_alternative)
2566 case 0: return \"mvf%?e\\t%0, %1\";
2567 case 1: return \"mnf%?e\\t%0, #%N1\";
2568 case 2: return \"ldf%?e\\t%0, %1\";
2569 case 3: return \"stf%?e\\t%1, %0\";
2570 case 4: return output_mov_long_double_fpu_from_arm (operands);
2571 case 5: return output_mov_long_double_arm_from_fpu (operands);
2572 case 6: return output_mov_long_double_arm_from_arm (operands);
2575 [(set_attr "length" "4,4,4,4,8,8,12")
2576 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2579 ;; load- and store-multiple insns
2580 ;; The arm can load/store any set of registers, provided that they are in
2581 ;; ascending order; but that is beyond GCC so stick with what it knows.
2583 (define_expand "load_multiple"
2584 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2585 (match_operand:SI 1 "" ""))
2586 (use (match_operand:SI 2 "" ""))])]
2589 /* Support only fixed point registers */
2590 if (GET_CODE (operands[2]) != CONST_INT
2591 || INTVAL (operands[2]) > 14
2592 || INTVAL (operands[2]) < 2
2593 || GET_CODE (operands[1]) != MEM
2594 || GET_CODE (operands[0]) != REG
2595 || REGNO (operands[0]) > 14
2596 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2600 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2601 force_reg (SImode, XEXP (operands[1], 0)),
2605 ;; Load multiple with write-back
2608 [(match_parallel 0 "load_multiple_operation"
2609 [(set (match_operand:SI 1 "s_register_operand" "+r")
2610 (plus:SI (match_dup 1)
2611 (match_operand:SI 2 "immediate_operand" "n")))
2612 (set (match_operand:SI 3 "s_register_operand" "=r")
2613 (mem:SI (match_dup 1)))])]
2614 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2618 int count = XVECLEN (operands[0], 0);
2620 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2621 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2622 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2624 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2628 [(set_attr "type" "load")])
2630 ;; Ordinary load multiple
2633 [(match_parallel 0 "load_multiple_operation"
2634 [(set (match_operand:SI 1 "s_register_operand" "=r")
2635 (match_operand:SI 2 "indirect_operand" "Q"))])]
2640 int count = XVECLEN (operands[0], 0);
2642 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2643 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2644 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2646 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2650 [(set_attr "type" "load")])
2652 (define_expand "store_multiple"
2653 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2654 (match_operand:SI 1 "" ""))
2655 (use (match_operand:SI 2 "" ""))])]
2658 /* Support only fixed point registers */
2659 if (GET_CODE (operands[2]) != CONST_INT
2660 || INTVAL (operands[2]) > 14
2661 || INTVAL (operands[2]) < 2
2662 || GET_CODE (operands[1]) != REG
2663 || GET_CODE (operands[0]) != MEM
2664 || REGNO (operands[1]) > 14
2665 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2669 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2670 force_reg (SImode, XEXP (operands[0], 0)),
2674 ;; Store multiple with write-back
2677 [(match_parallel 0 "store_multiple_operation"
2678 [(set (match_operand:SI 1 "s_register_operand" "+r")
2679 (plus:SI (match_dup 1)
2680 (match_operand:SI 2 "immediate_operand" "n")))
2681 (set (mem:SI (match_dup 1))
2682 (match_operand:SI 3 "s_register_operand" "r"))])]
2683 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2687 int count = XVECLEN (operands[0], 0);
2689 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2690 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2691 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2693 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2698 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2699 (const_string "store2")
2700 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2701 (const_string "store3")]
2702 (const_string "store4")))])
2704 ;; Ordinary store multiple
2707 [(match_parallel 0 "store_multiple_operation"
2708 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2709 (match_operand:SI 1 "s_register_operand" "r"))])]
2714 int count = XVECLEN (operands[0], 0);
2716 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2717 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2718 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2720 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2725 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2726 (const_string "store2")
2727 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2728 (const_string "store3")]
2729 (const_string "store4")))])
2731 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2732 ;; We could let this apply for blocks of less than this, but it clobbers so
2733 ;; many registers that there is then probably a better way.
2735 (define_expand "movstrqi"
2736 [(match_operand:BLK 0 "general_operand" "")
2737 (match_operand:BLK 1 "general_operand" "")
2738 (match_operand:SI 2 "const_int_operand" "")
2739 (match_operand:SI 3 "const_int_operand" "")]
2742 if (arm_gen_movstrqi (operands))
2748 ;; Comparison and test insns
2750 (define_expand "cmpsi"
2752 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2753 (match_operand:SI 1 "arm_add_operand" "")))]
2757 arm_compare_op0 = operands[0];
2758 arm_compare_op1 = operands[1];
2764 (define_expand "cmpsf"
2766 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2767 (match_operand:SF 1 "fpu_rhs_operand" "")))]
2771 arm_compare_op0 = operands[0];
2772 arm_compare_op1 = operands[1];
2778 (define_expand "cmpdf"
2780 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2781 (match_operand:DF 1 "fpu_rhs_operand" "")))]
2785 arm_compare_op0 = operands[0];
2786 arm_compare_op1 = operands[1];
2792 (define_expand "cmpxf"
2794 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2795 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2796 "ENABLE_XF_PATTERNS"
2799 arm_compare_op0 = operands[0];
2800 arm_compare_op1 = operands[1];
2807 [(set (match_operand 0 "cc_register" "")
2808 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2809 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
2814 [(set_attr "conds" "set")])
2817 [(set (match_operand 0 "cc_register" "")
2818 (compare (match_operand:SI 1 "s_register_operand" "r")
2819 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2822 [(set_attr "conds" "set")])
2825 [(set (match_operand 0 "cc_register" "")
2826 (compare (match_operand:SI 1 "s_register_operand" "r")
2827 (match_operator:SI 2 "shift_operator"
2828 [(match_operand:SI 3 "s_register_operand" "r")
2829 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
2832 [(set_attr "conds" "set")])
2835 [(set (match_operand 0 "cc_register" "")
2836 (compare (match_operand:SI 1 "s_register_operand" "r")
2837 (neg:SI (match_operator:SI 2 "shift_operator"
2838 [(match_operand:SI 3 "s_register_operand" "r")
2839 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
2842 [(set_attr "conds" "set")])
2846 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2847 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2852 [(set_attr "conds" "set")
2853 (set_attr "type" "f_2_r")])
2857 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2858 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2863 [(set_attr "conds" "set")
2864 (set_attr "type" "f_2_r")])
2868 (compare:CCFP (float_extend:DF
2869 (match_operand:SF 0 "s_register_operand" "f,f"))
2870 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2875 [(set_attr "conds" "set")
2876 (set_attr "type" "f_2_r")])
2880 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2882 (match_operand:SF 1 "s_register_operand" "f"))))]
2885 [(set_attr "conds" "set")
2886 (set_attr "type" "f_2_r")])
2890 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2891 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2892 "ENABLE_XF_PATTERNS"
2896 [(set_attr "conds" "set")
2897 (set_attr "type" "f_2_r")])
2900 [(set (reg:CCFPE 24)
2901 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2902 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2907 [(set_attr "conds" "set")
2908 (set_attr "type" "f_2_r")])
2911 [(set (reg:CCFPE 24)
2912 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2913 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2918 [(set_attr "conds" "set")
2919 (set_attr "type" "f_2_r")])
2922 [(set (reg:CCFPE 24)
2923 (compare:CCFPE (float_extend:DF
2924 (match_operand:SF 0 "s_register_operand" "f,f"))
2925 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2930 [(set_attr "conds" "set")
2931 (set_attr "type" "f_2_r")])
2934 [(set (reg:CCFPE 24)
2935 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2937 (match_operand:SF 1 "s_register_operand" "f"))))]
2940 [(set_attr "conds" "set")
2941 (set_attr "type" "f_2_r")])
2944 [(set (reg:CCFPE 24)
2945 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2946 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2947 "ENABLE_XF_PATTERNS"
2951 [(set_attr "conds" "set")
2952 (set_attr "type" "f_2_r")])
2954 ; This insn allows redundant compares to be removed by cse, nothing should
2955 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2956 ; is deleted later on. The match_dup will match the mode here, so that
2957 ; mode changes of the condition codes aren't lost by this even though we don't
2958 ; specify what they are.
2961 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2963 "\\t%@ deleted compare"
2964 [(set_attr "conds" "set")
2965 (set_attr "length" "0")])
2968 ;; Conditional branch insns
2970 (define_expand "beq"
2972 (if_then_else (eq (match_dup 1) (const_int 0))
2973 (label_ref (match_operand 0 "" ""))
2978 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2983 (define_expand "bne"
2985 (if_then_else (ne (match_dup 1) (const_int 0))
2986 (label_ref (match_operand 0 "" ""))
2991 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
2996 (define_expand "bgt"
2998 (if_then_else (gt (match_dup 1) (const_int 0))
2999 (label_ref (match_operand 0 "" ""))
3004 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3009 (define_expand "ble"
3011 (if_then_else (le (match_dup 1) (const_int 0))
3012 (label_ref (match_operand 0 "" ""))
3017 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3022 (define_expand "bge"
3024 (if_then_else (ge (match_dup 1) (const_int 0))
3025 (label_ref (match_operand 0 "" ""))
3030 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3035 (define_expand "blt"
3037 (if_then_else (lt (match_dup 1) (const_int 0))
3038 (label_ref (match_operand 0 "" ""))
3043 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3048 (define_expand "bgtu"
3050 (if_then_else (gtu (match_dup 1) (const_int 0))
3051 (label_ref (match_operand 0 "" ""))
3056 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3061 (define_expand "bleu"
3063 (if_then_else (leu (match_dup 1) (const_int 0))
3064 (label_ref (match_operand 0 "" ""))
3069 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3074 (define_expand "bgeu"
3076 (if_then_else (geu (match_dup 1) (const_int 0))
3077 (label_ref (match_operand 0 "" ""))
3082 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3087 (define_expand "bltu"
3089 (if_then_else (ltu (match_dup 1) (const_int 0))
3090 (label_ref (match_operand 0 "" ""))
3095 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3100 ;; patterns to match conditional branch insns
3104 (if_then_else (match_operator 1 "comparison_operator"
3105 [(reg 24) (const_int 0)])
3106 (label_ref (match_operand 0 "" ""))
3111 extern int arm_ccfsm_state;
3113 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3115 arm_ccfsm_state += 2;
3118 return \"b%d1\\t%l0\";
3120 [(set_attr "conds" "use")])
3124 (if_then_else (match_operator 1 "comparison_operator"
3125 [(reg 24) (const_int 0)])
3127 (label_ref (match_operand 0 "" ""))))]
3128 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3131 extern int arm_ccfsm_state;
3133 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3135 arm_ccfsm_state += 2;
3138 return \"b%D1\\t%l0\";
3140 [(set_attr "conds" "use")])
3145 (define_expand "seq"
3146 [(set (match_operand:SI 0 "s_register_operand" "=r")
3147 (eq:SI (match_dup 1) (const_int 0)))]
3151 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3156 (define_expand "sne"
3157 [(set (match_operand:SI 0 "s_register_operand" "=r")
3158 (ne:SI (match_dup 1) (const_int 0)))]
3162 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3167 (define_expand "sgt"
3168 [(set (match_operand:SI 0 "s_register_operand" "=r")
3169 (gt:SI (match_dup 1) (const_int 0)))]
3173 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3178 (define_expand "sle"
3179 [(set (match_operand:SI 0 "s_register_operand" "=r")
3180 (le:SI (match_dup 1) (const_int 0)))]
3184 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3189 (define_expand "sge"
3190 [(set (match_operand:SI 0 "s_register_operand" "=r")
3191 (ge:SI (match_dup 1) (const_int 0)))]
3195 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3200 (define_expand "slt"
3201 [(set (match_operand:SI 0 "s_register_operand" "=r")
3202 (lt:SI (match_dup 1) (const_int 0)))]
3206 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3211 (define_expand "sgtu"
3212 [(set (match_operand:SI 0 "s_register_operand" "=r")
3213 (gtu:SI (match_dup 1) (const_int 0)))]
3217 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3222 (define_expand "sleu"
3223 [(set (match_operand:SI 0 "s_register_operand" "=r")
3224 (leu:SI (match_dup 1) (const_int 0)))]
3228 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3233 (define_expand "sgeu"
3234 [(set (match_operand:SI 0 "s_register_operand" "=r")
3235 (geu:SI (match_dup 1) (const_int 0)))]
3239 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3244 (define_expand "sltu"
3245 [(set (match_operand:SI 0 "s_register_operand" "=r")
3246 (ltu:SI (match_dup 1) (const_int 0)))]
3250 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3256 [(set (match_operand:SI 0 "s_register_operand" "=r")
3257 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3259 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3260 [(set_attr "conds" "use")
3261 (set_attr "length" "8")])
3264 [(set (match_operand:SI 0 "s_register_operand" "=r")
3265 (neg:SI (match_operator:SI 1 "comparison_operator"
3266 [(reg 24) (const_int 0)])))]
3268 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3269 [(set_attr "conds" "use")
3270 (set_attr "length" "8")])
3273 [(set (match_operand:SI 0 "s_register_operand" "=r")
3274 (not:SI (match_operator:SI 1 "comparison_operator"
3275 [(reg 24) (const_int 0)])))]
3277 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3278 [(set_attr "conds" "use")
3279 (set_attr "length" "8")])
3282 ;; Jump and linkage insns
3286 (label_ref (match_operand 0 "" "")))]
3290 extern int arm_ccfsm_state;
3292 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3294 arm_ccfsm_state += 2;
3297 return \"b%?\\t%l0\";
3300 (define_expand "call"
3301 [(parallel [(call (match_operand 0 "memory_operand" "")
3302 (match_operand 1 "general_operand" ""))
3303 (clobber (reg:SI 14))])]
3308 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3309 (match_operand 1 "" "g"))
3310 (clobber (reg:SI 14))]
3313 return output_call (operands);
3315 [(set (attr "conds")
3316 (if_then_else (eq_attr "cpu" "arm6")
3317 (const_string "clob")
3318 (const_string "nocond")))
3319 ;; length is worst case, normally it is only two
3320 (set_attr "length" "12")
3321 (set_attr "type" "call")])
3324 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3325 (match_operand 1 "general_operand" "g"))
3326 (clobber (reg:SI 14))]
3329 return output_call_mem (operands);
3331 [(set (attr "conds")
3332 (if_then_else (eq_attr "cpu" "arm6")
3333 (const_string "clob")
3334 (const_string "nocond")))
3335 (set_attr "length" "12")
3336 (set_attr "type" "call")])
3338 (define_expand "call_value"
3339 [(parallel [(set (match_operand 0 "" "=rf")
3340 (call (match_operand 1 "memory_operand" "m")
3341 (match_operand 2 "general_operand" "g")))
3342 (clobber (reg:SI 14))])]
3347 [(set (match_operand 0 "" "=rf")
3348 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3349 (match_operand 2 "general_operand" "g")))
3350 (clobber (reg:SI 14))]
3353 return output_call (&operands[1]);
3355 [(set (attr "conds")
3356 (if_then_else (eq_attr "cpu" "arm6")
3357 (const_string "clob")
3358 (const_string "nocond")))
3359 (set_attr "length" "12")
3360 (set_attr "type" "call")])
3363 [(set (match_operand 0 "" "=rf")
3364 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3365 (match_operand 2 "general_operand" "g")))
3366 (clobber (reg:SI 14))]
3367 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3369 return output_call_mem (&operands[1]);
3371 [(set (attr "conds")
3372 (if_then_else (eq_attr "cpu" "arm6")
3373 (const_string "clob")
3374 (const_string "nocond")))
3375 (set_attr "length" "12")
3376 (set_attr "type" "call")])
3378 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3379 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3382 [(call (mem:SI (match_operand:SI 0 "" "i"))
3383 (match_operand:SI 1 "general_operand" "g"))
3384 (clobber (reg:SI 14))]
3385 "GET_CODE (operands[0]) == SYMBOL_REF"
3387 [(set (attr "conds")
3388 (if_then_else (eq_attr "cpu" "arm6")
3389 (const_string "clob")
3390 (const_string "nocond")))
3391 (set_attr "type" "call")])
3394 [(set (match_operand 0 "s_register_operand" "=rf")
3395 (call (mem:SI (match_operand:SI 1 "" "i"))
3396 (match_operand:SI 2 "general_operand" "g")))
3397 (clobber (reg:SI 14))]
3398 "GET_CODE(operands[1]) == SYMBOL_REF"
3400 [(set (attr "conds")
3401 (if_then_else (eq_attr "cpu" "arm6")
3402 (const_string "clob")
3403 (const_string "nocond")))
3404 (set_attr "type" "call")])
3406 ;; Often the return insn will be the same as loading from memory, so set attr
3407 (define_insn "return"
3412 extern int arm_ccfsm_state;
3414 if (arm_ccfsm_state == 2)
3416 arm_ccfsm_state += 2;
3419 return output_return_instruction (NULL, TRUE);
3421 [(set_attr "type" "load")])
3425 (if_then_else (match_operator 0 "comparison_operator"
3426 [(reg 24) (const_int 0)])
3432 extern int arm_ccfsm_state;
3434 if (arm_ccfsm_state == 2)
3436 arm_ccfsm_state += 2;
3439 return output_return_instruction (operands[0], TRUE);
3441 [(set_attr "conds" "use")
3442 (set_attr "type" "load")])
3446 (if_then_else (match_operator 0 "comparison_operator"
3447 [(reg 24) (const_int 0)])
3453 extern int arm_ccfsm_state;
3455 if (arm_ccfsm_state == 2)
3457 arm_ccfsm_state += 2;
3460 return output_return_instruction
3461 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3462 GET_MODE (operands[0]), XEXP (operands[0], 0),
3463 XEXP (operands[0], 1)),
3466 [(set_attr "conds" "use")
3467 (set_attr "type" "load")])
3469 ;; Call subroutine returning any type.
3471 (define_expand "untyped_call"
3472 [(parallel [(call (match_operand 0 "" "")
3474 (match_operand 1 "" "")
3475 (match_operand 2 "" "")])]
3481 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3483 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3485 rtx set = XVECEXP (operands[2], 0, i);
3486 emit_move_insn (SET_DEST (set), SET_SRC (set));
3489 /* The optimizer does not know that the call sets the function value
3490 registers we stored in the result block. We avoid problems by
3491 claiming that all hard registers are used and clobbered at this
3493 emit_insn (gen_blockage ());
3498 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3499 ;; all of memory. This blocks insns from being moved across this point.
3501 (define_insn "blockage"
3502 [(unspec_volatile [(const_int 0)] 0)]
3505 [(set_attr "length" "0")
3506 (set_attr "type" "block")])
3508 (define_insn "tablejump"
3510 (match_operand:SI 0 "s_register_operand" "r"))
3511 (use (label_ref (match_operand 1 "" "")))]
3513 "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
3517 (match_operand:SI 0 "memory_operand" "m"))
3518 (use (label_ref (match_operand 1 "" "")))]
3520 "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
3521 [(set_attr "type" "load")])
3523 (define_insn "indirect_jump"
3525 (match_operand:SI 0 "s_register_operand" "r"))]
3527 "mov%?\\t%|pc, %0\\t%@ indirect jump")
3531 (match_operand:SI 0 "memory_operand" "m"))]
3533 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3534 [(set_attr "type" "load")])
3541 "mov%?\\tr0, r0\\t%@ nop")
3543 ;; Patterns to allow combination of arithmetic, cond code and shifts
3546 [(set (match_operand:SI 0 "s_register_operand" "=r")
3547 (match_operator:SI 1 "shiftable_operator"
3548 [(match_operator:SI 3 "shift_operator"
3549 [(match_operand:SI 4 "s_register_operand" "r")
3550 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3551 (match_operand:SI 2 "s_register_operand" "r")]))]
3553 "%i1%?\\t%0, %2, %4%S3")
3556 [(set (reg:CC_NOOV 24)
3557 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3558 [(match_operator:SI 3 "shift_operator"
3559 [(match_operand:SI 4 "s_register_operand" "r")
3560 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3561 (match_operand:SI 2 "s_register_operand" "r")])
3563 (set (match_operand:SI 0 "s_register_operand" "=r")
3564 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3567 "%i1%?s\\t%0, %2, %4%S3"
3568 [(set_attr "conds" "set")])
3571 [(set (reg:CC_NOOV 24)
3572 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3573 [(match_operator:SI 3 "shift_operator"
3574 [(match_operand:SI 4 "s_register_operand" "r")
3575 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3576 (match_operand:SI 2 "s_register_operand" "r")])
3578 (clobber (match_scratch:SI 0 "=r"))]
3580 "%i1%?s\\t%0, %2, %4%S3"
3581 [(set_attr "conds" "set")])
3584 [(set (match_operand:SI 0 "s_register_operand" "=r")
3585 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3586 (match_operator:SI 2 "shift_operator"
3587 [(match_operand:SI 3 "s_register_operand" "r")
3588 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
3590 "sub%?\\t%0, %1, %3%S2")
3593 [(set (reg:CC_NOOV 24)
3595 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3596 (match_operator:SI 2 "shift_operator"
3597 [(match_operand:SI 3 "s_register_operand" "r")
3598 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3600 (set (match_operand:SI 0 "s_register_operand" "=r")
3601 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3604 "sub%?s\\t%0, %1, %3%S2"
3605 [(set_attr "conds" "set")])
3608 [(set (reg:CC_NOOV 24)
3610 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3611 (match_operator:SI 2 "shift_operator"
3612 [(match_operand:SI 3 "s_register_operand" "r")
3613 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3615 (clobber (match_scratch:SI 0 "=r"))]
3617 "sub%?s\\t%0, %1, %3%S2"
3618 [(set_attr "conds" "set")])
3620 ;; These variants of the above insns can occur if the first operand is the
3621 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3622 ;; seem to be a way around it. Most of the predicates have to be null
3623 ;; because the format can be generated part way through reload, so
3624 ;; if we don't match it as soon as it becomes available, reload doesn't know
3625 ;; how to reload pseudos that haven't got hard registers; the constraints will
3626 ;; sort everything out.
3629 [(set (match_operand:SI 0 "" "=&r")
3630 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3631 [(match_operand:SI 3 "" "r")
3632 (match_operand:SI 4 "" "rM")])
3633 (match_operand:SI 2 "" "r"))
3634 (match_operand:SI 1 "const_int_operand" "n")))]
3635 "reload_in_progress"
3637 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
3638 operands[2] = operands[1];
3639 operands[1] = operands[0];
3640 return output_add_immediate (operands);
3642 ; we have no idea how long the add_immediate is, it could be up to 4.
3643 [(set_attr "length" "20")])
3646 [(set (reg:CC_NOOV 24)
3647 (compare:CC_NOOV (plus:SI
3649 (match_operator:SI 5 "shift_operator"
3650 [(match_operand:SI 3 "" "r")
3651 (match_operand:SI 4 "" "rM")])
3652 (match_operand:SI 1 "" "r"))
3653 (match_operand:SI 2 "const_int_operand" "n"))
3655 (set (match_operand:SI 0 "" "=&r")
3656 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3659 "reload_in_progress"
3661 output_add_immediate (operands);
3662 return \"add%?s\\t%0, %0, %3%S5\";
3664 [(set_attr "conds" "set")
3665 (set_attr "length" "20")])
3668 [(set (reg:CC_NOOV 24)
3669 (compare:CC_NOOV (plus:SI
3671 (match_operator:SI 5 "shift_operator"
3672 [(match_operand:SI 3 "" "r")
3673 (match_operand:SI 4 "" "rM")])
3674 (match_operand:SI 1 "" "r"))
3675 (match_operand:SI 2 "const_int_operand" "n"))
3677 (clobber (match_scratch:SI 0 "=&r"))]
3678 "reload_in_progress"
3680 output_add_immediate (operands);
3681 return \"add%?s\\t%0, %0, %3%S5\";
3683 [(set_attr "conds" "set")
3684 (set_attr "length" "20")])
3686 ;; These are similar, but are needed when the mla pattern contains the
3687 ;; eliminated register as operand 3.
3690 [(set (match_operand:SI 0 "" "=&r,&r")
3691 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3692 (match_operand:SI 2 "" "r,r"))
3693 (match_operand:SI 3 "" "r,r"))
3694 (match_operand:SI 4 "const_int_operand" "n,n")))]
3695 "reload_in_progress"
3697 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3698 operands[2] = operands[4];
3699 operands[1] = operands[0];
3700 return output_add_immediate (operands);
3702 [(set_attr "length" "20")])
3705 [(set (reg:CC_NOOV 24)
3706 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3707 (match_operand:SI 3 "" "r")
3708 (match_operand:SI 4 "" "r"))
3709 (match_operand:SI 1 "" "r"))
3710 (match_operand:SI 2 "const_int_operand" "n"))
3712 (set (match_operand:SI 0 "" "=&r")
3713 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3715 "reload_in_progress"
3717 output_add_immediate (operands);
3718 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3721 [(set_attr "length" "20")
3722 (set_attr "conds" "set")])
3725 [(set (reg:CC_NOOV 24)
3726 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3727 (match_operand:SI 3 "" "r")
3728 (match_operand:SI 4 "" "r"))
3729 (match_operand:SI 1 "" "r"))
3730 (match_operand:SI 2 "const_int_operand" "n"))
3732 (clobber (match_scratch:SI 0 "=&r"))]
3733 "reload_in_progress"
3735 output_add_immediate (operands);
3736 return \"mla%?s\\t%0, %3, %4, %0\";
3738 [(set_attr "length" "20")
3739 (set_attr "conds" "set")])
3745 [(set (match_operand:SI 0 "s_register_operand" "=r")
3746 (and:SI (match_operator 1 "comparison_operator"
3747 [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
3748 (match_operand:SI 2 "s_register_operand" "r")))]
3750 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3751 [(set_attr "conds" "use")
3752 (set_attr "length" "8")])
3755 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3756 (ior:SI (match_operator 2 "comparison_operator"
3757 [(reg 24) (const_int 0)])
3758 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3762 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3763 [(set_attr "conds" "use")
3764 (set_attr "length" "4,8")])
3767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3768 (match_operator 1 "comparison_operator"
3769 [(match_operand:SI 2 "s_register_operand" "r,r")
3770 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
3774 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3775 return \"mov\\t%0, %2, lsr #31\";
3777 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3778 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3780 if (GET_CODE (operands[1]) == NE)
3782 if (which_alternative == 1)
3783 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3784 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3786 if (which_alternative == 1)
3787 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3789 output_asm_insn (\"cmp\\t%2, %3\", operands);
3790 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3792 [(set_attr "conds" "clob")
3793 (set_attr "length" "12")])
3796 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3797 (ior:SI (match_operator 1 "comparison_operator"
3798 [(match_operand:SI 2 "s_register_operand" "r")
3799 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3800 (match_operator 4 "comparison_operator"
3801 [(match_operand:SI 5 "s_register_operand" "r")
3802 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3807 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3808 GET_CODE (operands[1]));
3810 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3812 output_asm_insn (\"mov\\t%0, #0\", operands);
3813 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3814 || comparison_dominates_p (GET_CODE (operands[1]),
3815 GET_CODE (operands[4]))
3817 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3820 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3821 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3824 [(set_attr "conds" "clob")
3826 (set_attr "length" "20")])
3831 (match_operator 5 "equality_operator"
3832 [(ior:SI (match_operator 6 "comparison_operator"
3833 [(match_operand:SI 0 "s_register_operand" "")
3834 (match_operand:SI 1 "arm_add_operand" "")])
3835 (match_operator 7 "comparison_operator"
3836 [(match_operand:SI 2 "s_register_operand" "")
3837 (match_operand:SI 3 "arm_add_operand" "")]))
3839 (label_ref (match_operand 4 "" ""))
3842 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3843 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3844 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3846 (compare:CC (ior:CC (match_op_dup 6
3847 [(match_dup 0) (match_dup 1)])
3849 [(match_dup 2) (match_dup 3)]))
3852 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3853 (label_ref (match_dup 4))
3857 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3858 GET_CODE (operands[7]))
3859 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3861 if (GET_CODE (operands[5]) == NE)
3862 operands[5] = gen_rtx (code, CCmode,
3863 XEXP (operands[5], 0), XEXP (operands[5], 1));
3865 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3866 XEXP (operands[5], 0), XEXP (operands[5], 1));
3870 ;; Don't match these patterns if we can use a conditional compare, since they
3871 ;; tell the final prescan branch elimator code that full branch inlining
3877 (ne (ior:SI (match_operator 5 "comparison_operator"
3878 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3879 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3880 (match_operator 6 "comparison_operator"
3881 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3882 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
3884 (label_ref (match_operand 4 "" ""))
3887 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3888 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3889 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3892 extern int arm_ccfsm_state;
3894 if (which_alternative & 1)
3895 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
3897 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
3899 if (which_alternative >= 2)
3900 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3902 output_asm_insn (\"cmp\\t%2, %3\", operands);
3904 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3906 arm_ccfsm_state += 2;
3909 return \"b%d6\\t%l4\";
3911 [(set_attr "conds" "jump_clob")
3912 (set_attr "length" "16")])
3917 (ior:CC (match_operator 4 "comparison_operator"
3918 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3919 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3920 (match_operator 5 "comparison_operator"
3921 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3922 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
3924 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3925 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3926 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3928 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3930 if (which_alternative >= 2)
3931 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3933 output_asm_insn (\"cmp\\t%2, %3\", operands);
3935 if (which_alternative & 1)
3936 return \"cmn%D5\\t%0, #%n1\";
3937 return \"cmp%D5\\t%0, %1\";
3940 if (which_alternative & 1)
3941 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3943 output_asm_insn (\"cmp\\t%0, %1\", operands);
3945 if (which_alternative >= 2)
3946 return \"cmn%D4\\t%2, #%n3\";
3947 return \"cmp%D4\\t%2, %3\";
3949 [(set_attr "conds" "set")
3950 (set_attr "length" "8")])
3953 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3954 (if_then_else (match_operator 3 "equality_operator"
3955 [(match_operator 4 "comparison_operator"
3956 [(reg 24) (const_int 0)])
3958 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3959 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3962 if (GET_CODE (operands[3]) == NE)
3964 if (which_alternative != 1)
3965 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3966 if (which_alternative != 0)
3967 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3970 if (which_alternative != 0)
3971 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3972 if (which_alternative != 1)
3973 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
3976 [(set_attr "conds" "use")
3977 (set_attr "length" "4,4,8")])
3980 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3981 (match_operator:SI 5 "shiftable_operator"
3982 [(match_operator:SI 4 "comparison_operator"
3983 [(match_operand:SI 2 "s_register_operand" "r,r")
3984 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3985 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3989 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
3990 return \"%i5\\t%0, %1, %2, lsr #31\";
3992 output_asm_insn (\"cmp\\t%2, %3\", operands);
3993 if (GET_CODE (operands[5]) == AND)
3994 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
3995 else if (which_alternative != 0)
3996 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3997 return \"%i5%d4\\t%0, %1, #1\";
3999 [(set_attr "conds" "clob")
4000 (set_attr "length" "12")])
4003 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4004 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4005 (match_operator:SI 4 "comparison_operator"
4006 [(match_operand:SI 2 "s_register_operand" "r,r")
4007 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4011 output_asm_insn (\"cmp\\t%2, %3\", operands);
4012 if (which_alternative != 0)
4013 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4014 return \"sub%d4\\t%0, %1, #1\";
4016 [(set_attr "conds" "clob")
4017 (set_attr "length" "8,12")])
4020 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4021 (and:SI (match_operator 1 "comparison_operator"
4022 [(match_operand:SI 2 "s_register_operand" "r")
4023 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4024 (match_operator 4 "comparison_operator"
4025 [(match_operand:SI 5 "s_register_operand" "r")
4026 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4032 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4033 reverse_condition (GET_CODE (operands[4])))
4035 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4036 reverse_condition (GET_CODE (operands[1])))
4038 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4040 output_asm_insn (\"mov\\t%0, #1\", operands);
4041 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4043 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
4044 : \"cmp%d1\\t%5, %6\", operands);
4048 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4049 output_asm_insn (\"cmp\\t%5, %6\", operands);
4051 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
4054 [(set_attr "conds" "clob")
4055 (set_attr "length" "20")])
4059 (if_then_else (match_operator 1 "equality_operator"
4060 [(and:SI (match_operator 2 "comparison_operator"
4061 [(match_operand:SI 3 "s_register_operand" "")
4062 (match_operand:SI 4 "arm_add_operand" "")])
4063 (match_operator 0 "comparison_operator"
4064 [(match_operand:SI 5 "s_register_operand" "")
4065 (match_operand:SI 6 "arm_add_operand" "")]))
4067 (label_ref (match_operand 7 "" ""))
4070 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4071 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4072 reverse_condition (GET_CODE (operands[0])))
4073 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4074 reverse_condition (GET_CODE (operands[2]))))"
4076 (compare:CC (ior:CC (match_op_dup 2
4077 [(match_dup 3) (match_dup 4)])
4079 [(match_dup 5) (match_dup 6)]))
4082 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4083 (label_ref (match_dup 7))
4087 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4088 This is safe since we only do it for integer comparisons. */
4089 enum rtx_code code =
4090 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4091 reverse_condition (GET_CODE (operands[0])))
4092 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4094 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4095 GET_MODE (operands[2]), operands[3], operands[4]);
4096 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4097 GET_MODE (operands[0]), operands[5], operands[6]);
4098 if (GET_CODE (operands[1]) == NE)
4099 operands[1] = gen_rtx (code, CCmode,
4100 XEXP (operands[1], 0), XEXP (operands[1], 1));
4102 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4103 XEXP (operands[1], 0), XEXP (operands[1], 1));
4107 ;; Don't match these patterns if we can use a conditional compare, since they
4108 ;; tell the final prescan branch elimator code that full branch inlining
4114 (eq (and:SI (match_operator 1 "comparison_operator"
4115 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4116 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4117 (match_operator 4 "comparison_operator"
4118 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4119 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4121 (label_ref (match_operand 0 "" ""))
4124 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4125 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4126 reverse_condition (GET_CODE (operands[4])))
4127 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4128 reverse_condition (GET_CODE (operands[1]))))"
4131 extern int arm_ccfsm_state;
4133 if (which_alternative & 1)
4134 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
4136 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4138 if (which_alternative >= 2)
4139 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4141 output_asm_insn (\"cmp\\t%5, %6\", operands);
4143 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4145 arm_ccfsm_state += 2;
4148 return \"b%D4\\t%l0\";
4150 [(set_attr "conds" "jump_clob")
4151 (set_attr "length" "16")])
4154 [(set (match_operand:SI 0 "s_register_operand" "=r")
4155 (neg:SI (match_operator 3 "comparison_operator"
4156 [(match_operand:SI 1 "s_register_operand" "r")
4157 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4161 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4162 return \"mov\\t%0, %1, asr #31\";
4164 if (GET_CODE (operands[3]) == NE)
4165 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4167 if (GET_CODE (operands[3]) == GT)
4168 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4170 output_asm_insn (\"cmp\\t%1, %2\", operands);
4171 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4172 return \"mvn%d3\\t%0, #0\";
4174 [(set_attr "conds" "clob")
4175 (set_attr "length" "12")])
4177 (define_insn "movcond"
4178 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4180 (match_operator 5 "comparison_operator"
4181 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4182 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4183 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4184 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4188 if (GET_CODE (operands[5]) == LT
4189 && (operands[4] == const0_rtx))
4191 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4193 if (operands[2] == const0_rtx)
4194 return \"and\\t%0, %1, %3, asr #31\";
4195 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4197 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4199 if (operands[1] == const0_rtx)
4200 return \"bic\\t%0, %2, %3, asr #31\";
4201 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4203 /* The only case that falls through to here is when both ops 1 & 2
4207 if (GET_CODE (operands[5]) == GE
4208 && (operands[4] == const0_rtx))
4210 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4212 if (operands[2] == const0_rtx)
4213 return \"bic\\t%0, %1, %3, asr #31\";
4214 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4216 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4218 if (operands[1] == const0_rtx)
4219 return \"and\\t%0, %2, %3, asr #31\";
4220 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4222 /* The only case that falls through to here is when both ops 1 & 2
4225 if (GET_CODE (operands[4]) == CONST_INT
4226 && !const_ok_for_arm (INTVAL (operands[4])))
4227 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4229 output_asm_insn (\"cmp\\t%3, %4\", operands);
4230 if (which_alternative != 0)
4231 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4232 if (which_alternative != 1)
4233 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4236 [(set_attr "conds" "clob")
4237 (set_attr "length" "8,8,12")])
4240 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4241 (if_then_else:SI (match_operator 9 "comparison_operator"
4242 [(match_operand:SI 5 "s_register_operand" "r,r")
4243 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4244 (match_operator:SI 8 "shiftable_operator"
4245 [(match_operand:SI 1 "s_register_operand" "r,r")
4246 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4247 (match_operator:SI 7 "shiftable_operator"
4248 [(match_operand:SI 3 "s_register_operand" "r,r")
4249 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4253 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4254 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4255 [(set_attr "conds" "clob")
4256 (set_attr "length" "12")])
4259 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4260 (if_then_else:SI (match_operator 6 "comparison_operator"
4261 [(match_operand:SI 2 "s_register_operand" "r,r")
4262 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4263 (match_operator:SI 7 "shiftable_operator"
4264 [(match_operand:SI 4 "s_register_operand" "r,r")
4265 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4266 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4270 /* If we have an operation where (op x 0) is the identity operation and
4271 the condtional operator is LT or GE and we are comparing against zero and
4272 everything is in registers then we can do this in two instructions */
4273 if (operands[3] == const0_rtx
4274 && GET_CODE (operands[7]) != AND
4275 && GET_CODE (operands[5]) == REG
4276 && GET_CODE (operands[1]) == REG
4277 && REGNO (operands[1]) == REGNO (operands[4])
4278 && REGNO (operands[4]) != REGNO (operands[0]))
4280 if (GET_CODE (operands[6]) == LT)
4281 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4282 else if (GET_CODE (operands[6]) == GE)
4283 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4285 if (GET_CODE (operands[3]) == CONST_INT
4286 && !const_ok_for_arm (INTVAL (operands[3])))
4287 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4289 output_asm_insn (\"cmp\\t%2, %3\", operands);
4290 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4291 if (which_alternative != 0)
4293 if (GET_CODE (operands[1]) == MEM)
4294 return \"ldr%D6\\t%0, %1\";
4296 return \"mov%D6\\t%0, %1\";
4300 [(set_attr "conds" "clob")
4301 (set_attr "length" "8,12")])
4304 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4305 (if_then_else:SI (match_operator 6 "comparison_operator"
4306 [(match_operand:SI 4 "s_register_operand" "r,r")
4307 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4308 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4309 (match_operator:SI 7 "shiftable_operator"
4310 [(match_operand:SI 2 "s_register_operand" "r,r")
4311 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4315 /* If we have an operation where (op x 0) is the identity operation and
4316 the condtional operator is LT or GE and we are comparing against zero and
4317 everything is in registers then we can do this in two instructions */
4318 if (operands[5] == const0_rtx
4319 && GET_CODE (operands[7]) != AND
4320 && GET_CODE (operands[3]) == REG
4321 && GET_CODE (operands[1]) == REG
4322 && REGNO (operands[1]) == REGNO (operands[2])
4323 && REGNO (operands[2]) != REGNO (operands[0]))
4325 if (GET_CODE (operands[6]) == GE)
4326 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4327 else if (GET_CODE (operands[6]) == LT)
4328 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4331 if (GET_CODE (operands[5]) == CONST_INT
4332 && !const_ok_for_arm (INTVAL (operands[5])))
4333 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4335 output_asm_insn (\"cmp\\t%4, %5\", operands);
4337 if (which_alternative != 0)
4339 if (GET_CODE (operands[1]) == MEM)
4340 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4342 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4344 return \"%I7%D6\\t%0, %2, %3\";
4346 [(set_attr "conds" "clob")
4347 (set_attr "length" "8,12")])
4350 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4351 (if_then_else:SI (match_operator 6 "comparison_operator"
4352 [(match_operand:SI 4 "s_register_operand" "r,r")
4353 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4355 (match_operand:SI 2 "s_register_operand" "r,r")
4356 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4357 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4362 if (GET_CODE (operands[5]) == CONST_INT
4363 && !const_ok_for_arm (INTVAL (operands[5])))
4364 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4366 output_asm_insn (\"cmp\\t%4, %5\", operands);
4367 if (GET_CODE (operands[3]) == CONST_INT
4368 && !const_ok_for_arm (INTVAL (operands[3])))
4369 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4371 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4372 if (which_alternative != 0)
4374 if (GET_CODE (operands[1]) == MEM)
4375 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4377 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4382 [(set_attr "conds" "clob")
4383 (set_attr "length" "8,12")])
4386 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4387 (if_then_else:SI (match_operator 6 "comparison_operator"
4388 [(match_operand:SI 4 "s_register_operand" "r,r")
4389 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4390 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4392 (match_operand:SI 2 "s_register_operand" "r,r")
4393 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4398 if (GET_CODE (operands[5]) == CONST_INT
4399 && !const_ok_for_arm (INTVAL (operands[5])))
4400 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4402 output_asm_insn (\"cmp\\t%4, %5\", operands);
4403 if (GET_CODE (operands[3]) == CONST_INT
4404 && !const_ok_for_arm (INTVAL (operands[3])))
4405 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4407 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4408 if (which_alternative != 0)
4410 if (GET_CODE (operands[6]) == MEM)
4411 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4413 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4418 [(set_attr "conds" "clob")
4419 (set_attr "length" "8,12")])
4422 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4423 (if_then_else:SI (match_operator 5 "comparison_operator"
4424 [(match_operand:SI 3 "s_register_operand" "r,r")
4425 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4426 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4428 (match_operand:SI 2 "s_register_operand" "r,r"))))
4432 [(set_attr "conds" "clob")
4433 (set_attr "length" "8,12")])
4436 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4438 (match_operator 5 "comparison_operator"
4439 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4440 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4442 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4443 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4447 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4448 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4449 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4450 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4451 [(set_attr "conds" "clob")
4452 (set_attr "length" "8,8,12,12")])
4455 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4457 (match_operator 6 "comparison_operator"
4458 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4459 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4460 (match_operator:SI 7 "shift_operator"
4461 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4462 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4463 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4467 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4468 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4469 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4470 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4471 [(set_attr "conds" "clob")
4472 (set_attr "length" "8,8,12,12")])
4475 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4477 (match_operator 6 "comparison_operator"
4478 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4479 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4480 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4481 (match_operator:SI 7 "shift_operator"
4482 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4483 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4487 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4488 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4489 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4490 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4491 [(set_attr "conds" "clob")
4492 (set_attr "length" "8,8,12,12")])
4495 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4497 (match_operator 7 "comparison_operator"
4498 [(match_operand:SI 5 "s_register_operand" "r,r")
4499 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4500 (match_operator:SI 8 "shift_operator"
4501 [(match_operand:SI 1 "s_register_operand" "r,r")
4502 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4503 (match_operator:SI 9 "shift_operator"
4504 [(match_operand:SI 3 "s_register_operand" "r,r")
4505 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4509 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4510 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4511 [(set_attr "conds" "clob")
4512 (set_attr "length" "12")])
4515 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4517 (match_operator 6 "comparison_operator"
4518 [(match_operand:SI 4 "s_register_operand" "r,r")
4519 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4520 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4521 (match_operator:SI 7 "shiftable_operator"
4522 [(match_operand:SI 2 "s_register_operand" "r,r")
4523 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4527 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4528 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4529 [(set_attr "conds" "clob")
4530 (set_attr "length" "12")])
4533 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4535 (match_operator 6 "comparison_operator"
4536 [(match_operand:SI 4 "s_register_operand" "r,r")
4537 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4538 (match_operator:SI 7 "shiftable_operator"
4539 [(match_operand:SI 2 "s_register_operand" "r,r")
4540 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4541 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4545 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4546 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4547 [(set_attr "conds" "clob")
4548 (set_attr "length" "12")])
4551 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4553 (match_operator 5 "comparison_operator"
4554 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4555 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4556 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4557 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4558 (clobber (reg:CC 24))]
4561 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4562 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4563 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4564 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4565 [(set_attr "conds" "clob")
4566 (set_attr "length" "8,8,12,12")])
4569 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4571 (match_operator 5 "comparison_operator"
4572 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4573 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4574 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4575 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4576 (clobber (reg:CC 24))]
4579 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4580 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4581 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4582 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4583 [(set_attr "conds" "clob")
4584 (set_attr "length" "8,8,12,12")])
4587 [(set (match_operand:SI 0 "s_register_operand" "=r")
4588 (match_operator:SI 1 "shiftable_operator"
4589 [(match_operand:SI 2 "memory_operand" "m")
4590 (match_operand:SI 3 "memory_operand" "m")]))
4591 (clobber (match_scratch:SI 4 "=r"))]
4592 "adjacent_mem_locations (operands[2], operands[3])"
4597 int val1 = 0, val2 = 0;
4599 if (REGNO (operands[0]) > REGNO (operands[4]))
4601 ldm[1] = operands[4];
4602 ldm[2] = operands[0];
4606 ldm[1] = operands[0];
4607 ldm[2] = operands[4];
4609 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4610 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4611 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4612 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4613 arith[0] = operands[0];
4614 arith[3] = operands[1];
4628 ldm[0] = ops[0] = operands[4];
4629 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4630 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4631 output_add_immediate (ops);
4633 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4635 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4639 ldm[0] = XEXP (operands[3], 0);
4641 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4643 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4647 ldm[0] = XEXP (operands[2], 0);
4649 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4651 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4653 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4657 [(set_attr "length" "12")
4658 (set_attr "type" "load")])
4660 ;; the arm can support extended pre-inc instructions
4662 ;; In all these cases, we use operands 0 and 1 for the register being
4663 ;; incremented because those are the operands that local-alloc will
4664 ;; tie and these are the pair most likely to be tieable (and the ones
4665 ;; that will benefit the most).
4667 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4668 ;; elimination will cause too many headaches.
4671 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4672 (match_operand:SI 2 "index_operand" "rJ")))
4673 (match_operand:QI 3 "s_register_operand" "r"))
4674 (set (match_operand:SI 0 "s_register_operand" "=r")
4675 (plus:SI (match_dup 1) (match_dup 2)))]
4676 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4677 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4678 && (GET_CODE (operands[2]) != REG
4679 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4680 "str%?b\\t%3, [%0, %2]!"
4681 [(set_attr "type" "store1")])
4684 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4685 (match_operand:SI 2 "s_register_operand" "r")))
4686 (match_operand:QI 3 "s_register_operand" "r"))
4687 (set (match_operand:SI 0 "s_register_operand" "=r")
4688 (minus:SI (match_dup 1) (match_dup 2)))]
4689 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4690 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4691 && (GET_CODE (operands[2]) != REG
4692 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4693 "str%?b\\t%3, [%0, -%2]!"
4694 [(set_attr "type" "store1")])
4697 [(set (match_operand:QI 3 "s_register_operand" "=r")
4698 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4699 (match_operand:SI 2 "index_operand" "rJ"))))
4700 (set (match_operand:SI 0 "s_register_operand" "=r")
4701 (plus:SI (match_dup 1) (match_dup 2)))]
4702 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4703 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4704 && (GET_CODE (operands[2]) != REG
4705 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4706 "ldr%?b\\t%3, [%0, %2]!"
4707 [(set_attr "type" "load")])
4710 [(set (match_operand:QI 3 "s_register_operand" "=r")
4711 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4712 (match_operand:SI 2 "s_register_operand" "r"))))
4713 (set (match_operand:SI 0 "s_register_operand" "=r")
4714 (minus:SI (match_dup 1) (match_dup 2)))]
4715 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4716 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4717 && (GET_CODE (operands[2]) != REG
4718 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4719 "ldr%?b\\t%3, [%0, -%2]!"
4720 [(set_attr "type" "load")])
4723 [(set (match_operand:SI 3 "s_register_operand" "=r")
4725 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4726 (match_operand:SI 2 "index_operand" "rJ")))))
4727 (set (match_operand:SI 0 "s_register_operand" "=r")
4728 (plus:SI (match_dup 1) (match_dup 2)))]
4729 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4730 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4731 && (GET_CODE (operands[2]) != REG
4732 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4733 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4734 [(set_attr "type" "load")])
4737 [(set (match_operand:SI 3 "s_register_operand" "=r")
4739 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4740 (match_operand:SI 2 "s_register_operand" "r")))))
4741 (set (match_operand:SI 0 "s_register_operand" "=r")
4742 (minus:SI (match_dup 1) (match_dup 2)))]
4743 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4744 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4745 && (GET_CODE (operands[2]) != REG
4746 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4747 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4748 [(set_attr "type" "load")])
4751 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4752 (match_operand:SI 2 "index_operand" "rJ")))
4753 (match_operand:SI 3 "s_register_operand" "r"))
4754 (set (match_operand:SI 0 "s_register_operand" "=r")
4755 (plus:SI (match_dup 1) (match_dup 2)))]
4756 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4757 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4758 && (GET_CODE (operands[2]) != REG
4759 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4760 "str%?\\t%3, [%0, %2]!"
4761 [(set_attr "type" "store1")])
4764 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4765 (match_operand:SI 2 "s_register_operand" "r")))
4766 (match_operand:SI 3 "s_register_operand" "r"))
4767 (set (match_operand:SI 0 "s_register_operand" "=r")
4768 (minus:SI (match_dup 1) (match_dup 2)))]
4769 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4770 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4771 && (GET_CODE (operands[2]) != REG
4772 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4773 "str%?\\t%3, [%0, -%2]!"
4774 [(set_attr "type" "store1")])
4777 [(set (match_operand:SI 3 "s_register_operand" "=r")
4778 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4779 (match_operand:SI 2 "index_operand" "rJ"))))
4780 (set (match_operand:SI 0 "s_register_operand" "=r")
4781 (plus:SI (match_dup 1) (match_dup 2)))]
4782 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4783 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4784 && (GET_CODE (operands[2]) != REG
4785 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4786 "ldr%?\\t%3, [%0, %2]!"
4787 [(set_attr "type" "load")])
4790 [(set (match_operand:SI 3 "s_register_operand" "=r")
4791 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4792 (match_operand:SI 2 "s_register_operand" "r"))))
4793 (set (match_operand:SI 0 "s_register_operand" "=r")
4794 (minus:SI (match_dup 1) (match_dup 2)))]
4795 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4796 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4797 && (GET_CODE (operands[2]) != REG
4798 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4799 "ldr%?\\t%3, [%0, -%2]!"
4800 [(set_attr "type" "load")])
4803 [(set (match_operand:HI 3 "s_register_operand" "=r")
4804 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4805 (match_operand:SI 2 "index_operand" "rJ"))))
4806 (set (match_operand:SI 0 "s_register_operand" "=r")
4807 (plus:SI (match_dup 1) (match_dup 2)))]
4808 "(! BYTES_BIG_ENDIAN)
4809 && ! TARGET_SHORT_BY_BYTES
4810 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4811 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4812 && (GET_CODE (operands[2]) != REG
4813 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4814 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4815 [(set_attr "type" "load")])
4818 [(set (match_operand:HI 3 "s_register_operand" "=r")
4819 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4820 (match_operand:SI 2 "s_register_operand" "r"))))
4821 (set (match_operand:SI 0 "s_register_operand" "=r")
4822 (minus:SI (match_dup 1) (match_dup 2)))]
4823 "(!BYTES_BIG_ENDIAN)
4824 && ! TARGET_SHORT_BY_BYTES
4825 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4826 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4827 && (GET_CODE (operands[2]) != REG
4828 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4829 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4830 [(set_attr "type" "load")])
4833 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4834 [(match_operand:SI 3 "s_register_operand" "r")
4835 (match_operand:SI 4 "const_shift_operand" "n")])
4836 (match_operand:SI 1 "s_register_operand" "0")))
4837 (match_operand:QI 5 "s_register_operand" "r"))
4838 (set (match_operand:SI 0 "s_register_operand" "=r")
4839 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4841 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4842 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4843 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4844 "str%?b\\t%5, [%0, %3%S2]!"
4845 [(set_attr "type" "store1")])
4848 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4849 (match_operator:SI 2 "shift_operator"
4850 [(match_operand:SI 3 "s_register_operand" "r")
4851 (match_operand:SI 4 "const_shift_operand" "n")])))
4852 (match_operand:QI 5 "s_register_operand" "r"))
4853 (set (match_operand:SI 0 "s_register_operand" "=r")
4854 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4856 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4857 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4858 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4859 "str%?b\\t%5, [%0, -%3%S2]!"
4860 [(set_attr "type" "store1")])
4863 [(set (match_operand:QI 5 "s_register_operand" "=r")
4864 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4865 [(match_operand:SI 3 "s_register_operand" "r")
4866 (match_operand:SI 4 "const_shift_operand" "n")])
4867 (match_operand:SI 1 "s_register_operand" "0"))))
4868 (set (match_operand:SI 0 "s_register_operand" "=r")
4869 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4871 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4872 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4873 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4874 "ldr%?b\\t%5, [%0, %3%S2]!"
4875 [(set_attr "type" "load")])
4878 [(set (match_operand:QI 5 "s_register_operand" "=r")
4879 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4880 (match_operator:SI 2 "shift_operator"
4881 [(match_operand:SI 3 "s_register_operand" "r")
4882 (match_operand:SI 4 "const_shift_operand" "n")]))))
4883 (set (match_operand:SI 0 "s_register_operand" "=r")
4884 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4886 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4887 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4888 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4889 "ldr%?b\\t%5, [%0, -%3%S2]!"
4890 [(set_attr "type" "load")])
4893 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4894 [(match_operand:SI 3 "s_register_operand" "r")
4895 (match_operand:SI 4 "const_shift_operand" "n")])
4896 (match_operand:SI 1 "s_register_operand" "0")))
4897 (match_operand:SI 5 "s_register_operand" "r"))
4898 (set (match_operand:SI 0 "s_register_operand" "=r")
4899 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4901 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4902 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4903 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4904 "str%?\\t%5, [%0, %3%S2]!"
4905 [(set_attr "type" "store1")])
4908 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4909 (match_operator:SI 2 "shift_operator"
4910 [(match_operand:SI 3 "s_register_operand" "r")
4911 (match_operand:SI 4 "const_shift_operand" "n")])))
4912 (match_operand:SI 5 "s_register_operand" "r"))
4913 (set (match_operand:SI 0 "s_register_operand" "=r")
4914 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4916 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4917 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4918 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4919 "str%?\\t%5, [%0, -%3%S2]!"
4920 [(set_attr "type" "store1")])
4923 [(set (match_operand:SI 5 "s_register_operand" "=r")
4924 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4925 [(match_operand:SI 3 "s_register_operand" "r")
4926 (match_operand:SI 4 "const_shift_operand" "n")])
4927 (match_operand:SI 1 "s_register_operand" "0"))))
4928 (set (match_operand:SI 0 "s_register_operand" "=r")
4929 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4931 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4932 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4933 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4934 "ldr%?\\t%5, [%0, %3%S2]!"
4935 [(set_attr "type" "load")])
4938 [(set (match_operand:SI 5 "s_register_operand" "=r")
4939 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4940 (match_operator:SI 2 "shift_operator"
4941 [(match_operand:SI 3 "s_register_operand" "r")
4942 (match_operand:SI 4 "const_shift_operand" "n")]))))
4943 (set (match_operand:SI 0 "s_register_operand" "=r")
4944 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4946 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4947 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4948 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4949 "ldr%?\\t%5, [%0, -%3%S2]!"
4950 [(set_attr "type" "load")])
4953 [(set (match_operand:HI 5 "s_register_operand" "=r")
4954 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
4955 [(match_operand:SI 3 "s_register_operand" "r")
4956 (match_operand:SI 4 "const_shift_operand" "n")])
4957 (match_operand:SI 1 "s_register_operand" "0"))))
4958 (set (match_operand:SI 0 "s_register_operand" "=r")
4959 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4961 "(! BYTES_BIG_ENDIAN)
4962 && ! TARGET_SHORT_BY_BYTES
4963 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4964 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4965 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4966 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
4967 [(set_attr "type" "load")])
4970 [(set (match_operand:HI 5 "s_register_operand" "=r")
4971 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4972 (match_operator:SI 2 "shift_operator"
4973 [(match_operand:SI 3 "s_register_operand" "r")
4974 (match_operand:SI 4 "const_shift_operand" "n")]))))
4975 (set (match_operand:SI 0 "s_register_operand" "=r")
4976 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4978 "(! BYTES_BIG_ENDIAN)
4979 && ! TARGET_SHORT_BY_BYTES
4980 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4981 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4982 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4983 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
4984 [(set_attr "type" "load")])
4986 ; It can also support extended post-inc expressions, but combine doesn't
4988 ; It doesn't seem worth adding peepholes for anything but the most common
4989 ; cases since, unlike combine, the increment must immediately follow the load
4990 ; for this pattern to match.
4991 ; When loading we must watch to see that the base register isn't trampled by
4992 ; the load. In such cases this isn't a post-inc expression.
4995 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
4996 (match_operand:QI 2 "s_register_operand" "r"))
4998 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5000 "str%?b\\t%2, [%0], %1")
5003 [(set (match_operand:QI 0 "s_register_operand" "=r")
5004 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5006 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5007 "REGNO(operands[0]) != REGNO(operands[1])
5008 && (GET_CODE (operands[2]) != REG
5009 || REGNO(operands[0]) != REGNO (operands[2]))"
5010 "ldr%?b\\t%0, [%1], %2")
5013 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5014 (match_operand:SI 2 "s_register_operand" "r"))
5016 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5018 "str%?\\t%2, [%0], %1")
5021 [(set (match_operand:HI 0 "s_register_operand" "=r")
5022 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5024 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5025 "(! BYTES_BIG_ENDIAN)
5026 && ! TARGET_SHORT_BY_BYTES
5027 && REGNO(operands[0]) != REGNO(operands[1])
5028 && (GET_CODE (operands[2]) != REG
5029 || REGNO(operands[0]) != REGNO (operands[2]))"
5030 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5033 [(set (match_operand:SI 0 "s_register_operand" "=r")
5034 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5036 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5037 "REGNO(operands[0]) != REGNO(operands[1])
5038 && (GET_CODE (operands[2]) != REG
5039 || REGNO(operands[0]) != REGNO (operands[2]))"
5040 "ldr%?\\t%0, [%1], %2")
5043 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5044 (match_operand:SI 1 "index_operand" "rJ")))
5045 (match_operand:QI 2 "s_register_operand" "r"))
5046 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5048 "str%?b\\t%2, [%0, %1]!")
5051 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5052 [(match_operand:SI 0 "s_register_operand" "r")
5053 (match_operand:SI 1 "const_int_operand" "n")])
5054 (match_operand:SI 2 "s_register_operand" "+r")))
5055 (match_operand:QI 3 "s_register_operand" "r"))
5056 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5059 "str%?b\\t%3, [%2, %0%S4]!")
5061 ; This pattern is never tried by combine, so do it as a peephole
5064 [(set (match_operand:SI 0 "s_register_operand" "=r")
5065 (match_operand:SI 1 "s_register_operand" "r"))
5066 (set (match_operand 2 "cc_register" "")
5067 (compare (match_dup 1) (const_int 0)))]
5069 "sub%?s\\t%0, %1, #0"
5070 [(set_attr "conds" "set")])
5072 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5073 ; reversed, check that the memory references aren't volatile.
5076 [(set (match_operand:SI 0 "s_register_operand" "=r")
5077 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5079 (set (match_operand:SI 2 "s_register_operand" "=r")
5080 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5081 (set (match_operand:SI 3 "s_register_operand" "=r")
5082 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5083 (set (match_operand:SI 4 "s_register_operand" "=r")
5084 (mem:SI (match_dup 1)))]
5085 "REGNO (operands[0]) > REGNO (operands[2])
5086 && REGNO (operands[2]) > REGNO (operands[3])
5087 && REGNO (operands[3]) > REGNO (operands[4])
5088 && !(REGNO (operands[1]) == REGNO (operands[0])
5089 || REGNO (operands[1]) == REGNO (operands[2])
5090 || REGNO (operands[1]) == REGNO (operands[3])
5091 || REGNO (operands[1]) == REGNO (operands[4]))
5092 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5093 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5094 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5095 (prev_nonnote_insn (insn)))))
5096 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5098 (prev_nonnote_insn (insn))))))"
5099 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5102 [(set (match_operand:SI 0 "s_register_operand" "=r")
5103 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5105 (set (match_operand:SI 2 "s_register_operand" "=r")
5106 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5107 (set (match_operand:SI 3 "s_register_operand" "=r")
5108 (mem:SI (match_dup 1)))]
5109 "REGNO (operands[0]) > REGNO (operands[2])
5110 && REGNO (operands[2]) > REGNO (operands[3])
5111 && !(REGNO (operands[1]) == REGNO (operands[0])
5112 || REGNO (operands[1]) == REGNO (operands[2])
5113 || REGNO (operands[1]) == REGNO (operands[3]))
5114 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5115 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5116 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5117 (prev_nonnote_insn (insn)))))"
5118 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5121 [(set (match_operand:SI 0 "s_register_operand" "=r")
5122 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5124 (set (match_operand:SI 2 "s_register_operand" "=r")
5125 (mem:SI (match_dup 1)))]
5126 "REGNO (operands[0]) > REGNO (operands[2])
5127 && !(REGNO (operands[1]) == REGNO (operands[0])
5128 || REGNO (operands[1]) == REGNO (operands[2]))
5129 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5130 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5131 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5134 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5136 (match_operand:SI 0 "s_register_operand" "r"))
5137 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5138 (match_operand:SI 2 "s_register_operand" "r"))
5139 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5140 (match_operand:SI 3 "s_register_operand" "r"))
5141 (set (mem:SI (match_dup 1))
5142 (match_operand:SI 4 "s_register_operand" "r"))]
5143 "REGNO (operands[0]) > REGNO (operands[2])
5144 && REGNO (operands[2]) > REGNO (operands[3])
5145 && REGNO (operands[3]) > REGNO (operands[4])
5146 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5147 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5148 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5149 (prev_nonnote_insn (insn)))))
5150 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5152 (prev_nonnote_insn (insn))))))"
5153 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5156 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5158 (match_operand:SI 0 "s_register_operand" "r"))
5159 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5160 (match_operand:SI 2 "s_register_operand" "r"))
5161 (set (mem:SI (match_dup 1))
5162 (match_operand:SI 3 "s_register_operand" "r"))]
5163 "REGNO (operands[0]) > REGNO (operands[2])
5164 && REGNO (operands[2]) > REGNO (operands[3])
5165 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5166 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5167 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5168 (prev_nonnote_insn (insn)))))"
5169 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5172 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5174 (match_operand:SI 0 "s_register_operand" "r"))
5175 (set (mem:SI (match_dup 1))
5176 (match_operand:SI 2 "s_register_operand" "r"))]
5177 "REGNO (operands[0]) > REGNO (operands[2])
5178 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5179 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5180 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5182 ;; A call followed by return can be replaced by restoring the regs and
5183 ;; jumping to the subroutine, provided we aren't passing the address of
5184 ;; any of our local variables. If we call alloca then this is unsafe
5185 ;; since restoring the frame frees the memory, which is not what we want.
5186 ;; Sometimes the return might have been targeted by the final prescan:
5187 ;; if so then emit a propper return insn as well.
5188 ;; Unfortunately, if the frame pointer is required, we don't know if the
5189 ;; current function has any implicit stack pointer adjustments that will
5190 ;; be restored by the return: we can't therefore do a tail call.
5191 ;; Another unfortunate that we can't handle is if current_function_args_size
5192 ;; is non-zero: in this case elimination of the argument pointer assumed
5193 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5197 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5198 (match_operand:SI 1 "general_operand" "g"))
5199 (clobber (reg:SI 14))])
5201 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5202 && !get_frame_size () && !current_function_calls_alloca
5203 && !frame_pointer_needed && !current_function_args_size)"
5206 extern rtx arm_target_insn;
5207 extern int arm_ccfsm_state, arm_current_cc;
5209 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5211 arm_current_cc ^= 1;
5212 output_return_instruction (NULL, TRUE);
5213 arm_ccfsm_state = 0;
5214 arm_target_insn = NULL;
5217 output_return_instruction (NULL, FALSE);
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" "8")])
5227 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5228 (call (mem:SI (match_operand:SI 1 "" "i"))
5229 (match_operand:SI 2 "general_operand" "g")))
5230 (clobber (reg:SI 14))])
5232 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5233 && !get_frame_size () && !current_function_calls_alloca
5234 && !frame_pointer_needed && !current_function_args_size)"
5237 extern rtx arm_target_insn;
5238 extern int arm_ccfsm_state, arm_current_cc;
5240 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5242 arm_current_cc ^= 1;
5243 output_return_instruction (NULL, TRUE);
5244 arm_ccfsm_state = 0;
5245 arm_target_insn = NULL;
5248 output_return_instruction (NULL, FALSE);
5249 return \"b%?\\t%a1\";
5251 [(set (attr "conds")
5252 (if_then_else (eq_attr "cpu" "arm6")
5253 (const_string "clob")
5254 (const_string "nocond")))
5255 (set_attr "length" "8")])
5257 ;; As above but when this function is not void, we must be returning the
5258 ;; result of the called subroutine.
5261 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5262 (call (mem:SI (match_operand:SI 1 "" "i"))
5263 (match_operand:SI 2 "general_operand" "g")))
5264 (clobber (reg:SI 14))])
5267 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5268 && !get_frame_size () && !current_function_calls_alloca
5269 && !frame_pointer_needed && !current_function_args_size)"
5272 extern rtx arm_target_insn;
5273 extern int arm_ccfsm_state, arm_current_cc;
5275 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5277 arm_current_cc ^= 1;
5278 output_return_instruction (NULL, TRUE);
5279 arm_ccfsm_state = 0;
5280 arm_target_insn = NULL;
5283 output_return_instruction (NULL, FALSE);
5284 return \"b%?\\t%a1\";
5286 [(set (attr "conds")
5287 (if_then_else (eq_attr "cpu" "arm6")
5288 (const_string "clob")
5289 (const_string "nocond")))
5290 (set_attr "length" "8")])
5292 ;; If calling a subroutine and then jumping back to somewhere else, but not
5293 ;; too far away, then we can set the link register with the branch address
5294 ;; and jump direct to the subroutine. On return from the subroutine
5295 ;; execution continues at the branch; this avoids a prefetch stall.
5296 ;; We use the length attribute (via short_branch ()) to establish whether or
5297 ;; not this is possible, this is the same asthe sparc does.
5300 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5301 (match_operand:SI 1 "general_operand" "g"))
5302 (clobber (reg:SI 14))])
5304 (label_ref (match_operand 2 "" "")))]
5305 "0 && GET_CODE (operands[0]) == SYMBOL_REF
5306 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5307 && arm_insn_not_targeted (insn)"
5310 int backward = arm_backwards_branch (INSN_UID (insn),
5311 INSN_UID (operands[2]));
5314 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5315 * above, leaving it out means that the code will still run on an arm 2 or 3
5320 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5322 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5327 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5329 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5331 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5333 return \"b%?\\t%a0\";
5335 [(set (attr "conds")
5336 (if_then_else (eq_attr "cpu" "arm6")
5337 (const_string "clob")
5338 (const_string "nocond")))
5339 (set (attr "length")
5340 (if_then_else (eq_attr "cpu" "arm6")
5345 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5346 (call (mem:SI (match_operand:SI 1 "" "i"))
5347 (match_operand:SI 2 "general_operand" "g")))
5348 (clobber (reg:SI 14))])
5350 (label_ref (match_operand 3 "" "")))]
5351 "0 && GET_CODE (operands[0]) == SYMBOL_REF
5352 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5353 && arm_insn_not_targeted (insn)"
5356 int backward = arm_backwards_branch (INSN_UID (insn),
5357 INSN_UID (operands[3]));
5360 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5361 * above, leaving it out means that the code will still run on an arm 2 or 3
5366 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5368 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5373 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5375 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5377 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5379 return \"b%?\\t%a1\";
5381 [(set (attr "conds")
5382 (if_then_else (eq_attr "cpu" "arm6")
5383 (const_string "clob")
5384 (const_string "nocond")))
5385 (set (attr "length")
5386 (if_then_else (eq_attr "cpu" "arm6")
5392 (if_then_else (match_operator 0 "comparison_operator"
5393 [(match_operator:SI 1 "shift_operator"
5394 [(match_operand:SI 2 "s_register_operand" "r")
5395 (match_operand:SI 3 "reg_or_int_operand" "rM")])
5396 (match_operand:SI 4 "s_register_operand" "r")])
5397 (label_ref (match_operand 5 "" ""))
5402 (compare:CC (match_dup 4)
5403 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5405 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5406 (label_ref (match_dup 5))
5409 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5410 operands[1], operands[2]);
5414 [(set (match_operand:SI 0 "s_register_operand" "")
5415 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5417 (neg:SI (match_operator:SI 2 "comparison_operator"
5418 [(match_operand:SI 3 "s_register_operand" "")
5419 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5420 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5422 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5423 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5427 ;; This pattern can be used because cc_noov mode implies that the following
5428 ;; branch will be an equality (EQ or NE), so the sign extension is not
5429 ;; needed. Combine doesn't eliminate these because by the time it sees the
5430 ;; branch it no-longer knows that the data came from memory.
5433 [(set (reg:CC_NOOV 24)
5435 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5437 (match_operand 1 "immediate_operand" "I")))
5438 (clobber (match_scratch:SI 2 "=r"))]
5439 "((unsigned long) INTVAL (operands[1]))
5440 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5442 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5443 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5444 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5447 [(set_attr "conds" "set")
5448 (set_attr "length" "8")
5449 (set_attr "type" "load")])
5451 (define_expand "prologue"
5452 [(clobber (const_int 0))]
5455 arm_expand_prologue ();
5459 ;; This split is only used during output to reduce the number of patterns
5460 ;; that need assembler instructions adding to them. We allowed the setting
5461 ;; of the conditions to be implicit during rtl generation so that
5462 ;; the conditional compare patterns would work. However this conflicts to
5463 ;; some extend with the conditional data operations, so we have to split them
5467 [(set (match_operand:SI 0 "s_register_operand" "")
5468 (if_then_else:SI (match_operator 1 "comparison_operator"
5469 [(match_operand 2 "" "") (match_operand 3 "" "")])
5470 (match_operand 4 "" "")
5471 (match_operand 5 "" "")))
5474 [(set (match_dup 6) (match_dup 7))
5476 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5481 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5484 operands[6] = gen_rtx (REG, mode, 24);
5485 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5491 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5492 (if_then_else:SI (match_operator 4 "comparison_operator"
5493 [(match_operand 3 "reversible_cc_register" "")
5495 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5497 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5501 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5502 [(set_attr "conds" "use")
5503 (set_attr "length" "4,8")])
5505 ;; The next two patterns occur when an AND operation is followed by a
5506 ;; scc insn sequence
5509 [(set (match_operand:SI 0 "s_register_operand" "=r")
5510 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5512 (match_operand:SI 2 "immediate_operand" "n")))]
5515 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5516 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5517 return \"mvnne\\t%0, #0\";
5519 [(set_attr "conds" "clob")
5520 (set_attr "length" "8")])
5523 [(set (match_operand:SI 0 "s_register_operand" "=r")
5525 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5527 (match_operand:SI 2 "immediate_operand" "n"))))]
5530 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5531 output_asm_insn (\"tst\\t%1, %2\", operands);
5532 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5533 return \"movne\\t%0, #0\";
5535 [(set_attr "conds" "clob")
5536 (set_attr "length" "12")])
5538 ;; Push multiple registers to the stack. The first register is in the
5539 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5542 [(match_parallel 2 "multi_register_push"
5543 [(set (match_operand:BLK 0 "memory_operand" "=m")
5544 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5550 extern int lr_save_eliminated;
5552 if (lr_save_eliminated)
5554 if (XVECLEN (operands[2], 0) > 1)
5558 strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5559 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5561 strcat (pattern, \", %|\");
5562 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5565 strcat (pattern, \"}\");
5566 output_asm_insn (pattern, operands);
5569 [(set_attr "type" "store4")])