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 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2497 XEXP (XEXP (operands[0], 0), 1)));
2498 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2504 [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
2505 (match_operand:DF 1 "general_operand"
2506 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
2507 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2512 switch (which_alternative)
2515 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2518 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2521 ops[0] = operands[0];
2522 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2523 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2524 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2525 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2527 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2528 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2532 return \"mvf%?d\\t%0, %1\";
2534 case 5: return \"mnf%?d\\t%0, #%N1\";
2535 case 6: return \"ldf%?d\\t%0, %1\";
2536 case 7: return \"stf%?d\\t%1, %0\";
2537 case 8: return output_mov_double_fpu_from_arm (operands);
2538 case 9: return output_mov_double_arm_from_fpu (operands);
2539 case 10: return output_move_double (operands);
2543 [(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
2545 "load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2547 (define_expand "movxf"
2548 [(set (match_operand:XF 0 "general_operand" "")
2549 (match_operand:XF 1 "general_operand" ""))]
2550 "ENABLE_XF_PATTERNS"
2553 ;; Even when the XFmode patterns aren't enabled, we enable this after
2554 ;; reloading so that we can push floating point registers in the prologue.
2557 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2558 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2559 "ENABLE_XF_PATTERNS || reload_completed"
2561 switch (which_alternative)
2563 case 0: return \"mvf%?e\\t%0, %1\";
2564 case 1: return \"mnf%?e\\t%0, #%N1\";
2565 case 2: return \"ldf%?e\\t%0, %1\";
2566 case 3: return \"stf%?e\\t%1, %0\";
2567 case 4: return output_mov_long_double_fpu_from_arm (operands);
2568 case 5: return output_mov_long_double_arm_from_fpu (operands);
2569 case 6: return output_mov_long_double_arm_from_arm (operands);
2572 [(set_attr "length" "4,4,4,4,8,8,12")
2573 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2576 ;; load- and store-multiple insns
2577 ;; The arm can load/store any set of registers, provided that they are in
2578 ;; ascending order; but that is beyond GCC so stick with what it knows.
2580 (define_expand "load_multiple"
2581 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2582 (match_operand:SI 1 "" ""))
2583 (use (match_operand:SI 2 "" ""))])]
2586 /* Support only fixed point registers */
2587 if (GET_CODE (operands[2]) != CONST_INT
2588 || INTVAL (operands[2]) > 14
2589 || INTVAL (operands[2]) < 2
2590 || GET_CODE (operands[1]) != MEM
2591 || GET_CODE (operands[0]) != REG
2592 || REGNO (operands[0]) > 14
2593 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2597 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2598 force_reg (SImode, XEXP (operands[1], 0)),
2602 ;; Load multiple with write-back
2605 [(match_parallel 0 "load_multiple_operation"
2606 [(set (match_operand:SI 1 "s_register_operand" "+r")
2607 (plus:SI (match_dup 1)
2608 (match_operand:SI 2 "immediate_operand" "n")))
2609 (set (match_operand:SI 3 "s_register_operand" "=r")
2610 (mem:SI (match_dup 1)))])]
2611 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2615 int count = XVECLEN (operands[0], 0);
2617 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2618 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2619 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2621 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2625 [(set_attr "type" "load")])
2627 ;; Ordinary load multiple
2630 [(match_parallel 0 "load_multiple_operation"
2631 [(set (match_operand:SI 1 "s_register_operand" "=r")
2632 (match_operand:SI 2 "indirect_operand" "Q"))])]
2637 int count = XVECLEN (operands[0], 0);
2639 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2640 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2641 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2643 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2647 [(set_attr "type" "load")])
2649 (define_expand "store_multiple"
2650 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2651 (match_operand:SI 1 "" ""))
2652 (use (match_operand:SI 2 "" ""))])]
2655 /* Support only fixed point registers */
2656 if (GET_CODE (operands[2]) != CONST_INT
2657 || INTVAL (operands[2]) > 14
2658 || INTVAL (operands[2]) < 2
2659 || GET_CODE (operands[1]) != REG
2660 || GET_CODE (operands[0]) != MEM
2661 || REGNO (operands[1]) > 14
2662 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2666 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2667 force_reg (SImode, XEXP (operands[0], 0)),
2671 ;; Store multiple with write-back
2674 [(match_parallel 0 "store_multiple_operation"
2675 [(set (match_operand:SI 1 "s_register_operand" "+r")
2676 (plus:SI (match_dup 1)
2677 (match_operand:SI 2 "immediate_operand" "n")))
2678 (set (mem:SI (match_dup 1))
2679 (match_operand:SI 3 "s_register_operand" "r"))])]
2680 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2684 int count = XVECLEN (operands[0], 0);
2686 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2687 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2688 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2690 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2695 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2696 (const_string "store2")
2697 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2698 (const_string "store3")]
2699 (const_string "store4")))])
2701 ;; Ordinary store multiple
2704 [(match_parallel 0 "store_multiple_operation"
2705 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2706 (match_operand:SI 1 "s_register_operand" "r"))])]
2711 int count = XVECLEN (operands[0], 0);
2713 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2714 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2715 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2717 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2722 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2723 (const_string "store2")
2724 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2725 (const_string "store3")]
2726 (const_string "store4")))])
2728 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2729 ;; We could let this apply for blocks of less than this, but it clobbers so
2730 ;; many registers that there is then probably a better way.
2732 (define_expand "movstrqi"
2733 [(match_operand:BLK 0 "general_operand" "")
2734 (match_operand:BLK 1 "general_operand" "")
2735 (match_operand:SI 2 "const_int_operand" "")
2736 (match_operand:SI 3 "const_int_operand" "")]
2739 if (arm_gen_movstrqi (operands))
2745 ;; Comparison and test insns
2747 (define_expand "cmpsi"
2749 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2750 (match_operand:SI 1 "arm_add_operand" "")))]
2754 arm_compare_op0 = operands[0];
2755 arm_compare_op1 = operands[1];
2761 (define_expand "cmpsf"
2763 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2764 (match_operand:SF 1 "fpu_rhs_operand" "")))]
2768 arm_compare_op0 = operands[0];
2769 arm_compare_op1 = operands[1];
2775 (define_expand "cmpdf"
2777 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2778 (match_operand:DF 1 "fpu_rhs_operand" "")))]
2782 arm_compare_op0 = operands[0];
2783 arm_compare_op1 = operands[1];
2789 (define_expand "cmpxf"
2791 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2792 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2793 "ENABLE_XF_PATTERNS"
2796 arm_compare_op0 = operands[0];
2797 arm_compare_op1 = operands[1];
2804 [(set (match_operand 0 "cc_register" "")
2805 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2806 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
2811 [(set_attr "conds" "set")])
2814 [(set (match_operand 0 "cc_register" "")
2815 (compare (match_operand:SI 1 "s_register_operand" "r")
2816 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2819 [(set_attr "conds" "set")])
2822 [(set (match_operand 0 "cc_register" "")
2823 (compare (match_operand:SI 1 "s_register_operand" "r")
2824 (match_operator:SI 2 "shift_operator"
2825 [(match_operand:SI 3 "s_register_operand" "r")
2826 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
2829 [(set_attr "conds" "set")])
2832 [(set (match_operand 0 "cc_register" "")
2833 (compare (match_operand:SI 1 "s_register_operand" "r")
2834 (neg:SI (match_operator:SI 2 "shift_operator"
2835 [(match_operand:SI 3 "s_register_operand" "r")
2836 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
2839 [(set_attr "conds" "set")])
2843 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2844 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2849 [(set_attr "conds" "set")
2850 (set_attr "type" "f_2_r")])
2854 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2855 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2860 [(set_attr "conds" "set")
2861 (set_attr "type" "f_2_r")])
2865 (compare:CCFP (float_extend:DF
2866 (match_operand:SF 0 "s_register_operand" "f,f"))
2867 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2872 [(set_attr "conds" "set")
2873 (set_attr "type" "f_2_r")])
2877 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2879 (match_operand:SF 1 "s_register_operand" "f"))))]
2882 [(set_attr "conds" "set")
2883 (set_attr "type" "f_2_r")])
2887 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2888 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2889 "ENABLE_XF_PATTERNS"
2893 [(set_attr "conds" "set")
2894 (set_attr "type" "f_2_r")])
2897 [(set (reg:CCFPE 24)
2898 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2899 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2904 [(set_attr "conds" "set")
2905 (set_attr "type" "f_2_r")])
2908 [(set (reg:CCFPE 24)
2909 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2910 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2915 [(set_attr "conds" "set")
2916 (set_attr "type" "f_2_r")])
2919 [(set (reg:CCFPE 24)
2920 (compare:CCFPE (float_extend:DF
2921 (match_operand:SF 0 "s_register_operand" "f,f"))
2922 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2927 [(set_attr "conds" "set")
2928 (set_attr "type" "f_2_r")])
2931 [(set (reg:CCFPE 24)
2932 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2934 (match_operand:SF 1 "s_register_operand" "f"))))]
2937 [(set_attr "conds" "set")
2938 (set_attr "type" "f_2_r")])
2941 [(set (reg:CCFPE 24)
2942 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2943 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2944 "ENABLE_XF_PATTERNS"
2948 [(set_attr "conds" "set")
2949 (set_attr "type" "f_2_r")])
2951 ; This insn allows redundant compares to be removed by cse, nothing should
2952 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2953 ; is deleted later on. The match_dup will match the mode here, so that
2954 ; mode changes of the condition codes aren't lost by this even though we don't
2955 ; specify what they are.
2958 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2960 "\\t%@ deleted compare"
2961 [(set_attr "conds" "set")
2962 (set_attr "length" "0")])
2965 ;; Conditional branch insns
2967 (define_expand "beq"
2969 (if_then_else (eq (match_dup 1) (const_int 0))
2970 (label_ref (match_operand 0 "" ""))
2975 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2980 (define_expand "bne"
2982 (if_then_else (ne (match_dup 1) (const_int 0))
2983 (label_ref (match_operand 0 "" ""))
2988 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
2993 (define_expand "bgt"
2995 (if_then_else (gt (match_dup 1) (const_int 0))
2996 (label_ref (match_operand 0 "" ""))
3001 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3006 (define_expand "ble"
3008 (if_then_else (le (match_dup 1) (const_int 0))
3009 (label_ref (match_operand 0 "" ""))
3014 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3019 (define_expand "bge"
3021 (if_then_else (ge (match_dup 1) (const_int 0))
3022 (label_ref (match_operand 0 "" ""))
3027 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3032 (define_expand "blt"
3034 (if_then_else (lt (match_dup 1) (const_int 0))
3035 (label_ref (match_operand 0 "" ""))
3040 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3045 (define_expand "bgtu"
3047 (if_then_else (gtu (match_dup 1) (const_int 0))
3048 (label_ref (match_operand 0 "" ""))
3053 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3058 (define_expand "bleu"
3060 (if_then_else (leu (match_dup 1) (const_int 0))
3061 (label_ref (match_operand 0 "" ""))
3066 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3071 (define_expand "bgeu"
3073 (if_then_else (geu (match_dup 1) (const_int 0))
3074 (label_ref (match_operand 0 "" ""))
3079 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3084 (define_expand "bltu"
3086 (if_then_else (ltu (match_dup 1) (const_int 0))
3087 (label_ref (match_operand 0 "" ""))
3092 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3097 ;; patterns to match conditional branch insns
3101 (if_then_else (match_operator 1 "comparison_operator"
3102 [(reg 24) (const_int 0)])
3103 (label_ref (match_operand 0 "" ""))
3108 extern int arm_ccfsm_state;
3110 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3112 arm_ccfsm_state += 2;
3115 return \"b%d1\\t%l0\";
3117 [(set_attr "conds" "use")])
3121 (if_then_else (match_operator 1 "comparison_operator"
3122 [(reg 24) (const_int 0)])
3124 (label_ref (match_operand 0 "" ""))))]
3125 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3128 extern int arm_ccfsm_state;
3130 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3132 arm_ccfsm_state += 2;
3135 return \"b%D1\\t%l0\";
3137 [(set_attr "conds" "use")])
3142 (define_expand "seq"
3143 [(set (match_operand:SI 0 "s_register_operand" "=r")
3144 (eq:SI (match_dup 1) (const_int 0)))]
3148 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3153 (define_expand "sne"
3154 [(set (match_operand:SI 0 "s_register_operand" "=r")
3155 (ne:SI (match_dup 1) (const_int 0)))]
3159 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3164 (define_expand "sgt"
3165 [(set (match_operand:SI 0 "s_register_operand" "=r")
3166 (gt:SI (match_dup 1) (const_int 0)))]
3170 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3175 (define_expand "sle"
3176 [(set (match_operand:SI 0 "s_register_operand" "=r")
3177 (le:SI (match_dup 1) (const_int 0)))]
3181 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3186 (define_expand "sge"
3187 [(set (match_operand:SI 0 "s_register_operand" "=r")
3188 (ge:SI (match_dup 1) (const_int 0)))]
3192 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3197 (define_expand "slt"
3198 [(set (match_operand:SI 0 "s_register_operand" "=r")
3199 (lt:SI (match_dup 1) (const_int 0)))]
3203 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3208 (define_expand "sgtu"
3209 [(set (match_operand:SI 0 "s_register_operand" "=r")
3210 (gtu:SI (match_dup 1) (const_int 0)))]
3214 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3219 (define_expand "sleu"
3220 [(set (match_operand:SI 0 "s_register_operand" "=r")
3221 (leu:SI (match_dup 1) (const_int 0)))]
3225 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3230 (define_expand "sgeu"
3231 [(set (match_operand:SI 0 "s_register_operand" "=r")
3232 (geu:SI (match_dup 1) (const_int 0)))]
3236 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3241 (define_expand "sltu"
3242 [(set (match_operand:SI 0 "s_register_operand" "=r")
3243 (ltu:SI (match_dup 1) (const_int 0)))]
3247 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3253 [(set (match_operand:SI 0 "s_register_operand" "=r")
3254 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3256 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3257 [(set_attr "conds" "use")
3258 (set_attr "length" "8")])
3261 [(set (match_operand:SI 0 "s_register_operand" "=r")
3262 (neg:SI (match_operator:SI 1 "comparison_operator"
3263 [(reg 24) (const_int 0)])))]
3265 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3266 [(set_attr "conds" "use")
3267 (set_attr "length" "8")])
3270 [(set (match_operand:SI 0 "s_register_operand" "=r")
3271 (not:SI (match_operator:SI 1 "comparison_operator"
3272 [(reg 24) (const_int 0)])))]
3274 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3275 [(set_attr "conds" "use")
3276 (set_attr "length" "8")])
3279 ;; Jump and linkage insns
3283 (label_ref (match_operand 0 "" "")))]
3287 extern int arm_ccfsm_state;
3289 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3291 arm_ccfsm_state += 2;
3294 return \"b%?\\t%l0\";
3297 (define_expand "call"
3298 [(parallel [(call (match_operand 0 "memory_operand" "")
3299 (match_operand 1 "general_operand" ""))
3300 (clobber (reg:SI 14))])]
3305 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3306 (match_operand 1 "" "g"))
3307 (clobber (reg:SI 14))]
3310 return output_call (operands);
3312 [(set (attr "conds")
3313 (if_then_else (eq_attr "cpu" "arm6")
3314 (const_string "clob")
3315 (const_string "nocond")))
3316 ;; length is worst case, normally it is only two
3317 (set_attr "length" "12")
3318 (set_attr "type" "call")])
3321 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3322 (match_operand 1 "general_operand" "g"))
3323 (clobber (reg:SI 14))]
3326 return output_call_mem (operands);
3328 [(set (attr "conds")
3329 (if_then_else (eq_attr "cpu" "arm6")
3330 (const_string "clob")
3331 (const_string "nocond")))
3332 (set_attr "length" "12")
3333 (set_attr "type" "call")])
3335 (define_expand "call_value"
3336 [(parallel [(set (match_operand 0 "" "=rf")
3337 (call (match_operand 1 "memory_operand" "m")
3338 (match_operand 2 "general_operand" "g")))
3339 (clobber (reg:SI 14))])]
3344 [(set (match_operand 0 "" "=rf")
3345 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3346 (match_operand 2 "general_operand" "g")))
3347 (clobber (reg:SI 14))]
3350 return output_call (&operands[1]);
3352 [(set (attr "conds")
3353 (if_then_else (eq_attr "cpu" "arm6")
3354 (const_string "clob")
3355 (const_string "nocond")))
3356 (set_attr "length" "12")
3357 (set_attr "type" "call")])
3360 [(set (match_operand 0 "" "=rf")
3361 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3362 (match_operand 2 "general_operand" "g")))
3363 (clobber (reg:SI 14))]
3364 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3366 return output_call_mem (&operands[1]);
3368 [(set (attr "conds")
3369 (if_then_else (eq_attr "cpu" "arm6")
3370 (const_string "clob")
3371 (const_string "nocond")))
3372 (set_attr "length" "12")
3373 (set_attr "type" "call")])
3375 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3376 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3379 [(call (mem:SI (match_operand:SI 0 "" "i"))
3380 (match_operand:SI 1 "general_operand" "g"))
3381 (clobber (reg:SI 14))]
3382 "GET_CODE (operands[0]) == SYMBOL_REF"
3384 [(set (attr "conds")
3385 (if_then_else (eq_attr "cpu" "arm6")
3386 (const_string "clob")
3387 (const_string "nocond")))
3388 (set_attr "type" "call")])
3391 [(set (match_operand 0 "s_register_operand" "=rf")
3392 (call (mem:SI (match_operand:SI 1 "" "i"))
3393 (match_operand:SI 2 "general_operand" "g")))
3394 (clobber (reg:SI 14))]
3395 "GET_CODE(operands[1]) == SYMBOL_REF"
3397 [(set (attr "conds")
3398 (if_then_else (eq_attr "cpu" "arm6")
3399 (const_string "clob")
3400 (const_string "nocond")))
3401 (set_attr "type" "call")])
3403 ;; Often the return insn will be the same as loading from memory, so set attr
3404 (define_insn "return"
3409 extern int arm_ccfsm_state;
3411 if (arm_ccfsm_state == 2)
3413 arm_ccfsm_state += 2;
3416 return output_return_instruction (NULL, TRUE);
3418 [(set_attr "type" "load")])
3422 (if_then_else (match_operator 0 "comparison_operator"
3423 [(reg 24) (const_int 0)])
3429 extern int arm_ccfsm_state;
3431 if (arm_ccfsm_state == 2)
3433 arm_ccfsm_state += 2;
3436 return output_return_instruction (operands[0], TRUE);
3438 [(set_attr "conds" "use")
3439 (set_attr "type" "load")])
3443 (if_then_else (match_operator 0 "comparison_operator"
3444 [(reg 24) (const_int 0)])
3450 extern int arm_ccfsm_state;
3452 if (arm_ccfsm_state == 2)
3454 arm_ccfsm_state += 2;
3457 return output_return_instruction
3458 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3459 GET_MODE (operands[0]), XEXP (operands[0], 0),
3460 XEXP (operands[0], 1)),
3463 [(set_attr "conds" "use")
3464 (set_attr "type" "load")])
3466 ;; Call subroutine returning any type.
3468 (define_expand "untyped_call"
3469 [(parallel [(call (match_operand 0 "" "")
3471 (match_operand 1 "" "")
3472 (match_operand 2 "" "")])]
3478 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3480 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3482 rtx set = XVECEXP (operands[2], 0, i);
3483 emit_move_insn (SET_DEST (set), SET_SRC (set));
3486 /* The optimizer does not know that the call sets the function value
3487 registers we stored in the result block. We avoid problems by
3488 claiming that all hard registers are used and clobbered at this
3490 emit_insn (gen_blockage ());
3495 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3496 ;; all of memory. This blocks insns from being moved across this point.
3498 (define_insn "blockage"
3499 [(unspec_volatile [(const_int 0)] 0)]
3502 [(set_attr "length" "0")
3503 (set_attr "type" "block")])
3505 (define_insn "tablejump"
3507 (match_operand:SI 0 "s_register_operand" "r"))
3508 (use (label_ref (match_operand 1 "" "")))]
3510 "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
3514 (match_operand:SI 0 "memory_operand" "m"))
3515 (use (label_ref (match_operand 1 "" "")))]
3517 "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
3518 [(set_attr "type" "load")])
3520 (define_insn "indirect_jump"
3522 (match_operand:SI 0 "s_register_operand" "r"))]
3524 "mov%?\\t%|pc, %0\\t%@ indirect jump")
3528 (match_operand:SI 0 "memory_operand" "m"))]
3530 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3531 [(set_attr "type" "load")])
3538 "mov%?\\tr0, r0\\t%@ nop")
3540 ;; Patterns to allow combination of arithmetic, cond code and shifts
3543 [(set (match_operand:SI 0 "s_register_operand" "=r")
3544 (match_operator:SI 1 "shiftable_operator"
3545 [(match_operator:SI 3 "shift_operator"
3546 [(match_operand:SI 4 "s_register_operand" "r")
3547 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3548 (match_operand:SI 2 "s_register_operand" "r")]))]
3550 "%i1%?\\t%0, %2, %4%S3")
3553 [(set (reg:CC_NOOV 24)
3554 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3555 [(match_operator:SI 3 "shift_operator"
3556 [(match_operand:SI 4 "s_register_operand" "r")
3557 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3558 (match_operand:SI 2 "s_register_operand" "r")])
3560 (set (match_operand:SI 0 "s_register_operand" "=r")
3561 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3564 "%i1%?s\\t%0, %2, %4%S3"
3565 [(set_attr "conds" "set")])
3568 [(set (reg:CC_NOOV 24)
3569 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3570 [(match_operator:SI 3 "shift_operator"
3571 [(match_operand:SI 4 "s_register_operand" "r")
3572 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3573 (match_operand:SI 2 "s_register_operand" "r")])
3575 (clobber (match_scratch:SI 0 "=r"))]
3577 "%i1%?s\\t%0, %2, %4%S3"
3578 [(set_attr "conds" "set")])
3581 [(set (match_operand:SI 0 "s_register_operand" "=r")
3582 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3583 (match_operator:SI 2 "shift_operator"
3584 [(match_operand:SI 3 "s_register_operand" "r")
3585 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
3587 "sub%?\\t%0, %1, %3%S2")
3590 [(set (reg:CC_NOOV 24)
3592 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3593 (match_operator:SI 2 "shift_operator"
3594 [(match_operand:SI 3 "s_register_operand" "r")
3595 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3597 (set (match_operand:SI 0 "s_register_operand" "=r")
3598 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3601 "sub%?s\\t%0, %1, %3%S2"
3602 [(set_attr "conds" "set")])
3605 [(set (reg:CC_NOOV 24)
3607 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3608 (match_operator:SI 2 "shift_operator"
3609 [(match_operand:SI 3 "s_register_operand" "r")
3610 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3612 (clobber (match_scratch:SI 0 "=r"))]
3614 "sub%?s\\t%0, %1, %3%S2"
3615 [(set_attr "conds" "set")])
3617 ;; These variants of the above insns can occur if the first operand is the
3618 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3619 ;; seem to be a way around it. Most of the predicates have to be null
3620 ;; because the format can be generated part way through reload, so
3621 ;; if we don't match it as soon as it becomes available, reload doesn't know
3622 ;; how to reload pseudos that haven't got hard registers; the constraints will
3623 ;; sort everything out.
3626 [(set (match_operand:SI 0 "" "=&r")
3627 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3628 [(match_operand:SI 3 "" "r")
3629 (match_operand:SI 4 "" "rM")])
3630 (match_operand:SI 2 "" "r"))
3631 (match_operand:SI 1 "const_int_operand" "n")))]
3632 "reload_in_progress"
3634 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
3635 operands[2] = operands[1];
3636 operands[1] = operands[0];
3637 return output_add_immediate (operands);
3639 ; we have no idea how long the add_immediate is, it could be up to 4.
3640 [(set_attr "length" "20")])
3643 [(set (reg:CC_NOOV 24)
3644 (compare:CC_NOOV (plus:SI
3646 (match_operator:SI 5 "shift_operator"
3647 [(match_operand:SI 3 "" "r")
3648 (match_operand:SI 4 "" "rM")])
3649 (match_operand:SI 1 "" "r"))
3650 (match_operand:SI 2 "const_int_operand" "n"))
3652 (set (match_operand:SI 0 "" "=&r")
3653 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3656 "reload_in_progress"
3658 output_add_immediate (operands);
3659 return \"add%?s\\t%0, %0, %3%S5\";
3661 [(set_attr "conds" "set")
3662 (set_attr "length" "20")])
3665 [(set (reg:CC_NOOV 24)
3666 (compare:CC_NOOV (plus:SI
3668 (match_operator:SI 5 "shift_operator"
3669 [(match_operand:SI 3 "" "r")
3670 (match_operand:SI 4 "" "rM")])
3671 (match_operand:SI 1 "" "r"))
3672 (match_operand:SI 2 "const_int_operand" "n"))
3674 (clobber (match_scratch:SI 0 "=&r"))]
3675 "reload_in_progress"
3677 output_add_immediate (operands);
3678 return \"add%?s\\t%0, %0, %3%S5\";
3680 [(set_attr "conds" "set")
3681 (set_attr "length" "20")])
3683 ;; These are similar, but are needed when the mla pattern contains the
3684 ;; eliminated register as operand 3.
3687 [(set (match_operand:SI 0 "" "=&r,&r")
3688 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3689 (match_operand:SI 2 "" "r,r"))
3690 (match_operand:SI 3 "" "r,r"))
3691 (match_operand:SI 4 "const_int_operand" "n,n")))]
3692 "reload_in_progress"
3694 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3695 operands[2] = operands[4];
3696 operands[1] = operands[0];
3697 return output_add_immediate (operands);
3699 [(set_attr "length" "20")])
3702 [(set (reg:CC_NOOV 24)
3703 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3704 (match_operand:SI 3 "" "r")
3705 (match_operand:SI 4 "" "r"))
3706 (match_operand:SI 1 "" "r"))
3707 (match_operand:SI 2 "const_int_operand" "n"))
3709 (set (match_operand:SI 0 "" "=&r")
3710 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3712 "reload_in_progress"
3714 output_add_immediate (operands);
3715 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3718 [(set_attr "length" "20")
3719 (set_attr "conds" "set")])
3722 [(set (reg:CC_NOOV 24)
3723 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3724 (match_operand:SI 3 "" "r")
3725 (match_operand:SI 4 "" "r"))
3726 (match_operand:SI 1 "" "r"))
3727 (match_operand:SI 2 "const_int_operand" "n"))
3729 (clobber (match_scratch:SI 0 "=&r"))]
3730 "reload_in_progress"
3732 output_add_immediate (operands);
3733 return \"mla%?s\\t%0, %3, %4, %0\";
3735 [(set_attr "length" "20")
3736 (set_attr "conds" "set")])
3742 [(set (match_operand:SI 0 "s_register_operand" "=r")
3743 (and:SI (match_operator 1 "comparison_operator"
3744 [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
3745 (match_operand:SI 2 "s_register_operand" "r")))]
3747 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3748 [(set_attr "conds" "use")
3749 (set_attr "length" "8")])
3752 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3753 (ior:SI (match_operator 2 "comparison_operator"
3754 [(reg 24) (const_int 0)])
3755 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3759 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3760 [(set_attr "conds" "use")
3761 (set_attr "length" "4,8")])
3764 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3765 (match_operator 1 "comparison_operator"
3766 [(match_operand:SI 2 "s_register_operand" "r,r")
3767 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
3771 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3772 return \"mov\\t%0, %2, lsr #31\";
3774 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3775 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3777 if (GET_CODE (operands[1]) == NE)
3779 if (which_alternative == 1)
3780 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3781 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3783 if (which_alternative == 1)
3784 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3786 output_asm_insn (\"cmp\\t%2, %3\", operands);
3787 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3789 [(set_attr "conds" "clob")
3790 (set_attr "length" "12")])
3793 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3794 (ior:SI (match_operator 1 "comparison_operator"
3795 [(match_operand:SI 2 "s_register_operand" "r")
3796 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3797 (match_operator 4 "comparison_operator"
3798 [(match_operand:SI 5 "s_register_operand" "r")
3799 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3804 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3805 GET_CODE (operands[1]));
3807 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3809 output_asm_insn (\"mov\\t%0, #0\", operands);
3810 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3811 || comparison_dominates_p (GET_CODE (operands[1]),
3812 GET_CODE (operands[4]))
3814 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3817 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3818 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3821 [(set_attr "conds" "clob")
3823 (set_attr "length" "20")])
3828 (match_operator 5 "equality_operator"
3829 [(ior:SI (match_operator 6 "comparison_operator"
3830 [(match_operand:SI 0 "s_register_operand" "")
3831 (match_operand:SI 1 "arm_add_operand" "")])
3832 (match_operator 7 "comparison_operator"
3833 [(match_operand:SI 2 "s_register_operand" "")
3834 (match_operand:SI 3 "arm_add_operand" "")]))
3836 (label_ref (match_operand 4 "" ""))
3839 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3840 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3841 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3843 (compare:CC (ior:CC (match_op_dup 6
3844 [(match_dup 0) (match_dup 1)])
3846 [(match_dup 2) (match_dup 3)]))
3849 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3850 (label_ref (match_dup 4))
3854 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3855 GET_CODE (operands[7]))
3856 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3858 if (GET_CODE (operands[5]) == NE)
3859 operands[5] = gen_rtx (code, CCmode,
3860 XEXP (operands[5], 0), XEXP (operands[5], 1));
3862 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3863 XEXP (operands[5], 0), XEXP (operands[5], 1));
3867 ;; Don't match these patterns if we can use a conditional compare, since they
3868 ;; tell the final prescan branch elimator code that full branch inlining
3874 (ne (ior:SI (match_operator 5 "comparison_operator"
3875 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3876 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3877 (match_operator 6 "comparison_operator"
3878 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3879 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
3881 (label_ref (match_operand 4 "" ""))
3884 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3885 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3886 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3889 extern int arm_ccfsm_state;
3891 if (which_alternative & 1)
3892 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
3894 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
3896 if (which_alternative >= 2)
3897 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3899 output_asm_insn (\"cmp\\t%2, %3\", operands);
3901 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3903 arm_ccfsm_state += 2;
3906 return \"b%d6\\t%l4\";
3908 [(set_attr "conds" "jump_clob")
3909 (set_attr "length" "16")])
3914 (ior:CC (match_operator 4 "comparison_operator"
3915 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3916 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3917 (match_operator 5 "comparison_operator"
3918 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3919 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
3921 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3922 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3923 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3925 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3927 if (which_alternative >= 2)
3928 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3930 output_asm_insn (\"cmp\\t%2, %3\", operands);
3932 if (which_alternative & 1)
3933 return \"cmn%D5\\t%0, #%n1\";
3934 return \"cmp%D5\\t%0, %1\";
3937 if (which_alternative & 1)
3938 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3940 output_asm_insn (\"cmp\\t%0, %1\", operands);
3942 if (which_alternative >= 2)
3943 return \"cmn%D4\\t%2, #%n3\";
3944 return \"cmp%D4\\t%2, %3\";
3946 [(set_attr "conds" "set")
3947 (set_attr "length" "8")])
3950 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3951 (if_then_else (match_operator 3 "equality_operator"
3952 [(match_operator 4 "comparison_operator"
3953 [(reg 24) (const_int 0)])
3955 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3956 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3959 if (GET_CODE (operands[3]) == NE)
3961 if (which_alternative != 1)
3962 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3963 if (which_alternative != 0)
3964 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3967 if (which_alternative != 0)
3968 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3969 if (which_alternative != 1)
3970 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
3973 [(set_attr "conds" "use")
3974 (set_attr "length" "4,4,8")])
3977 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3978 (match_operator:SI 5 "shiftable_operator"
3979 [(match_operator:SI 4 "comparison_operator"
3980 [(match_operand:SI 2 "s_register_operand" "r,r")
3981 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3982 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3986 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
3987 return \"%i5\\t%0, %1, %2, lsr #31\";
3989 output_asm_insn (\"cmp\\t%2, %3\", operands);
3990 if (GET_CODE (operands[5]) == AND)
3991 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
3992 else if (which_alternative != 0)
3993 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3994 return \"%i5%d4\\t%0, %1, #1\";
3996 [(set_attr "conds" "clob")
3997 (set_attr "length" "12")])
4000 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4001 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4002 (match_operator:SI 4 "comparison_operator"
4003 [(match_operand:SI 2 "s_register_operand" "r,r")
4004 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4008 output_asm_insn (\"cmp\\t%2, %3\", operands);
4009 if (which_alternative != 0)
4010 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4011 return \"sub%d4\\t%0, %1, #1\";
4013 [(set_attr "conds" "clob")
4014 (set_attr "length" "8,12")])
4017 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4018 (and:SI (match_operator 1 "comparison_operator"
4019 [(match_operand:SI 2 "s_register_operand" "r")
4020 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4021 (match_operator 4 "comparison_operator"
4022 [(match_operand:SI 5 "s_register_operand" "r")
4023 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4029 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4030 reverse_condition (GET_CODE (operands[4])))
4032 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4033 reverse_condition (GET_CODE (operands[1])))
4035 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4037 output_asm_insn (\"mov\\t%0, #1\", operands);
4038 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4040 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
4041 : \"cmp%d1\\t%5, %6\", operands);
4045 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4046 output_asm_insn (\"cmp\\t%5, %6\", operands);
4048 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
4051 [(set_attr "conds" "clob")
4052 (set_attr "length" "20")])
4056 (if_then_else (match_operator 1 "equality_operator"
4057 [(and:SI (match_operator 2 "comparison_operator"
4058 [(match_operand:SI 3 "s_register_operand" "")
4059 (match_operand:SI 4 "arm_add_operand" "")])
4060 (match_operator 0 "comparison_operator"
4061 [(match_operand:SI 5 "s_register_operand" "")
4062 (match_operand:SI 6 "arm_add_operand" "")]))
4064 (label_ref (match_operand 7 "" ""))
4067 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4068 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4069 reverse_condition (GET_CODE (operands[0])))
4070 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4071 reverse_condition (GET_CODE (operands[2]))))"
4073 (compare:CC (ior:CC (match_op_dup 2
4074 [(match_dup 3) (match_dup 4)])
4076 [(match_dup 5) (match_dup 6)]))
4079 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4080 (label_ref (match_dup 7))
4084 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4085 This is safe since we only do it for integer comparisons. */
4086 enum rtx_code code =
4087 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4088 reverse_condition (GET_CODE (operands[0])))
4089 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4091 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4092 GET_MODE (operands[2]), operands[3], operands[4]);
4093 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4094 GET_MODE (operands[0]), operands[5], operands[6]);
4095 if (GET_CODE (operands[1]) == NE)
4096 operands[1] = gen_rtx (code, CCmode,
4097 XEXP (operands[1], 0), XEXP (operands[1], 1));
4099 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4100 XEXP (operands[1], 0), XEXP (operands[1], 1));
4104 ;; Don't match these patterns if we can use a conditional compare, since they
4105 ;; tell the final prescan branch elimator code that full branch inlining
4111 (eq (and:SI (match_operator 1 "comparison_operator"
4112 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4113 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4114 (match_operator 4 "comparison_operator"
4115 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4116 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4118 (label_ref (match_operand 0 "" ""))
4121 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4122 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4123 reverse_condition (GET_CODE (operands[4])))
4124 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4125 reverse_condition (GET_CODE (operands[1]))))"
4128 extern int arm_ccfsm_state;
4130 if (which_alternative & 1)
4131 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
4133 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4135 if (which_alternative >= 2)
4136 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4138 output_asm_insn (\"cmp\\t%5, %6\", operands);
4140 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4142 arm_ccfsm_state += 2;
4145 return \"b%D4\\t%l0\";
4147 [(set_attr "conds" "jump_clob")
4148 (set_attr "length" "16")])
4151 [(set (match_operand:SI 0 "s_register_operand" "=r")
4152 (neg:SI (match_operator 3 "comparison_operator"
4153 [(match_operand:SI 1 "s_register_operand" "r")
4154 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4158 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4159 return \"mov\\t%0, %1, asr #31\";
4161 if (GET_CODE (operands[3]) == NE)
4162 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4164 if (GET_CODE (operands[3]) == GT)
4165 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4167 output_asm_insn (\"cmp\\t%1, %2\", operands);
4168 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4169 return \"mvn%d3\\t%0, #0\";
4171 [(set_attr "conds" "clob")
4172 (set_attr "length" "12")])
4174 (define_insn "movcond"
4175 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4177 (match_operator 5 "comparison_operator"
4178 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4179 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4180 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4181 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4185 if (GET_CODE (operands[5]) == LT
4186 && (operands[4] == const0_rtx))
4188 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4190 if (operands[2] == const0_rtx)
4191 return \"and\\t%0, %1, %3, asr #31\";
4192 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4194 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4196 if (operands[1] == const0_rtx)
4197 return \"bic\\t%0, %2, %3, asr #31\";
4198 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4200 /* The only case that falls through to here is when both ops 1 & 2
4204 if (GET_CODE (operands[5]) == GE
4205 && (operands[4] == const0_rtx))
4207 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4209 if (operands[2] == const0_rtx)
4210 return \"bic\\t%0, %1, %3, asr #31\";
4211 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4213 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4215 if (operands[1] == const0_rtx)
4216 return \"and\\t%0, %2, %3, asr #31\";
4217 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4219 /* The only case that falls through to here is when both ops 1 & 2
4222 if (GET_CODE (operands[4]) == CONST_INT
4223 && !const_ok_for_arm (INTVAL (operands[4])))
4224 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4226 output_asm_insn (\"cmp\\t%3, %4\", operands);
4227 if (which_alternative != 0)
4228 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4229 if (which_alternative != 1)
4230 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4233 [(set_attr "conds" "clob")
4234 (set_attr "length" "8,8,12")])
4237 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4238 (if_then_else:SI (match_operator 9 "comparison_operator"
4239 [(match_operand:SI 5 "s_register_operand" "r,r")
4240 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4241 (match_operator:SI 8 "shiftable_operator"
4242 [(match_operand:SI 1 "s_register_operand" "r,r")
4243 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4244 (match_operator:SI 7 "shiftable_operator"
4245 [(match_operand:SI 3 "s_register_operand" "r,r")
4246 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4250 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4251 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4252 [(set_attr "conds" "clob")
4253 (set_attr "length" "12")])
4256 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4257 (if_then_else:SI (match_operator 6 "comparison_operator"
4258 [(match_operand:SI 2 "s_register_operand" "r,r")
4259 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4260 (match_operator:SI 7 "shiftable_operator"
4261 [(match_operand:SI 4 "s_register_operand" "r,r")
4262 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4263 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4267 /* If we have an operation where (op x 0) is the identity operation and
4268 the condtional operator is LT or GE and we are comparing against zero and
4269 everything is in registers then we can do this in two instructions */
4270 if (operands[3] == const0_rtx
4271 && GET_CODE (operands[7]) != AND
4272 && GET_CODE (operands[5]) == REG
4273 && GET_CODE (operands[1]) == REG
4274 && REGNO (operands[1]) == REGNO (operands[4])
4275 && REGNO (operands[4]) != REGNO (operands[0]))
4277 if (GET_CODE (operands[6]) == LT)
4278 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4279 else if (GET_CODE (operands[6]) == GE)
4280 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4282 if (GET_CODE (operands[3]) == CONST_INT
4283 && !const_ok_for_arm (INTVAL (operands[3])))
4284 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4286 output_asm_insn (\"cmp\\t%2, %3\", operands);
4287 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4288 if (which_alternative != 0)
4290 if (GET_CODE (operands[1]) == MEM)
4291 return \"ldr%D6\\t%0, %1\";
4293 return \"mov%D6\\t%0, %1\";
4297 [(set_attr "conds" "clob")
4298 (set_attr "length" "8,12")])
4301 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4302 (if_then_else:SI (match_operator 6 "comparison_operator"
4303 [(match_operand:SI 4 "s_register_operand" "r,r")
4304 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4305 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4306 (match_operator:SI 7 "shiftable_operator"
4307 [(match_operand:SI 2 "s_register_operand" "r,r")
4308 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4312 /* If we have an operation where (op x 0) is the identity operation and
4313 the condtional operator is LT or GE and we are comparing against zero and
4314 everything is in registers then we can do this in two instructions */
4315 if (operands[5] == const0_rtx
4316 && GET_CODE (operands[7]) != AND
4317 && GET_CODE (operands[3]) == REG
4318 && GET_CODE (operands[1]) == REG
4319 && REGNO (operands[1]) == REGNO (operands[2])
4320 && REGNO (operands[2]) != REGNO (operands[0]))
4322 if (GET_CODE (operands[6]) == GE)
4323 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4324 else if (GET_CODE (operands[6]) == LT)
4325 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4328 if (GET_CODE (operands[5]) == CONST_INT
4329 && !const_ok_for_arm (INTVAL (operands[5])))
4330 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4332 output_asm_insn (\"cmp\\t%4, %5\", operands);
4334 if (which_alternative != 0)
4336 if (GET_CODE (operands[1]) == MEM)
4337 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4339 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4341 return \"%I7%D6\\t%0, %2, %3\";
4343 [(set_attr "conds" "clob")
4344 (set_attr "length" "8,12")])
4347 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4348 (if_then_else:SI (match_operator 6 "comparison_operator"
4349 [(match_operand:SI 4 "s_register_operand" "r,r")
4350 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4352 (match_operand:SI 2 "s_register_operand" "r,r")
4353 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4354 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4359 if (GET_CODE (operands[5]) == CONST_INT
4360 && !const_ok_for_arm (INTVAL (operands[5])))
4361 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4363 output_asm_insn (\"cmp\\t%4, %5\", operands);
4364 if (GET_CODE (operands[3]) == CONST_INT
4365 && !const_ok_for_arm (INTVAL (operands[3])))
4366 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4368 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4369 if (which_alternative != 0)
4371 if (GET_CODE (operands[1]) == MEM)
4372 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4374 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4379 [(set_attr "conds" "clob")
4380 (set_attr "length" "8,12")])
4383 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4384 (if_then_else:SI (match_operator 6 "comparison_operator"
4385 [(match_operand:SI 4 "s_register_operand" "r,r")
4386 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4387 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4389 (match_operand:SI 2 "s_register_operand" "r,r")
4390 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4395 if (GET_CODE (operands[5]) == CONST_INT
4396 && !const_ok_for_arm (INTVAL (operands[5])))
4397 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4399 output_asm_insn (\"cmp\\t%4, %5\", operands);
4400 if (GET_CODE (operands[3]) == CONST_INT
4401 && !const_ok_for_arm (INTVAL (operands[3])))
4402 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4404 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4405 if (which_alternative != 0)
4407 if (GET_CODE (operands[6]) == MEM)
4408 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4410 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4415 [(set_attr "conds" "clob")
4416 (set_attr "length" "8,12")])
4419 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4420 (if_then_else:SI (match_operator 5 "comparison_operator"
4421 [(match_operand:SI 3 "s_register_operand" "r,r")
4422 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4423 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4425 (match_operand:SI 2 "s_register_operand" "r,r"))))
4429 [(set_attr "conds" "clob")
4430 (set_attr "length" "8,12")])
4433 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4435 (match_operator 5 "comparison_operator"
4436 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4437 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4439 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4440 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4444 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4445 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4446 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4447 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4448 [(set_attr "conds" "clob")
4449 (set_attr "length" "8,8,12,12")])
4452 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4454 (match_operator 6 "comparison_operator"
4455 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4456 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4457 (match_operator:SI 7 "shift_operator"
4458 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4459 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4460 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4464 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4465 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4466 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4467 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4468 [(set_attr "conds" "clob")
4469 (set_attr "length" "8,8,12,12")])
4472 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4474 (match_operator 6 "comparison_operator"
4475 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4476 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4477 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4478 (match_operator:SI 7 "shift_operator"
4479 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4480 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4484 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4485 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4486 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4487 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4488 [(set_attr "conds" "clob")
4489 (set_attr "length" "8,8,12,12")])
4492 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4494 (match_operator 7 "comparison_operator"
4495 [(match_operand:SI 5 "s_register_operand" "r,r")
4496 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4497 (match_operator:SI 8 "shift_operator"
4498 [(match_operand:SI 1 "s_register_operand" "r,r")
4499 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4500 (match_operator:SI 9 "shift_operator"
4501 [(match_operand:SI 3 "s_register_operand" "r,r")
4502 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4506 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4507 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4508 [(set_attr "conds" "clob")
4509 (set_attr "length" "12")])
4512 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4514 (match_operator 6 "comparison_operator"
4515 [(match_operand:SI 4 "s_register_operand" "r,r")
4516 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4517 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4518 (match_operator:SI 7 "shiftable_operator"
4519 [(match_operand:SI 2 "s_register_operand" "r,r")
4520 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4524 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4525 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4526 [(set_attr "conds" "clob")
4527 (set_attr "length" "12")])
4530 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4532 (match_operator 6 "comparison_operator"
4533 [(match_operand:SI 4 "s_register_operand" "r,r")
4534 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4535 (match_operator:SI 7 "shiftable_operator"
4536 [(match_operand:SI 2 "s_register_operand" "r,r")
4537 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4538 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4542 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4543 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4544 [(set_attr "conds" "clob")
4545 (set_attr "length" "12")])
4548 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4550 (match_operator 5 "comparison_operator"
4551 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4552 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4553 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4554 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4555 (clobber (reg:CC 24))]
4558 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4559 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4560 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4561 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4562 [(set_attr "conds" "clob")
4563 (set_attr "length" "8,8,12,12")])
4566 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4568 (match_operator 5 "comparison_operator"
4569 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4570 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4571 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4572 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4573 (clobber (reg:CC 24))]
4576 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4577 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4578 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4579 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4580 [(set_attr "conds" "clob")
4581 (set_attr "length" "8,8,12,12")])
4584 [(set (match_operand:SI 0 "s_register_operand" "=r")
4585 (match_operator:SI 1 "shiftable_operator"
4586 [(match_operand:SI 2 "memory_operand" "m")
4587 (match_operand:SI 3 "memory_operand" "m")]))
4588 (clobber (match_scratch:SI 4 "=r"))]
4589 "adjacent_mem_locations (operands[2], operands[3])"
4594 int val1 = 0, val2 = 0;
4596 if (REGNO (operands[0]) > REGNO (operands[4]))
4598 ldm[1] = operands[4];
4599 ldm[2] = operands[0];
4603 ldm[1] = operands[0];
4604 ldm[2] = operands[4];
4606 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4607 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4608 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4609 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4610 arith[0] = operands[0];
4611 arith[3] = operands[1];
4625 ldm[0] = ops[0] = operands[4];
4626 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4627 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4628 output_add_immediate (ops);
4630 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4632 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4636 ldm[0] = XEXP (operands[3], 0);
4638 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4640 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4644 ldm[0] = XEXP (operands[2], 0);
4646 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4648 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4650 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4654 [(set_attr "length" "12")
4655 (set_attr "type" "load")])
4657 ;; the arm can support extended pre-inc instructions
4659 ;; In all these cases, we use operands 0 and 1 for the register being
4660 ;; incremented because those are the operands that local-alloc will
4661 ;; tie and these are the pair most likely to be tieable (and the ones
4662 ;; that will benefit the most).
4664 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4665 ;; elimination will cause too many headaches.
4668 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4669 (match_operand:SI 2 "index_operand" "rJ")))
4670 (match_operand:QI 3 "s_register_operand" "r"))
4671 (set (match_operand:SI 0 "s_register_operand" "=r")
4672 (plus:SI (match_dup 1) (match_dup 2)))]
4673 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4674 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4675 && (GET_CODE (operands[2]) != REG
4676 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4677 "str%?b\\t%3, [%0, %2]!"
4678 [(set_attr "type" "store1")])
4681 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4682 (match_operand:SI 2 "s_register_operand" "r")))
4683 (match_operand:QI 3 "s_register_operand" "r"))
4684 (set (match_operand:SI 0 "s_register_operand" "=r")
4685 (minus:SI (match_dup 1) (match_dup 2)))]
4686 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4687 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4688 && (GET_CODE (operands[2]) != REG
4689 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4690 "str%?b\\t%3, [%0, -%2]!"
4691 [(set_attr "type" "store1")])
4694 [(set (match_operand:QI 3 "s_register_operand" "=r")
4695 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4696 (match_operand:SI 2 "index_operand" "rJ"))))
4697 (set (match_operand:SI 0 "s_register_operand" "=r")
4698 (plus:SI (match_dup 1) (match_dup 2)))]
4699 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4700 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4701 && (GET_CODE (operands[2]) != REG
4702 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4703 "ldr%?b\\t%3, [%0, %2]!"
4704 [(set_attr "type" "load")])
4707 [(set (match_operand:QI 3 "s_register_operand" "=r")
4708 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4709 (match_operand:SI 2 "s_register_operand" "r"))))
4710 (set (match_operand:SI 0 "s_register_operand" "=r")
4711 (minus:SI (match_dup 1) (match_dup 2)))]
4712 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4713 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4714 && (GET_CODE (operands[2]) != REG
4715 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4716 "ldr%?b\\t%3, [%0, -%2]!"
4717 [(set_attr "type" "load")])
4720 [(set (match_operand:SI 3 "s_register_operand" "=r")
4722 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4723 (match_operand:SI 2 "index_operand" "rJ")))))
4724 (set (match_operand:SI 0 "s_register_operand" "=r")
4725 (plus:SI (match_dup 1) (match_dup 2)))]
4726 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4727 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4728 && (GET_CODE (operands[2]) != REG
4729 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4730 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4731 [(set_attr "type" "load")])
4734 [(set (match_operand:SI 3 "s_register_operand" "=r")
4736 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4737 (match_operand:SI 2 "s_register_operand" "r")))))
4738 (set (match_operand:SI 0 "s_register_operand" "=r")
4739 (minus:SI (match_dup 1) (match_dup 2)))]
4740 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4741 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4742 && (GET_CODE (operands[2]) != REG
4743 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4744 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4745 [(set_attr "type" "load")])
4748 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4749 (match_operand:SI 2 "index_operand" "rJ")))
4750 (match_operand:SI 3 "s_register_operand" "r"))
4751 (set (match_operand:SI 0 "s_register_operand" "=r")
4752 (plus:SI (match_dup 1) (match_dup 2)))]
4753 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4754 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4755 && (GET_CODE (operands[2]) != REG
4756 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4757 "str%?\\t%3, [%0, %2]!"
4758 [(set_attr "type" "store1")])
4761 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4762 (match_operand:SI 2 "s_register_operand" "r")))
4763 (match_operand:SI 3 "s_register_operand" "r"))
4764 (set (match_operand:SI 0 "s_register_operand" "=r")
4765 (minus:SI (match_dup 1) (match_dup 2)))]
4766 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4767 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4768 && (GET_CODE (operands[2]) != REG
4769 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4770 "str%?\\t%3, [%0, -%2]!"
4771 [(set_attr "type" "store1")])
4774 [(set (match_operand:SI 3 "s_register_operand" "=r")
4775 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4776 (match_operand:SI 2 "index_operand" "rJ"))))
4777 (set (match_operand:SI 0 "s_register_operand" "=r")
4778 (plus:SI (match_dup 1) (match_dup 2)))]
4779 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4780 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4781 && (GET_CODE (operands[2]) != REG
4782 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4783 "ldr%?\\t%3, [%0, %2]!"
4784 [(set_attr "type" "load")])
4787 [(set (match_operand:SI 3 "s_register_operand" "=r")
4788 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4789 (match_operand:SI 2 "s_register_operand" "r"))))
4790 (set (match_operand:SI 0 "s_register_operand" "=r")
4791 (minus:SI (match_dup 1) (match_dup 2)))]
4792 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4793 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4794 && (GET_CODE (operands[2]) != REG
4795 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4796 "ldr%?\\t%3, [%0, -%2]!"
4797 [(set_attr "type" "load")])
4800 [(set (match_operand:HI 3 "s_register_operand" "=r")
4801 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4802 (match_operand:SI 2 "index_operand" "rJ"))))
4803 (set (match_operand:SI 0 "s_register_operand" "=r")
4804 (plus:SI (match_dup 1) (match_dup 2)))]
4805 "(! BYTES_BIG_ENDIAN)
4806 && ! TARGET_SHORT_BY_BYTES
4807 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4808 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4809 && (GET_CODE (operands[2]) != REG
4810 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4811 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4812 [(set_attr "type" "load")])
4815 [(set (match_operand:HI 3 "s_register_operand" "=r")
4816 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4817 (match_operand:SI 2 "s_register_operand" "r"))))
4818 (set (match_operand:SI 0 "s_register_operand" "=r")
4819 (minus:SI (match_dup 1) (match_dup 2)))]
4820 "(!BYTES_BIG_ENDIAN)
4821 && ! TARGET_SHORT_BY_BYTES
4822 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4823 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4824 && (GET_CODE (operands[2]) != REG
4825 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4826 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4827 [(set_attr "type" "load")])
4830 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4831 [(match_operand:SI 3 "s_register_operand" "r")
4832 (match_operand:SI 4 "const_shift_operand" "n")])
4833 (match_operand:SI 1 "s_register_operand" "0")))
4834 (match_operand:QI 5 "s_register_operand" "r"))
4835 (set (match_operand:SI 0 "s_register_operand" "=r")
4836 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4838 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4839 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4840 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4841 "str%?b\\t%5, [%0, %3%S2]!"
4842 [(set_attr "type" "store1")])
4845 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4846 (match_operator:SI 2 "shift_operator"
4847 [(match_operand:SI 3 "s_register_operand" "r")
4848 (match_operand:SI 4 "const_shift_operand" "n")])))
4849 (match_operand:QI 5 "s_register_operand" "r"))
4850 (set (match_operand:SI 0 "s_register_operand" "=r")
4851 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4853 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4854 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4855 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4856 "str%?b\\t%5, [%0, -%3%S2]!"
4857 [(set_attr "type" "store1")])
4860 [(set (match_operand:QI 5 "s_register_operand" "=r")
4861 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4862 [(match_operand:SI 3 "s_register_operand" "r")
4863 (match_operand:SI 4 "const_shift_operand" "n")])
4864 (match_operand:SI 1 "s_register_operand" "0"))))
4865 (set (match_operand:SI 0 "s_register_operand" "=r")
4866 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4868 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4869 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4870 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4871 "ldr%?b\\t%5, [%0, %3%S2]!"
4872 [(set_attr "type" "load")])
4875 [(set (match_operand:QI 5 "s_register_operand" "=r")
4876 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4877 (match_operator:SI 2 "shift_operator"
4878 [(match_operand:SI 3 "s_register_operand" "r")
4879 (match_operand:SI 4 "const_shift_operand" "n")]))))
4880 (set (match_operand:SI 0 "s_register_operand" "=r")
4881 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4883 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4884 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4885 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4886 "ldr%?b\\t%5, [%0, -%3%S2]!"
4887 [(set_attr "type" "load")])
4890 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4891 [(match_operand:SI 3 "s_register_operand" "r")
4892 (match_operand:SI 4 "const_shift_operand" "n")])
4893 (match_operand:SI 1 "s_register_operand" "0")))
4894 (match_operand:SI 5 "s_register_operand" "r"))
4895 (set (match_operand:SI 0 "s_register_operand" "=r")
4896 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4898 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4899 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4900 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4901 "str%?\\t%5, [%0, %3%S2]!"
4902 [(set_attr "type" "store1")])
4905 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4906 (match_operator:SI 2 "shift_operator"
4907 [(match_operand:SI 3 "s_register_operand" "r")
4908 (match_operand:SI 4 "const_shift_operand" "n")])))
4909 (match_operand:SI 5 "s_register_operand" "r"))
4910 (set (match_operand:SI 0 "s_register_operand" "=r")
4911 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4913 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4914 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4915 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4916 "str%?\\t%5, [%0, -%3%S2]!"
4917 [(set_attr "type" "store1")])
4920 [(set (match_operand:SI 5 "s_register_operand" "=r")
4921 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4922 [(match_operand:SI 3 "s_register_operand" "r")
4923 (match_operand:SI 4 "const_shift_operand" "n")])
4924 (match_operand:SI 1 "s_register_operand" "0"))))
4925 (set (match_operand:SI 0 "s_register_operand" "=r")
4926 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4928 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4929 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4930 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4931 "ldr%?\\t%5, [%0, %3%S2]!"
4932 [(set_attr "type" "load")])
4935 [(set (match_operand:SI 5 "s_register_operand" "=r")
4936 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4937 (match_operator:SI 2 "shift_operator"
4938 [(match_operand:SI 3 "s_register_operand" "r")
4939 (match_operand:SI 4 "const_shift_operand" "n")]))))
4940 (set (match_operand:SI 0 "s_register_operand" "=r")
4941 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4943 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4944 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4945 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4946 "ldr%?\\t%5, [%0, -%3%S2]!"
4947 [(set_attr "type" "load")])
4950 [(set (match_operand:HI 5 "s_register_operand" "=r")
4951 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
4952 [(match_operand:SI 3 "s_register_operand" "r")
4953 (match_operand:SI 4 "const_shift_operand" "n")])
4954 (match_operand:SI 1 "s_register_operand" "0"))))
4955 (set (match_operand:SI 0 "s_register_operand" "=r")
4956 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4958 "(! BYTES_BIG_ENDIAN)
4959 && ! TARGET_SHORT_BY_BYTES
4960 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4961 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4962 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4963 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
4964 [(set_attr "type" "load")])
4967 [(set (match_operand:HI 5 "s_register_operand" "=r")
4968 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4969 (match_operator:SI 2 "shift_operator"
4970 [(match_operand:SI 3 "s_register_operand" "r")
4971 (match_operand:SI 4 "const_shift_operand" "n")]))))
4972 (set (match_operand:SI 0 "s_register_operand" "=r")
4973 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4975 "(! BYTES_BIG_ENDIAN)
4976 && ! TARGET_SHORT_BY_BYTES
4977 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4978 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4979 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4980 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
4981 [(set_attr "type" "load")])
4983 ; It can also support extended post-inc expressions, but combine doesn't
4985 ; It doesn't seem worth adding peepholes for anything but the most common
4986 ; cases since, unlike combine, the increment must immediately follow the load
4987 ; for this pattern to match.
4988 ; When loading we must watch to see that the base register isn't trampled by
4989 ; the load. In such cases this isn't a post-inc expression.
4992 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
4993 (match_operand:QI 2 "s_register_operand" "r"))
4995 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4997 "str%?b\\t%2, [%0], %1")
5000 [(set (match_operand:QI 0 "s_register_operand" "=r")
5001 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5003 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5004 "REGNO(operands[0]) != REGNO(operands[1])
5005 && (GET_CODE (operands[2]) != REG
5006 || REGNO(operands[0]) != REGNO (operands[2]))"
5007 "ldr%?b\\t%0, [%1], %2")
5010 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5011 (match_operand:SI 2 "s_register_operand" "r"))
5013 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5015 "str%?\\t%2, [%0], %1")
5018 [(set (match_operand:HI 0 "s_register_operand" "=r")
5019 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5021 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5022 "(! BYTES_BIG_ENDIAN)
5023 && ! TARGET_SHORT_BY_BYTES
5024 && REGNO(operands[0]) != REGNO(operands[1])
5025 && (GET_CODE (operands[2]) != REG
5026 || REGNO(operands[0]) != REGNO (operands[2]))"
5027 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5030 [(set (match_operand:SI 0 "s_register_operand" "=r")
5031 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5033 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5034 "REGNO(operands[0]) != REGNO(operands[1])
5035 && (GET_CODE (operands[2]) != REG
5036 || REGNO(operands[0]) != REGNO (operands[2]))"
5037 "ldr%?\\t%0, [%1], %2")
5040 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5041 (match_operand:SI 1 "index_operand" "rJ")))
5042 (match_operand:QI 2 "s_register_operand" "r"))
5043 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5045 "str%?b\\t%2, [%0, %1]!")
5048 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5049 [(match_operand:SI 0 "s_register_operand" "r")
5050 (match_operand:SI 1 "const_int_operand" "n")])
5051 (match_operand:SI 2 "s_register_operand" "+r")))
5052 (match_operand:QI 3 "s_register_operand" "r"))
5053 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5056 "str%?b\\t%3, [%2, %0%S4]!")
5058 ; This pattern is never tried by combine, so do it as a peephole
5061 [(set (match_operand:SI 0 "s_register_operand" "=r")
5062 (match_operand:SI 1 "s_register_operand" "r"))
5063 (set (match_operand 2 "cc_register" "")
5064 (compare (match_dup 1) (const_int 0)))]
5066 "sub%?s\\t%0, %1, #0"
5067 [(set_attr "conds" "set")])
5069 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5070 ; reversed, check that the memory references aren't volatile.
5073 [(set (match_operand:SI 0 "s_register_operand" "=r")
5074 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5076 (set (match_operand:SI 2 "s_register_operand" "=r")
5077 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5078 (set (match_operand:SI 3 "s_register_operand" "=r")
5079 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5080 (set (match_operand:SI 4 "s_register_operand" "=r")
5081 (mem:SI (match_dup 1)))]
5082 "REGNO (operands[0]) > REGNO (operands[2])
5083 && REGNO (operands[2]) > REGNO (operands[3])
5084 && REGNO (operands[3]) > REGNO (operands[4])
5085 && !(REGNO (operands[1]) == REGNO (operands[0])
5086 || REGNO (operands[1]) == REGNO (operands[2])
5087 || REGNO (operands[1]) == REGNO (operands[3])
5088 || REGNO (operands[1]) == REGNO (operands[4]))
5089 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5090 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5091 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5092 (prev_nonnote_insn (insn)))))
5093 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5095 (prev_nonnote_insn (insn))))))"
5096 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5099 [(set (match_operand:SI 0 "s_register_operand" "=r")
5100 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5102 (set (match_operand:SI 2 "s_register_operand" "=r")
5103 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5104 (set (match_operand:SI 3 "s_register_operand" "=r")
5105 (mem:SI (match_dup 1)))]
5106 "REGNO (operands[0]) > REGNO (operands[2])
5107 && REGNO (operands[2]) > REGNO (operands[3])
5108 && !(REGNO (operands[1]) == REGNO (operands[0])
5109 || REGNO (operands[1]) == REGNO (operands[2])
5110 || REGNO (operands[1]) == REGNO (operands[3]))
5111 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5112 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5113 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5114 (prev_nonnote_insn (insn)))))"
5115 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5118 [(set (match_operand:SI 0 "s_register_operand" "=r")
5119 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5121 (set (match_operand:SI 2 "s_register_operand" "=r")
5122 (mem:SI (match_dup 1)))]
5123 "REGNO (operands[0]) > REGNO (operands[2])
5124 && !(REGNO (operands[1]) == REGNO (operands[0])
5125 || REGNO (operands[1]) == REGNO (operands[2]))
5126 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5127 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5128 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5131 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5133 (match_operand:SI 0 "s_register_operand" "r"))
5134 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5135 (match_operand:SI 2 "s_register_operand" "r"))
5136 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5137 (match_operand:SI 3 "s_register_operand" "r"))
5138 (set (mem:SI (match_dup 1))
5139 (match_operand:SI 4 "s_register_operand" "r"))]
5140 "REGNO (operands[0]) > REGNO (operands[2])
5141 && REGNO (operands[2]) > REGNO (operands[3])
5142 && REGNO (operands[3]) > REGNO (operands[4])
5143 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5144 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5145 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5146 (prev_nonnote_insn (insn)))))
5147 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5149 (prev_nonnote_insn (insn))))))"
5150 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5153 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5155 (match_operand:SI 0 "s_register_operand" "r"))
5156 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5157 (match_operand:SI 2 "s_register_operand" "r"))
5158 (set (mem:SI (match_dup 1))
5159 (match_operand:SI 3 "s_register_operand" "r"))]
5160 "REGNO (operands[0]) > REGNO (operands[2])
5161 && REGNO (operands[2]) > REGNO (operands[3])
5162 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5163 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5164 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5165 (prev_nonnote_insn (insn)))))"
5166 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5169 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5171 (match_operand:SI 0 "s_register_operand" "r"))
5172 (set (mem:SI (match_dup 1))
5173 (match_operand:SI 2 "s_register_operand" "r"))]
5174 "REGNO (operands[0]) > REGNO (operands[2])
5175 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5176 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5177 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5179 ;; A call followed by return can be replaced by restoring the regs and
5180 ;; jumping to the subroutine, provided we aren't passing the address of
5181 ;; any of our local variables. If we call alloca then this is unsafe
5182 ;; since restoring the frame frees the memory, which is not what we want.
5183 ;; Sometimes the return might have been targeted by the final prescan:
5184 ;; if so then emit a propper return insn as well.
5185 ;; Unfortunately, if the frame pointer is required, we don't know if the
5186 ;; current function has any implicit stack pointer adjustments that will
5187 ;; be restored by the return: we can't therefore do a tail call.
5188 ;; Another unfortunate that we can't handle is if current_function_args_size
5189 ;; is non-zero: in this case elimination of the argument pointer assumed
5190 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5194 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5195 (match_operand:SI 1 "general_operand" "g"))
5196 (clobber (reg:SI 14))])
5198 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5199 && !get_frame_size () && !current_function_calls_alloca
5200 && !frame_pointer_needed && !current_function_args_size)"
5203 extern rtx arm_target_insn;
5204 extern int arm_ccfsm_state, arm_current_cc;
5206 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5208 arm_current_cc ^= 1;
5209 output_return_instruction (NULL, TRUE);
5210 arm_ccfsm_state = 0;
5211 arm_target_insn = NULL;
5214 output_return_instruction (NULL, FALSE);
5215 return \"b%?\\t%a0\";
5217 [(set (attr "conds")
5218 (if_then_else (eq_attr "cpu" "arm6")
5219 (const_string "clob")
5220 (const_string "nocond")))
5221 (set_attr "length" "8")])
5224 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5225 (call (mem:SI (match_operand:SI 1 "" "i"))
5226 (match_operand:SI 2 "general_operand" "g")))
5227 (clobber (reg:SI 14))])
5229 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5230 && !get_frame_size () && !current_function_calls_alloca
5231 && !frame_pointer_needed && !current_function_args_size)"
5234 extern rtx arm_target_insn;
5235 extern int arm_ccfsm_state, arm_current_cc;
5237 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5239 arm_current_cc ^= 1;
5240 output_return_instruction (NULL, TRUE);
5241 arm_ccfsm_state = 0;
5242 arm_target_insn = NULL;
5245 output_return_instruction (NULL, FALSE);
5246 return \"b%?\\t%a1\";
5248 [(set (attr "conds")
5249 (if_then_else (eq_attr "cpu" "arm6")
5250 (const_string "clob")
5251 (const_string "nocond")))
5252 (set_attr "length" "8")])
5254 ;; As above but when this function is not void, we must be returning the
5255 ;; result of the called subroutine.
5258 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5259 (call (mem:SI (match_operand:SI 1 "" "i"))
5260 (match_operand:SI 2 "general_operand" "g")))
5261 (clobber (reg:SI 14))])
5264 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5265 && !get_frame_size () && !current_function_calls_alloca
5266 && !frame_pointer_needed && !current_function_args_size)"
5269 extern rtx arm_target_insn;
5270 extern int arm_ccfsm_state, arm_current_cc;
5272 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5274 arm_current_cc ^= 1;
5275 output_return_instruction (NULL, TRUE);
5276 arm_ccfsm_state = 0;
5277 arm_target_insn = NULL;
5280 output_return_instruction (NULL, FALSE);
5281 return \"b%?\\t%a1\";
5283 [(set (attr "conds")
5284 (if_then_else (eq_attr "cpu" "arm6")
5285 (const_string "clob")
5286 (const_string "nocond")))
5287 (set_attr "length" "8")])
5289 ;; If calling a subroutine and then jumping back to somewhere else, but not
5290 ;; too far away, then we can set the link register with the branch address
5291 ;; and jump direct to the subroutine. On return from the subroutine
5292 ;; execution continues at the branch; this avoids a prefetch stall.
5293 ;; We use the length attribute (via short_branch ()) to establish whether or
5294 ;; not this is possible, this is the same asthe sparc does.
5297 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5298 (match_operand:SI 1 "general_operand" "g"))
5299 (clobber (reg:SI 14))])
5301 (label_ref (match_operand 2 "" "")))]
5302 "GET_CODE (operands[0]) == SYMBOL_REF
5303 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5304 && arm_insn_not_targeted (insn)"
5307 int backward = arm_backwards_branch (INSN_UID (insn),
5308 INSN_UID (operands[2]));
5311 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5312 * above, leaving it out means that the code will still run on an arm 2 or 3
5317 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5319 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5324 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5326 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5328 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5330 return \"b%?\\t%a0\";
5332 [(set (attr "conds")
5333 (if_then_else (eq_attr "cpu" "arm6")
5334 (const_string "clob")
5335 (const_string "nocond")))
5336 (set (attr "length")
5337 (if_then_else (eq_attr "cpu" "arm6")
5342 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5343 (call (mem:SI (match_operand:SI 1 "" "i"))
5344 (match_operand:SI 2 "general_operand" "g")))
5345 (clobber (reg:SI 14))])
5347 (label_ref (match_operand 3 "" "")))]
5348 "GET_CODE (operands[0]) == SYMBOL_REF
5349 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5350 && arm_insn_not_targeted (insn)"
5353 int backward = arm_backwards_branch (INSN_UID (insn),
5354 INSN_UID (operands[3]));
5357 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5358 * above, leaving it out means that the code will still run on an arm 2 or 3
5363 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5365 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5370 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5372 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5374 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5376 return \"b%?\\t%a1\";
5378 [(set (attr "conds")
5379 (if_then_else (eq_attr "cpu" "arm6")
5380 (const_string "clob")
5381 (const_string "nocond")))
5382 (set (attr "length")
5383 (if_then_else (eq_attr "cpu" "arm6")
5389 (if_then_else (match_operator 0 "comparison_operator"
5390 [(match_operator:SI 1 "shift_operator"
5391 [(match_operand:SI 2 "s_register_operand" "r")
5392 (match_operand:SI 3 "reg_or_int_operand" "rM")])
5393 (match_operand:SI 4 "s_register_operand" "r")])
5394 (label_ref (match_operand 5 "" ""))
5399 (compare:CC (match_dup 4)
5400 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5402 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5403 (label_ref (match_dup 5))
5406 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5407 operands[1], operands[2]);
5411 [(set (match_operand:SI 0 "s_register_operand" "")
5412 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5414 (neg:SI (match_operator:SI 2 "comparison_operator"
5415 [(match_operand:SI 3 "s_register_operand" "")
5416 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5417 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5419 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5420 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5424 ;; This pattern can be used because cc_noov mode implies that the following
5425 ;; branch will be an equality (EQ or NE), so the sign extension is not
5426 ;; needed. Combine doesn't eliminate these because by the time it sees the
5427 ;; branch it no-longer knows that the data came from memory.
5430 [(set (reg:CC_NOOV 24)
5432 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5434 (match_operand 1 "immediate_operand" "I")))
5435 (clobber (match_scratch:SI 2 "=r"))]
5436 "((unsigned long) INTVAL (operands[1]))
5437 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5439 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5440 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5441 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5444 [(set_attr "conds" "set")
5445 (set_attr "length" "8")
5446 (set_attr "type" "load")])
5448 (define_expand "prologue"
5449 [(clobber (const_int 0))]
5452 arm_expand_prologue ();
5456 ;; This split is only used during output to reduce the number of patterns
5457 ;; that need assembler instructions adding to them. We allowed the setting
5458 ;; of the conditions to be implicit during rtl generation so that
5459 ;; the conditional compare patterns would work. However this conflicts to
5460 ;; some extend with the conditional data operations, so we have to split them
5464 [(set (match_operand:SI 0 "s_register_operand" "")
5465 (if_then_else:SI (match_operator 1 "comparison_operator"
5466 [(match_operand 2 "" "") (match_operand 3 "" "")])
5467 (match_operand 4 "" "")
5468 (match_operand 5 "" "")))
5471 [(set (match_dup 6) (match_dup 7))
5473 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5478 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5481 operands[6] = gen_rtx (REG, mode, 24);
5482 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5488 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5489 (if_then_else:SI (match_operator 4 "comparison_operator"
5490 [(match_operand 3 "reversible_cc_register" "")
5492 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5494 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5498 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5499 [(set_attr "conds" "use")
5500 (set_attr "length" "4,8")])
5502 ;; The next two patterns occur when an AND operation is followed by a
5503 ;; scc insn sequence
5506 [(set (match_operand:SI 0 "s_register_operand" "=r")
5507 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5509 (match_operand:SI 2 "immediate_operand" "n")))]
5512 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5513 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5514 return \"mvnne\\t%0, #0\";
5516 [(set_attr "conds" "clob")
5517 (set_attr "length" "8")])
5520 [(set (match_operand:SI 0 "s_register_operand" "=r")
5522 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5524 (match_operand:SI 2 "immediate_operand" "n"))))]
5527 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5528 output_asm_insn (\"tst\\t%1, %2\", operands);
5529 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5530 return \"movne\\t%0, #0\";
5532 [(set_attr "conds" "clob")
5533 (set_attr "length" "12")])
5535 ;; Push multiple registers to the stack. The first register is in the
5536 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5539 [(match_parallel 2 "multi_register_push"
5540 [(set (match_operand:BLK 0 "memory_operand" "=m")
5541 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5547 extern int lr_save_eliminated;
5549 if (lr_save_eliminated)
5551 if (XVECLEN (operands[2], 0) > 1)
5555 strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5556 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5558 strcat (pattern, \", %|\");
5559 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5562 strcat (pattern, \"}\");
5563 output_asm_insn (pattern, operands);
5566 [(set_attr "type" "store4")])