1 ;;- Machine description Acorn RISC Machine 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 RISCiX 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 ; LENGTH of an instruction (in bytes)
70 (define_attr "length" "" (const_int 4))
72 ; An assembler sequence may clobber the condition codes without us knowing
73 (define_asm_attributes
74 [(set_attr "conds" "clob")
75 (set_attr "length" "4")])
77 ; TYPE attribute is used to detect floating point instructions which, if
78 ; running on a co-processor can run in parallel with other, basic instructions
79 ; If write-buffer scheduling is enabled then it can also be used in the
80 ; scheduling of writes.
82 ; Classification of each insn
83 ; normal any data instruction that doesn't hit memory or fp regs
84 ; block blockage insn, this blocks all functional units
85 ; float a floating point arithmetic operation (subject to expansion)
86 ; float_em a floating point arithmetic operation that is normally emulated
87 ; f_load a floating point load from memory
88 ; f_store a floating point store to memory
89 ; f_mem_r a transfer of a floating point register to a real reg via mem
90 ; r_mem_f the reverse of f_mem_r
91 ; f_2_r fast transfer float to arm (no memory needed)
92 ; r_2_f fast transfer arm to float
93 ; call a subroutine call
94 ; load any load from memory
95 ; store1 store 1 word to memory from arm registers
96 ; store2 store 2 words
97 ; store3 store 3 words
98 ; store4 store 4 words
101 "normal,block,float,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
102 (const_string "normal"))
104 (define_attr "write_conflict" "no,yes"
105 (if_then_else (eq_attr "type"
106 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
108 (const_string "no")))
110 ; The write buffer on some of the arm6 processors is hard to model exactly.
111 ; There is room in the buffer for up to two addresses and up to eight words
112 ; of memory, but the two needn't be split evenly. When writing the two
113 ; addresses are fully pipelined. However, a read from memory that is not
114 ; currently in the cache will block until the writes have completed.
115 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
116 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
117 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
118 ; cycle to add as well.
120 ;; (define_function_unit {name} {num-units} {n-users} {test}
121 ;; {ready-delay} {issue-delay} [{conflict-list}])
122 ;; This is not well tuned, but I don't have all the details.
123 (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0)
125 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
126 [(eq_attr "write_conflict" "yes")])
127 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
128 [(eq_attr "write_conflict" "yes")])
129 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
130 [(eq_attr "write_conflict" "yes")])
131 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
132 [(eq_attr "write_conflict" "yes")])
133 (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
134 [(eq_attr "write_conflict" "yes")])
136 ;; Note: For DImode insns, there is normally no reason why operands should
137 ;; not be in the same register, what we don't want is for something being
138 ;; written to partially overlap something that is an input.
142 (define_insn "adddi3"
143 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
144 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
145 (match_operand:DI 2 "s_register_operand" "r,0")))
146 (clobber (reg:CC 24))]
148 "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
149 [(set_attr "conds" "clob")
150 (set_attr "length" "8")])
153 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
154 (plus:DI (sign_extend:DI
155 (match_operand:SI 1 "s_register_operand" "r,r"))
156 (match_operand:DI 2 "s_register_operand" "r,0")))
157 (clobber (reg:CC 24))]
159 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
160 [(set_attr "conds" "clob")
161 (set_attr "length" "8")])
164 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
165 (plus:DI (zero_extend:DI
166 (match_operand:SI 1 "s_register_operand" "r,r"))
167 (match_operand:DI 2 "s_register_operand" "r,0")))
168 (clobber (reg:CC 24))]
170 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
171 [(set_attr "conds" "clob")
172 (set_attr "length" "8")])
174 (define_expand "addsi3"
175 [(set (match_operand:SI 0 "s_register_operand" "")
176 (plus:SI (match_operand:SI 1 "s_register_operand" "")
177 (match_operand:SI 2 "reg_or_int_operand" "")))]
180 if (GET_CODE (operands[2]) == CONST_INT)
182 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
184 (reload_in_progress || reload_completed ? 0
185 : preserve_subexpressions_p ()));
191 [(set (match_operand:SI 0 "s_register_operand" "")
192 (plus:SI (match_operand:SI 1 "s_register_operand" "")
193 (match_operand:SI 2 "const_int_operand" "")))]
194 "! (const_ok_for_arm (INTVAL (operands[2]))
195 || const_ok_for_arm (-INTVAL (operands[2])))"
196 [(clobber (const_int 0))]
198 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
204 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
205 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
206 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
212 [(set_attr "length" "4,4,16")])
215 [(set (reg:CC_NOOV 24)
217 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
218 (match_operand:SI 2 "arm_add_operand" "rI,L"))
220 (set (match_operand:SI 0 "s_register_operand" "=r,r")
221 (plus:SI (match_dup 1) (match_dup 2)))]
225 sub%?s\\t%0, %1, #%n2"
226 [(set_attr "conds" "set")])
230 (compare:CC (match_operand:SI 1 "s_register_operand" "r,r")
231 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
232 (set (match_operand:SI 0 "s_register_operand" "=r,r")
233 (plus:SI (match_dup 1) (match_dup 2)))]
237 sub%?s\\t%0, %1, #%n2"
238 [(set_attr "conds" "set")])
240 (define_insn "incscc"
241 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
242 (plus:SI (match_operator:SI 2 "comparison_operator"
243 [(reg 24) (const_int 0)])
244 (match_operand:SI 1 "s_register_operand" "0,?r")))]
248 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
249 [(set_attr "conds" "use")
250 (set_attr "length" "4,8")])
252 ; If a constant is too big to fit in a single instruction then the constant
253 ; will be pre-loaded into a register taking at least two insns, we might be
254 ; able to merge it with an add, but it depends on the exact value.
257 [(set (match_operand:SI 0 "s_register_operand" "=r")
258 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
259 (match_operand:SI 2 "immediate_operand" "n")))]
260 "!(const_ok_for_arm (INTVAL (operands[2]))
261 || const_ok_for_arm (-INTVAL (operands[2])))"
262 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
263 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
266 unsigned int val = (unsigned) INTVAL (operands[2]);
270 /* this code is similar to the approach followed in movsi, but it must
271 generate exactly two insns */
273 for (i = 30; i >= 0; i -= 2)
279 if (const_ok_for_arm (temp = (val & ~(255 << i))))
284 /* we might be able to do this as (larger number - small number) */
285 temp = ((val >> i) & 255) + 1;
286 if (temp > 255 && i < 24)
289 temp = ((val >> i) & 255) + 1;
291 if (const_ok_for_arm ((temp << i) - val))
294 temp = (unsigned) - (int) (i - val);
301 /* if we got here, we have found a way of doing it in two instructions.
302 the two constants are in val and temp */
303 operands[2] = GEN_INT ((int)val);
304 operands[3] = GEN_INT ((int)temp);
308 (define_insn "addsf3"
309 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
310 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
311 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
315 suf%?s\\t%0, %1, #%N2"
316 [(set_attr "type" "float")])
318 (define_insn "adddf3"
319 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
320 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
321 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
325 suf%?d\\t%0, %1, #%N2"
326 [(set_attr "type" "float")])
329 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
330 (plus:DF (float_extend:DF
331 (match_operand:SF 1 "s_register_operand" "f,f"))
332 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
336 suf%?d\\t%0, %1, #%N2"
337 [(set_attr "type" "float")])
340 [(set (match_operand:DF 0 "s_register_operand" "=f")
341 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
343 (match_operand:SF 2 "s_register_operand" "f"))))]
345 "adf%?d\\t%0, %1, %2"
346 [(set_attr "type" "float")])
349 [(set (match_operand:DF 0 "s_register_operand" "=f")
350 (plus:DF (float_extend:DF
351 (match_operand:SF 1 "s_register_operand" "f"))
353 (match_operand:SF 2 "s_register_operand" "f"))))]
355 "adf%?d\\t%0, %1, %2"
356 [(set_attr "type" "float")])
358 (define_insn "addxf3"
359 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
360 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
361 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
365 suf%?e\\t%0, %1, #%N2"
366 [(set_attr "type" "float")])
368 (define_insn "subdi3"
369 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
370 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
371 (match_operand:DI 2 "s_register_operand" "r,0,0")))
372 (clobber (reg:CC 24))]
374 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
375 [(set_attr "conds" "clob")
376 (set_attr "length" "8")])
379 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
380 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
382 (match_operand:SI 2 "s_register_operand" "r,r"))))
383 (clobber (reg:CC 24))]
385 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
386 [(set_attr "conds" "clob")
387 (set_attr "length" "8")])
390 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
391 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
393 (match_operand:SI 2 "s_register_operand" "r,r"))))
394 (clobber (reg:CC 24))]
396 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
397 [(set_attr "conds" "clob")
398 (set_attr "length" "8")])
401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
402 (minus:DI (zero_extend:DI
403 (match_operand:SI 2 "s_register_operand" "r,r"))
404 (match_operand:DI 1 "s_register_operand" "?r,0")))
405 (clobber (reg:CC 24))]
407 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
408 [(set_attr "conds" "clob")
409 (set_attr "length" "8")])
412 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
413 (minus:DI (sign_extend:DI
414 (match_operand:SI 2 "s_register_operand" "r,r"))
415 (match_operand:DI 1 "s_register_operand" "?r,0")))
416 (clobber (reg:CC 24))]
418 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
419 [(set_attr "conds" "clob")
420 (set_attr "length" "8")])
423 [(set (match_operand:DI 0 "s_register_operand" "=r")
424 (minus:DI (zero_extend:DI
425 (match_operand:SI 1 "s_register_operand" "r"))
427 (match_operand:SI 2 "s_register_operand" "r"))))
428 (clobber (reg:CC 24))]
430 "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
431 [(set_attr "conds" "clob")
432 (set_attr "length" "8")])
434 (define_expand "subsi3"
435 [(set (match_operand:SI 0 "s_register_operand" "")
436 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
437 (match_operand:SI 2 "s_register_operand" "")))]
440 if (GET_CODE (operands[1]) == CONST_INT)
442 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
444 (reload_in_progress || reload_completed ? 0
445 : preserve_subexpressions_p ()));
451 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
452 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
453 (match_operand:SI 2 "s_register_operand" "r,r")))]
458 [(set_attr "length" "4,16")])
461 [(set (match_operand:SI 0 "s_register_operand" "")
462 (minus:SI (match_operand:SI 1 "const_int_operand" "")
463 (match_operand:SI 2 "s_register_operand" "")))]
464 "! const_ok_for_arm (INTVAL (operands[1]))"
465 [(clobber (const_int 0))]
467 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
473 [(set (reg:CC_NOOV 24)
474 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
475 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
477 (set (match_operand:SI 0 "s_register_operand" "=r,r")
478 (minus:SI (match_dup 1) (match_dup 2)))]
483 [(set_attr "conds" "set")])
485 (define_insn "decscc"
486 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
487 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
488 (match_operator:SI 2 "comparison_operator"
489 [(reg 24) (const_int 0)])))]
493 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
494 [(set_attr "conds" "use")
495 (set_attr "length" "*,8")])
497 (define_insn "subsf3"
498 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
499 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
500 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
505 [(set_attr "type" "float")])
507 (define_insn "subdf3"
508 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
509 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
510 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
515 [(set_attr "type" "float")])
518 [(set (match_operand:DF 0 "s_register_operand" "=f")
519 (minus:DF (float_extend:DF
520 (match_operand:SF 1 "s_register_operand" "f"))
521 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
523 "suf%?d\\t%0, %1, %2"
524 [(set_attr "type" "float")])
527 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
528 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
530 (match_operand:SF 2 "s_register_operand" "f,f"))))]
535 [(set_attr "type" "float")])
538 [(set (match_operand:DF 0 "s_register_operand" "=f")
539 (minus:DF (float_extend:DF
540 (match_operand:SF 1 "s_register_operand" "f"))
542 (match_operand:SF 2 "s_register_operand" "f"))))]
544 "suf%?d\\t%0, %1, %2"
545 [(set_attr "type" "float")])
547 (define_insn "subxf3"
548 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
549 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
550 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
555 [(set_attr "type" "float")])
557 ;; Multiplication insns
559 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
560 (define_insn "mulsi3"
561 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
562 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
563 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
565 "mul%?\\t%0, %2, %1")
568 [(set (reg:CC_NOOV 24)
569 (compare:CC_NOOV (mult:SI
570 (match_operand:SI 2 "s_register_operand" "r,r")
571 (match_operand:SI 1 "s_register_operand" "%?r,0"))
573 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
574 (mult:SI (match_dup 2) (match_dup 1)))]
576 "mul%?s\\t%0, %2, %1"
577 [(set_attr "conds" "set")])
580 [(set (reg:CC_NOOV 24)
581 (compare:CC_NOOV (mult:SI
582 (match_operand:SI 2 "s_register_operand" "r,r")
583 (match_operand:SI 1 "s_register_operand" "%?r,0"))
585 (clobber (match_scratch:SI 0 "=&r,&r"))]
587 "mul%?s\\t%0, %2, %1"
588 [(set_attr "conds" "set")])
590 ;; Unnamed templates to match MLA instruction.
593 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
595 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
596 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
597 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
599 "mla%?\\t%0, %2, %1, %3")
602 [(set (reg:CC_NOOV 24)
603 (compare:CC_NOOV (plus:SI
605 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
606 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
607 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
609 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
610 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
613 "mla%?s\\t%0, %2, %1, %3"
614 [(set_attr "conds" "set")])
617 [(set (reg:CC_NOOV 24)
618 (compare:CC_NOOV (plus:SI
620 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
621 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
622 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
624 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
626 "mla%?s\\t%0, %2, %1, %3"
627 [(set_attr "conds" "set")])
629 (define_insn "mulsf3"
630 [(set (match_operand:SF 0 "s_register_operand" "=f")
631 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
632 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
634 "fml%?s\\t%0, %1, %2"
635 [(set_attr "type" "float")])
637 (define_insn "muldf3"
638 [(set (match_operand:DF 0 "s_register_operand" "=f")
639 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
640 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
642 "muf%?d\\t%0, %1, %2"
643 [(set_attr "type" "float")])
646 [(set (match_operand:DF 0 "s_register_operand" "=f")
647 (mult:DF (float_extend:DF
648 (match_operand:SF 1 "s_register_operand" "f"))
649 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
651 "muf%?d\\t%0, %1, %2"
652 [(set_attr "type" "float")])
655 [(set (match_operand:DF 0 "s_register_operand" "=f")
656 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
658 (match_operand:SF 2 "s_register_operand" "f"))))]
660 "muf%?d\\t%0, %1, %2"
661 [(set_attr "type" "float")])
664 [(set (match_operand:DF 0 "s_register_operand" "=f")
665 (mult:DF (float_extend:DF
666 (match_operand:SF 1 "s_register_operand" "f"))
668 (match_operand:SF 2 "s_register_operand" "f"))))]
670 "muf%?d\\t%0, %1, %2"
671 [(set_attr "type" "float")])
673 (define_insn "mulxf3"
674 [(set (match_operand:XF 0 "s_register_operand" "=f")
675 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
676 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
678 "muf%?e\\t%0, %1, %2"
679 [(set_attr "type" "float")])
683 (define_insn "divsf3"
684 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
685 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
686 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
691 [(set_attr "type" "float")])
693 (define_insn "divdf3"
694 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
695 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
696 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
701 [(set_attr "type" "float")])
704 [(set (match_operand:DF 0 "s_register_operand" "=f")
705 (div:DF (float_extend:DF
706 (match_operand:SF 1 "s_register_operand" "f"))
707 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
709 "dvf%?d\\t%0, %1, %2"
710 [(set_attr "type" "float")])
713 [(set (match_operand:DF 0 "s_register_operand" "=f")
714 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
716 (match_operand:SF 2 "s_register_operand" "f"))))]
718 "rdf%?d\\t%0, %2, %1"
719 [(set_attr "type" "float")])
722 [(set (match_operand:DF 0 "s_register_operand" "=f")
723 (div:DF (float_extend:DF
724 (match_operand:SF 1 "s_register_operand" "f"))
726 (match_operand:SF 2 "s_register_operand" "f"))))]
728 "dvf%?d\\t%0, %1, %2"
729 [(set_attr "type" "float")])
731 (define_insn "divxf3"
732 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
733 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
734 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
739 [(set_attr "type" "float")])
743 (define_insn "modsf3"
744 [(set (match_operand:SF 0 "s_register_operand" "=f")
745 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
746 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
748 "rmf%?s\\t%0, %1, %2"
749 [(set_attr "type" "float")])
751 (define_insn "moddf3"
752 [(set (match_operand:DF 0 "s_register_operand" "=f")
753 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
754 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
756 "rmf%?d\\t%0, %1, %2"
757 [(set_attr "type" "float")])
760 [(set (match_operand:DF 0 "s_register_operand" "=f")
761 (mod:DF (float_extend:DF
762 (match_operand:SF 1 "s_register_operand" "f"))
763 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
765 "rmf%?d\\t%0, %1, %2"
766 [(set_attr "type" "float")])
769 [(set (match_operand:DF 0 "s_register_operand" "=f")
770 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
772 (match_operand:SF 2 "s_register_operand" "f"))))]
774 "rmf%?d\\t%0, %1, %2"
775 [(set_attr "type" "float")])
778 [(set (match_operand:DF 0 "s_register_operand" "=f")
779 (mod:DF (float_extend:DF
780 (match_operand:SF 1 "s_register_operand" "f"))
782 (match_operand:SF 2 "s_register_operand" "f"))))]
784 "rmf%?d\\t%0, %1, %2"
785 [(set_attr "type" "float")])
787 (define_insn "modxf3"
788 [(set (match_operand:XF 0 "s_register_operand" "=f")
789 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
790 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
792 "rmf%?e\\t%0, %1, %2"
793 [(set_attr "type" "float")])
795 ;; Boolean and,ior,xor insns
797 (define_insn "anddi3"
798 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
799 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
800 (match_operand:DI 2 "s_register_operand" "r,0")))]
802 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
803 [(set_attr "length" "8")])
806 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
807 (and:DI (zero_extend:DI
808 (match_operand:SI 2 "s_register_operand" "r,r"))
809 (match_operand:DI 1 "s_register_operand" "?r,0")))]
811 "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
812 [(set_attr "length" "8")])
815 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
816 (and:DI (sign_extend:DI
817 (match_operand:SI 2 "s_register_operand" "r,r"))
818 (match_operand:DI 1 "s_register_operand" "?r,0")))]
820 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
821 [(set_attr "length" "8")])
823 (define_expand "andsi3"
824 [(set (match_operand:SI 0 "s_register_operand" "")
825 (and:SI (match_operand:SI 1 "s_register_operand" "")
826 (match_operand:SI 2 "reg_or_int_operand" "")))]
829 if (GET_CODE (operands[2]) == CONST_INT)
831 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
833 (reload_in_progress || reload_completed
834 ? 0 : preserve_subexpressions_p ()));
840 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
841 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
842 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
848 [(set_attr "length" "4,4,16")])
851 [(set (match_operand:SI 0 "s_register_operand" "")
852 (and:SI (match_operand:SI 1 "s_register_operand" "")
853 (match_operand:SI 2 "const_int_operand" "")))]
854 "! (const_ok_for_arm (INTVAL (operands[2]))
855 || const_ok_for_arm (~ INTVAL (operands[2])))"
856 [(clobber (const_int 0))]
858 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
864 [(set (reg:CC_NOOV 24)
866 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
867 (match_operand:SI 2 "arm_not_operand" "rI,K"))
869 (set (match_operand:SI 0 "s_register_operand" "=r,r")
870 (and:SI (match_dup 1) (match_dup 2)))]
874 bic%?s\\t%0, %1, #%B2"
875 [(set_attr "conds" "set")])
878 [(set (reg:CC_NOOV 24)
880 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
881 (match_operand:SI 1 "arm_not_operand" "rI,K"))
883 (clobber (match_scratch:SI 3 "=X,r"))]
887 bic%?s\\t%3, %0, #%B1"
888 [(set_attr "conds" "set")])
891 [(set (reg:CC_NOOV 24)
892 (compare:CC_NOOV (zero_extract:SI
893 (match_operand:SI 0 "s_register_operand" "r")
894 (match_operand:SI 1 "immediate_operand" "n")
895 (match_operand:SI 2 "immediate_operand" "n"))
897 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
898 && INTVAL (operands[1]) > 0
899 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
900 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
903 unsigned int mask = 0;
904 int cnt = INTVAL (operands[1]);
907 mask = (mask << 1) | 1;
908 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
909 output_asm_insn (\"tst%?\\t%0, %1\", operands);
913 [(set_attr "conds" "set")])
916 [(set (reg:CC_NOOV 24)
917 (compare:CC_NOOV (zero_extract:SI
918 (match_operand:QI 0 "memory_operand" "m")
919 (match_operand 1 "immediate_operand" "n")
920 (match_operand 2 "immediate_operand" "n"))
922 (clobber (match_scratch:QI 3 "=r"))]
923 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
924 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
927 unsigned int mask = 0;
928 int cnt = INTVAL (operands[1]);
931 mask = (mask << 1) | 1;
932 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
933 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
934 output_asm_insn (\"tst%?\\t%3, %1\", operands);
938 [(set_attr "conds" "set")
939 (set_attr "length" "8")])
941 ;; constants for op 2 will never be given to these patterns.
943 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
944 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
945 (match_operand:DI 1 "s_register_operand" "0,r")))]
947 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
948 [(set_attr "length" "8")])
951 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
952 (and:DI (not:DI (zero_extend:DI
953 (match_operand:SI 2 "s_register_operand" "r,r")))
954 (match_operand:DI 1 "s_register_operand" "0,?r")))]
958 bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
959 [(set_attr "length" "4,8")])
962 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
963 (and:DI (not:DI (sign_extend:DI
964 (match_operand:SI 2 "s_register_operand" "r,r")))
965 (match_operand:DI 1 "s_register_operand" "?r,0")))]
967 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
968 [(set_attr "length" "8")])
971 [(set (match_operand:SI 0 "s_register_operand" "=r")
972 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
973 (match_operand:SI 1 "s_register_operand" "r")))]
975 "bic%?\\t%0, %1, %2")
978 [(set (reg:CC_NOOV 24)
980 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
981 (match_operand:SI 1 "s_register_operand" "r"))
983 (set (match_operand:SI 0 "s_register_operand" "=r")
984 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
986 "bic%?s\\t%0, %1, %2"
987 [(set_attr "conds" "set")])
990 [(set (reg:CC_NOOV 24)
992 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
993 (match_operand:SI 1 "s_register_operand" "r"))
995 (clobber (match_scratch:SI 0 "=r"))]
997 "bic%?s\\t%0, %1, %2"
998 [(set_attr "conds" "set")])
1000 (define_insn "iordi3"
1001 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1002 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1003 (match_operand:DI 2 "s_register_operand" "r")))]
1005 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
1006 [(set_attr "length" "8")])
1009 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1010 (ior:DI (zero_extend:DI
1011 (match_operand:SI 2 "s_register_operand" "r,r"))
1012 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1016 orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1017 [(set_attr "length" "4,8")])
1020 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1021 (ior:DI (sign_extend:DI
1022 (match_operand:SI 2 "s_register_operand" "r,r"))
1023 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1025 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1026 [(set_attr "length" "8")])
1028 (define_expand "iorsi3"
1029 [(set (match_operand:SI 0 "s_register_operand" "")
1030 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1031 (match_operand:SI 2 "reg_or_int_operand" "")))]
1034 if (GET_CODE (operands[2]) == CONST_INT)
1036 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1038 (reload_in_progress || reload_completed
1039 ? 0 : preserve_subexpressions_p ()));
1045 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1046 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1047 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
1052 [(set_attr "length" "4,16")])
1055 [(set (match_operand:SI 0 "s_register_operand" "")
1056 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1057 (match_operand:SI 2 "const_int_operand" "")))]
1058 "! const_ok_for_arm (INTVAL (operands[2]))"
1059 [(clobber (const_int 0))]
1061 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1067 [(set (reg:CC_NOOV 24)
1068 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1069 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1071 (set (match_operand:SI 0 "s_register_operand" "=r")
1072 (ior:SI (match_dup 1) (match_dup 2)))]
1074 "orr%?s\\t%0, %1, %2"
1075 [(set_attr "conds" "set")])
1078 [(set (reg:CC_NOOV 24)
1079 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1080 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1082 (clobber (match_scratch:SI 0 "=r"))]
1084 "orr%?s\\t%0, %1, %2"
1085 [(set_attr "conds" "set")])
1087 (define_insn "xordi3"
1088 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1089 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1090 (match_operand:DI 2 "s_register_operand" "r,0")))]
1092 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
1093 [(set_attr "length" "8")])
1096 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1097 (xor:DI (zero_extend:DI
1098 (match_operand:SI 2 "s_register_operand" "r,r"))
1099 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1103 eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1104 [(set_attr "length" "4,8")])
1107 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1108 (xor:DI (sign_extend:DI
1109 (match_operand:SI 2 "s_register_operand" "r,r"))
1110 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1112 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1113 [(set_attr "length" "8")])
1115 (define_insn "xorsi3"
1116 [(set (match_operand:SI 0 "s_register_operand" "=r")
1117 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1118 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1120 "eor%?\\t%0, %1, %2")
1123 [(set (reg:CC_NOOV 24)
1124 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1125 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1127 (set (match_operand:SI 0 "s_register_operand" "=r")
1128 (xor:SI (match_dup 1) (match_dup 2)))]
1130 "eor%?s\\t%0, %1, %2"
1131 [(set_attr "conds" "set")])
1134 [(set (reg:CC_NOOV 24)
1135 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1136 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1140 [(set_attr "conds" "set")])
1142 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1143 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1147 [(set (match_operand:SI 0 "s_register_operand" "=r")
1148 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1149 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1150 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1151 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1153 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1154 (not:SI (match_dup 3))))
1155 (set (match_dup 0) (not:SI (match_dup 4)))]
1160 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1161 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1162 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1163 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1165 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1166 [(set_attr "length" "8")])
1170 ;; Minimum and maximum insns
1172 (define_insn "smaxsi3"
1173 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1174 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1175 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1176 (clobber (reg:CC 24))]
1179 cmp\\t%1, %2\;movlt\\t%0, %2
1180 cmp\\t%1, %2\;movge\\t%0, %1
1181 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1182 [(set_attr "conds" "clob")
1183 (set_attr "length" "8,8,12")])
1185 (define_insn "sminsi3"
1186 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1187 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1188 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1189 (clobber (reg:CC 24))]
1192 cmp\\t%1, %2\;movge\\t%0, %2
1193 cmp\\t%1, %2\;movlt\\t%0, %1
1194 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1195 [(set_attr "conds" "clob")
1196 (set_attr "length" "8,8,12")])
1198 (define_insn "umaxsi3"
1199 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1200 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1201 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1202 (clobber (reg:CC 24))]
1205 cmp\\t%1, %2\;movcc\\t%0, %2
1206 cmp\\t%1, %2\;movcs\\t%0, %1
1207 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1208 [(set_attr "conds" "clob")
1209 (set_attr "length" "8,8,12")])
1211 (define_insn "uminsi3"
1212 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1213 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1214 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1215 (clobber (reg:CC 24))]
1218 cmp\\t%1, %2\;movcs\\t%0, %2
1219 cmp\\t%1, %2\;movcc\\t%0, %1
1220 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1221 [(set_attr "conds" "clob")
1222 (set_attr "length" "8,8,12")])
1225 [(set (match_operand:SI 0 "memory_operand" "=m")
1226 (match_operator:SI 3 "minmax_operator"
1227 [(match_operand:SI 1 "s_register_operand" "r")
1228 (match_operand:SI 2 "s_register_operand" "r")]))
1229 (clobber (reg:CC 24))]
1232 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1234 output_asm_insn (\"cmp\\t%1, %2\", operands);
1235 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1236 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1239 [(set_attr "conds" "clob")
1240 (set_attr "length" "12")
1241 (set_attr "type" "store1")])
1244 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1245 (match_operator:SI 4 "shiftable_operator"
1246 [(match_operator:SI 5 "minmax_operator"
1247 [(match_operand:SI 2 "s_register_operand" "r,r")
1248 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1249 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1250 (clobber (reg:CC 24))]
1254 enum rtx_code code = GET_CODE (operands[4]);
1256 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1258 output_asm_insn (\"cmp\\t%2, %3\", operands);
1259 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1260 if (which_alternative != 0 || operands[3] != const0_rtx
1261 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1262 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1266 [(set_attr "conds" "clob")
1267 (set_attr "length" "12")])
1270 ;; Shift and rotation insns
1272 (define_expand "ashlsi3"
1273 [(set (match_operand:SI 0 "s_register_operand" "")
1274 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1275 (match_operand:SI 2 "arm_rhs_operand" "")))]
1278 if (GET_CODE (operands[2]) == CONST_INT
1279 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1281 emit_insn (gen_movsi (operands[0], const0_rtx));
1286 (define_expand "ashrsi3"
1287 [(set (match_operand:SI 0 "s_register_operand" "")
1288 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1289 (match_operand:SI 2 "arm_rhs_operand" "")))]
1292 if (GET_CODE (operands[2]) == CONST_INT
1293 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1294 operands[2] = GEN_INT (31);
1297 (define_expand "lshrsi3"
1298 [(set (match_operand:SI 0 "s_register_operand" "")
1299 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1300 (match_operand:SI 2 "arm_rhs_operand" "")))]
1303 if (GET_CODE (operands[2]) == CONST_INT
1304 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1306 emit_insn (gen_movsi (operands[0], const0_rtx));
1311 (define_expand "rotlsi3"
1312 [(set (match_operand:SI 0 "s_register_operand" "")
1313 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1314 (match_operand:SI 2 "reg_or_int_operand" "")))]
1317 if (GET_CODE (operands[2]) == CONST_INT)
1318 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1321 rtx reg = gen_reg_rtx (SImode);
1322 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1327 (define_expand "rotrsi3"
1328 [(set (match_operand:SI 0 "s_register_operand" "")
1329 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1330 (match_operand:SI 2 "arm_rhs_operand" "")))]
1333 if (GET_CODE (operands[2]) == CONST_INT
1334 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1335 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1339 [(set (match_operand:SI 0 "s_register_operand" "=r")
1340 (match_operator:SI 3 "shift_operator"
1341 [(match_operand:SI 1 "s_register_operand" "r")
1342 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1344 "mov%?\\t%0, %1%S3")
1347 [(set (reg:CC_NOOV 24)
1348 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1349 [(match_operand:SI 1 "s_register_operand" "r")
1350 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1352 (set (match_operand:SI 0 "s_register_operand" "=r")
1353 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1355 "mov%?s\\t%0, %1%S3"
1356 [(set_attr "conds" "set")])
1359 [(set (reg:CC_NOOV 24)
1360 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1361 [(match_operand:SI 1 "s_register_operand" "r")
1362 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1364 (clobber (match_scratch:SI 0 "=r"))]
1366 "mov%?s\\t%0, %1%S3"
1367 [(set_attr "conds" "set")])
1370 [(set (match_operand:SI 0 "s_register_operand" "=r")
1371 (not:SI (match_operator:SI 3 "shift_operator"
1372 [(match_operand:SI 1 "s_register_operand" "r")
1373 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
1375 "mvn%?\\t%0, %1%S3")
1378 [(set (reg:CC_NOOV 24)
1379 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1380 [(match_operand:SI 1 "s_register_operand" "r")
1381 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1383 (set (match_operand:SI 0 "s_register_operand" "=r")
1384 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1386 "mvn%?s\\t%0, %1%S3"
1387 [(set_attr "conds" "set")])
1390 [(set (reg:CC_NOOV 24)
1391 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1392 [(match_operand:SI 1 "s_register_operand" "r")
1393 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1395 (clobber (match_scratch:SI 0 "=r"))]
1397 "mvn%?s\\t%0, %1%S3"
1398 [(set_attr "conds" "set")])
1401 ;; Unary arithmetic insns
1403 (define_insn "negdi2"
1404 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1405 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1407 "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
1408 [(set_attr "conds" "clob")
1409 (set_attr "length" "8")])
1411 (define_insn "negsi2"
1412 [(set (match_operand:SI 0 "s_register_operand" "=r")
1413 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1415 "rsb%?\\t%0, %1, #0")
1417 (define_insn "negsf2"
1418 [(set (match_operand:SF 0 "s_register_operand" "=f")
1419 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1422 [(set_attr "type" "float")])
1424 (define_insn "negdf2"
1425 [(set (match_operand:DF 0 "s_register_operand" "=f")
1426 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1429 [(set_attr "type" "float")])
1432 [(set (match_operand:DF 0 "s_register_operand" "=f")
1433 (neg:DF (float_extend:DF
1434 (match_operand:SF 1 "s_register_operand" "f"))))]
1437 [(set_attr "type" "float")])
1439 (define_insn "negxf2"
1440 [(set (match_operand:XF 0 "s_register_operand" "=f")
1441 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1442 "ENABLE_XF_PATTERNS"
1444 [(set_attr "type" "float")])
1446 ;; abssi2 doesn't really clobber the condition codes if a different register
1447 ;; is being set. To keep things simple, assume during rtl manipulations that
1448 ;; it does, but tell the final scan operator the truth. Similarly for
1451 (define_insn "abssi2"
1452 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1453 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1457 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1458 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1459 [(set_attr "conds" "clob,*")
1460 (set_attr "length" "8")])
1463 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1464 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1468 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1469 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1470 [(set_attr "conds" "clob,*")
1471 (set_attr "length" "8")])
1473 (define_insn "abssf2"
1474 [(set (match_operand:SF 0 "s_register_operand" "=f")
1475 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1478 [(set_attr "type" "float")])
1480 (define_insn "absdf2"
1481 [(set (match_operand:DF 0 "s_register_operand" "=f")
1482 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1485 [(set_attr "type" "float")])
1488 [(set (match_operand:DF 0 "s_register_operand" "=f")
1489 (abs:DF (float_extend:DF
1490 (match_operand:SF 1 "s_register_operand" "f"))))]
1493 [(set_attr "type" "float")])
1495 (define_insn "absxf2"
1496 [(set (match_operand:XF 0 "s_register_operand" "=f")
1497 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1498 "ENABLE_XF_PATTERNS"
1500 [(set_attr "type" "float")])
1502 (define_insn "sqrtsf2"
1503 [(set (match_operand:SF 0 "s_register_operand" "=f")
1504 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1507 [(set_attr "type" "float_em")])
1509 (define_insn "sqrtdf2"
1510 [(set (match_operand:DF 0 "s_register_operand" "=f")
1511 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1514 [(set_attr "type" "float_em")])
1517 [(set (match_operand:DF 0 "s_register_operand" "=f")
1518 (sqrt:DF (float_extend:DF
1519 (match_operand:SF 1 "s_register_operand" "f"))))]
1522 [(set_attr "type" "float_em")])
1524 (define_insn "sqrtxf2"
1525 [(set (match_operand:XF 0 "s_register_operand" "=f")
1526 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1527 "ENABLE_XF_PATTERNS"
1529 [(set_attr "type" "float_em")])
1531 (define_insn "sinsf2"
1532 [(set (match_operand:SF 0 "s_register_operand" "=f")
1533 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1536 [(set_attr "type" "float_em")])
1538 (define_insn "sindf2"
1539 [(set (match_operand:DF 0 "s_register_operand" "=f")
1540 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1543 [(set_attr "type" "float_em")])
1546 [(set (match_operand:DF 0 "s_register_operand" "=f")
1547 (unspec:DF [(float_extend:DF
1548 (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1551 [(set_attr "type" "float_em")])
1553 (define_insn "sinxf2"
1554 [(set (match_operand:XF 0 "s_register_operand" "=f")
1555 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1556 "ENABLE_XF_PATTERNS"
1558 [(set_attr "type" "float_em")])
1560 (define_insn "cossf2"
1561 [(set (match_operand:SF 0 "s_register_operand" "=f")
1562 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1565 [(set_attr "type" "float_em")])
1567 (define_insn "cosdf2"
1568 [(set (match_operand:DF 0 "s_register_operand" "=f")
1569 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1572 [(set_attr "type" "float_em")])
1575 [(set (match_operand:DF 0 "s_register_operand" "=f")
1576 (unspec:DF [(float_extend:DF
1577 (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1580 [(set_attr "type" "float_em")])
1582 (define_insn "cosxf2"
1583 [(set (match_operand:XF 0 "s_register_operand" "=f")
1584 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1585 "ENABLE_XF_PATTERNS"
1587 [(set_attr "type" "float_em")])
1589 (define_insn "one_cmpldi2"
1590 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1591 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1593 "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
1594 [(set_attr "length" "8")])
1596 (define_insn "one_cmplsi2"
1597 [(set (match_operand:SI 0 "s_register_operand" "=r")
1598 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1603 [(set (reg:CC_NOOV 24)
1604 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1606 (set (match_operand:SI 0 "s_register_operand" "=r")
1607 (not:SI (match_dup 1)))]
1610 [(set_attr "conds" "set")])
1613 [(set (reg:CC_NOOV 24)
1614 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1616 (clobber (match_scratch:SI 0 "=r"))]
1619 [(set_attr "conds" "set")])
1621 ;; Fixed <--> Floating conversion insns
1623 (define_insn "floatsisf2"
1624 [(set (match_operand:SF 0 "s_register_operand" "=f")
1625 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1628 [(set_attr "type" "r_2_f")])
1630 (define_insn "floatsidf2"
1631 [(set (match_operand:DF 0 "s_register_operand" "=f")
1632 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1635 [(set_attr "type" "r_2_f")])
1637 (define_insn "floatsixf2"
1638 [(set (match_operand:XF 0 "s_register_operand" "=f")
1639 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1640 "ENABLE_XF_PATTERNS"
1642 [(set_attr "type" "r_2_f")])
1644 (define_insn "fix_truncsfsi2"
1645 [(set (match_operand:SI 0 "s_register_operand" "=r")
1646 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
1649 [(set_attr "type" "f_2_r")])
1651 (define_insn "fix_truncdfsi2"
1652 [(set (match_operand:SI 0 "s_register_operand" "=r")
1653 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
1656 [(set_attr "type" "f_2_r")])
1658 (define_insn "fix_truncxfsi2"
1659 [(set (match_operand:SI 0 "s_register_operand" "=r")
1660 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1661 "ENABLE_XF_PATTERNS"
1663 [(set_attr "type" "f_2_r")])
1667 (define_insn "truncdfsf2"
1668 [(set (match_operand:SF 0 "s_register_operand" "=f")
1670 (match_operand:DF 1 "s_register_operand" "f")))]
1673 [(set_attr "type" "float")])
1675 (define_insn "truncxfsf2"
1676 [(set (match_operand:SF 0 "s_register_operand" "=f")
1678 (match_operand:XF 1 "s_register_operand" "f")))]
1679 "ENABLE_XF_PATTERNS"
1681 [(set_attr "type" "float")])
1683 (define_insn "truncxfdf2"
1684 [(set (match_operand:DF 0 "s_register_operand" "=f")
1686 (match_operand:XF 1 "s_register_operand" "f")))]
1687 "ENABLE_XF_PATTERNS"
1689 [(set_attr "type" "float")])
1691 ;; Zero and sign extension instructions.
1693 (define_insn "zero_extendsidi2"
1694 [(set (match_operand:DI 0 "s_register_operand" "=r")
1695 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1698 if (REGNO (operands[1]) != REGNO (operands[0]))
1699 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1700 return \"mov%?\\t%R0, #0\";
1702 [(set_attr "length" "8")])
1704 (define_insn "zero_extendqidi2"
1705 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
1706 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1709 and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
1710 ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
1711 [(set_attr "length" "8")
1712 (set_attr "type" "*,load")])
1714 (define_insn "extendsidi2"
1715 [(set (match_operand:DI 0 "s_register_operand" "=r")
1716 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1719 if (REGNO (operands[1]) != REGNO (operands[0]))
1720 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1721 return \"mov%?\\t%R0, %0, asr #31\";
1723 [(set_attr "length" "8")])
1725 (define_expand "zero_extendhisi2"
1726 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1728 (set (match_operand:SI 0 "s_register_operand" "")
1729 (lshiftrt:SI (match_dup 2) (const_int 16)))]
1732 { operands[1] = gen_lowpart (SImode, operands[1]);
1733 operands[2] = gen_reg_rtx (SImode);
1736 (define_expand "zero_extendqisi2"
1737 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1739 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1742 if (GET_CODE (operands[1]) != MEM)
1744 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
1751 [(set (match_operand:SI 0 "s_register_operand" "=r")
1752 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1754 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1755 [(set_attr "type" "load")])
1758 [(set (match_operand:SI 0 "s_register_operand" "")
1759 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
1760 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1761 "GET_CODE (operands[1]) != MEM"
1762 [(set (match_dup 2) (match_dup 1))
1763 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
1767 [(set (reg:CC_NOOV 24)
1768 (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1772 [(set_attr "conds" "set")])
1774 (define_expand "extendhisi2"
1776 (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1778 (set (match_operand:SI 0 "s_register_operand" "")
1779 (ashiftrt:SI (match_dup 2)
1783 { operands[1] = gen_lowpart (SImode, operands[1]);
1784 operands[2] = gen_reg_rtx (SImode); }")
1786 (define_expand "extendqihi2"
1788 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1790 (set (match_operand:HI 0 "s_register_operand" "")
1791 (ashiftrt:SI (match_dup 2)
1795 { operands[0] = gen_lowpart (SImode, operands[0]);
1796 operands[1] = gen_lowpart (SImode, operands[1]);
1797 operands[2] = gen_reg_rtx (SImode); }")
1799 (define_expand "extendqisi2"
1801 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1803 (set (match_operand:SI 0 "s_register_operand" "")
1804 (ashiftrt:SI (match_dup 2)
1808 { operands[1] = gen_lowpart (SImode, operands[1]);
1809 operands[2] = gen_reg_rtx (SImode); }")
1811 (define_insn "extendsfdf2"
1812 [(set (match_operand:DF 0 "s_register_operand" "=f")
1813 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
1816 [(set_attr "type" "float")])
1818 (define_insn "extendsfxf2"
1819 [(set (match_operand:XF 0 "s_register_operand" "=f")
1820 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
1821 "ENABLE_XF_PATTERNS"
1824 (define_insn "extenddfxf2"
1825 [(set (match_operand:XF 0 "s_register_operand" "=f")
1826 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
1827 "ENABLE_XF_PATTERNS"
1829 [(set_attr "type" "float")])
1832 ;; Move insns (including loads and stores)
1834 ;; XXX Just some ideas about movti.
1835 ;; I don't think these are a good idea on the arm, there just aren't enough
1837 ;;(define_expand "loadti"
1838 ;; [(set (match_operand:TI 0 "s_register_operand" "")
1839 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
1842 ;;(define_expand "storeti"
1843 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
1844 ;; (match_operand:TI 1 "s_register_operand" ""))]
1847 ;;(define_expand "movti"
1848 ;; [(set (match_operand:TI 0 "general_operand" "")
1849 ;; (match_operand:TI 1 "general_operand" ""))]
1855 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1856 ;; operands[1] = copy_to_reg (operands[1]);
1857 ;; if (GET_CODE (operands[0]) == MEM)
1858 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
1859 ;; else if (GET_CODE (operands[1]) == MEM)
1860 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
1864 ;; emit_insn (insn);
1868 ;; Recognise garbage generated above.
1871 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
1872 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
1876 ;; register mem = (which_alternative < 3);
1877 ;; register char *template;
1879 ;; operands[mem] = XEXP (operands[mem], 0);
1880 ;; switch (which_alternative)
1882 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
1883 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
1884 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
1885 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
1886 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
1887 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
1889 ;; output_asm_insn (template, operands);
1894 (define_insn "movdi"
1895 [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
1896 (match_operand:DI 1 "di_operand" "rIK,n,o<>,r,F"))]
1899 return (output_move_double (operands));
1901 [(set_attr "length" "8,32,8,8,32")
1902 (set_attr "type" "*,*,load,store2,*")])
1904 (define_expand "movsi"
1905 [(set (match_operand:SI 0 "general_operand" "")
1906 (match_operand:SI 1 "general_operand" ""))]
1909 /* Everything except mem = const or mem = mem can be done easily */
1910 if (GET_CODE (operands[0]) == MEM)
1911 operands[1] = force_reg (SImode, operands[1]);
1912 if (GET_CODE (operands[1]) == CONST_INT
1913 && !(const_ok_for_arm (INTVAL (operands[1]))
1914 || const_ok_for_arm (~INTVAL (operands[1]))))
1916 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
1918 (reload_in_progress || reload_completed ? 0
1919 : preserve_subexpressions_p ()));
1925 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r,r")
1926 (match_operand:SI 1 "general_operand" "R,m,K,rI,r,S,?n"))]
1927 "(register_operand (operands[0], SImode)
1928 && (GET_CODE (operands[1]) != SYMBOL_REF
1929 || CONSTANT_ADDRESS_P (operands[1])))
1930 || register_operand (operands[1], SImode)"
1932 switch (which_alternative)
1935 /* NB Calling get_attr_length may cause the insn to be re-extracted... */
1936 if (get_attr_length (insn) == 8)
1938 /* ... so modify the operands here. */
1939 operands[1] = XEXP (operands[1], 0);
1940 output_asm_insn (\"sub%?\\t%0, %|pc, #(8 + . - %a1) & ~4095\",
1942 output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
1948 operands[1] = XEXP (operands[1], 0);
1949 output_asm_insn (\"ldr%?\\t%0, [%|pc, %1 - . - 8]\", operands);
1954 if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1955 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
1957 return \"ldr%?\\t%0, %1\";
1960 return \"mov%?\\t%0, %1\";
1962 return \"mvn%?\\t%0, #%B1\";
1964 return \"str%?\\t%1, %0\";
1966 return output_load_symbol (insn, operands);
1971 [(set (attr "length")
1972 (cond [(eq_attr "alternative" "0")
1976 (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
1980 (ior (eq_attr "alternative" "5")
1981 (eq_attr "alternative" "6")) (const_int 16)]
1983 (set_attr "type" "load,load,*,*,store1,*,*")])
1986 [(set (match_operand:SI 0 "s_register_operand" "")
1987 (match_operand:SI 1 "const_int_operand" ""))]
1988 "! (const_ok_for_arm (INTVAL (operands[1]))
1989 || const_ok_for_arm (~INTVAL (operands[1])))"
1990 [(clobber (const_int 0))]
1992 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
1997 ;; If copying one reg to another we can set the condition codes according to
1998 ;; its value. Such a move is common after a return from subroutine and the
1999 ;; result is being tested against zero.
2002 [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
2004 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2008 sub%?s\\t%0, %1, #0"
2009 [(set_attr "conds" "set")])
2011 ;; Subroutine to store a half word from a register into memory.
2012 ;; Operand 0 is the source register (HImode)
2013 ;; Operand 1 is the destination address in a register (SImode)
2015 ;; In both this routine and the next, we must be careful not to spill
2016 ;; a memory address of reg+large_const into a seperate PLUS insn, since this
2017 ;; can generate unrecognizable rtl.
2019 (define_expand "storehi"
2020 [;; store the low byte
2021 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2022 ;; extract the high byte
2024 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2025 ;; store the high byte
2026 (set (mem:QI (match_dup 4))
2027 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2031 enum rtx_code code = GET_CODE (operands[1]);
2033 if ((code == PLUS || code == MINUS)
2034 && (GET_CODE (XEXP (operands[1], 1)) == REG
2035 || GET_CODE (XEXP (operands[1], 0)) != REG))
2036 operands[1] = force_reg (SImode, operands[1]);
2037 operands[4] = plus_constant (operands[1], 1);
2038 operands[3] = gen_lowpart (QImode, operands[0]);
2039 operands[0] = gen_lowpart (SImode, operands[0]);
2040 operands[2] = gen_reg_rtx (SImode);
2044 (define_expand "storehi_bigend"
2045 [(set (mem:QI (match_dup 4)) (match_dup 3))
2047 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2048 (set (mem:QI (match_operand 1 "" ""))
2049 (subreg:QI (match_dup 2) 0))]
2053 enum rtx_code code = GET_CODE (operands[1]);
2054 if ((code == PLUS || code == MINUS)
2055 && (GET_CODE (XEXP (operands[1], 1)) == REG
2056 || GET_CODE (XEXP (operands[1], 0)) != REG))
2057 operands[1] = force_reg (SImode, operands[1]);
2059 operands[4] = plus_constant (operands[1], 1);
2060 operands[3] = gen_lowpart (QImode, operands[0]);
2061 operands[0] = gen_lowpart (SImode, operands[0]);
2062 operands[2] = gen_reg_rtx (SImode);
2066 ;; Subroutine to store a half word integer constant into memory.
2067 (define_expand "storeinthi"
2068 [(set (mem:QI (match_operand:SI 0 "" ""))
2069 (subreg:QI (match_operand 1 "" "") 0))
2070 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2074 HOST_WIDE_INT value = INTVAL (operands[1]);
2075 enum rtx_code code = GET_CODE (operands[0]);
2077 if ((code == PLUS || code == MINUS)
2078 && (GET_CODE (XEXP (operands[0], 1)) == REG
2079 || GET_CODE (XEXP (operands[0], 0)) != REG))
2080 operands[0] = force_reg (SImode, operands[0]);
2082 operands[1] = gen_reg_rtx (SImode);
2083 if (BYTES_BIG_ENDIAN)
2085 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2086 if ((value & 255) == ((value >> 8) & 255))
2087 operands[2] = operands[1];
2090 operands[2] = gen_reg_rtx (SImode);
2091 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2096 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2097 if ((value & 255) == ((value >> 8) & 255))
2098 operands[2] = operands[1];
2101 operands[2] = gen_reg_rtx (SImode);
2102 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2106 operands[3] = plus_constant (operands[0], 1);
2110 (define_expand "movhi"
2111 [(set (match_operand:HI 0 "general_operand" "")
2112 (match_operand:HI 1 "general_operand" ""))]
2118 if (! (reload_in_progress || reload_completed))
2120 if (GET_CODE (operands[0]) == MEM)
2122 if (GET_CODE (operands[1]) == CONST_INT)
2123 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
2126 if (GET_CODE (operands[1]) == MEM)
2127 operands[1] = force_reg (HImode, operands[1]);
2128 if (BYTES_BIG_ENDIAN)
2129 emit_insn (gen_storehi_bigend (operands[1],
2130 XEXP (operands[0], 0)));
2132 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
2136 /* Sign extend a constant, and keep it in an SImode reg. */
2137 else if (GET_CODE (operands[1]) == CONST_INT)
2139 rtx reg = gen_reg_rtx (SImode);
2140 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2142 /* If the constant is already valid, leave it alone. */
2143 if (! const_ok_for_arm (val))
2145 /* If setting all the top bits will make the constant
2146 loadable in a single instruction, then set them.
2147 Otherwise, sign extend the number. */
2149 if (const_ok_for_arm (~ (val | ~0xffff)))
2151 else if (val & 0x8000)
2155 emit_insn (gen_movsi (reg, GEN_INT (val)));
2156 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2158 else if (BYTES_BIG_ENDIAN && GET_CODE (operands[1]) == MEM)
2160 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2167 (define_expand "movhi_bigend"
2169 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2172 (ashiftrt:SI (match_dup 2) (const_int 16)))
2173 (set (match_operand:HI 0 "s_register_operand" "")
2174 (subreg:HI (match_dup 3) 0))]
2177 operands[2] = gen_reg_rtx (SImode);
2178 operands[3] = gen_reg_rtx (SImode);
2181 ;; Pattern to recognise insn generated default case above
2184 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2185 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2186 "(! BYTES_BIG_ENDIAN)
2187 && (GET_CODE (operands[1]) != CONST_INT
2188 || const_ok_for_arm (INTVAL (operands[1]))
2189 || const_ok_for_arm (~INTVAL (operands[1])))"
2191 mov%?\\t%0, %1\\t%@ movhi
2192 mvn%?\\t%0, #%B1\\t%@ movhi
2193 ldr%?\\t%0, %1\\t%@ movhi"
2194 [(set_attr "type" "*,*,load")])
2197 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2198 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2200 && (GET_CODE (operands[1]) != CONST_INT
2201 || const_ok_for_arm (INTVAL (operands[1]))
2202 || const_ok_for_arm (~INTVAL (operands[1])))"
2204 mov%?\\t%0, %1\\t%@ movhi
2205 mvn%?\\t%0, #%B1\\t%@ movhi
2206 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2207 [(set_attr "type" "*,*,load")
2208 (set_attr "length" "4,4,8")])
2211 [(set (match_operand:SI 0 "s_register_operand" "=r")
2212 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2215 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2216 [(set_attr "type" "load")])
2218 (define_expand "reload_outhi"
2219 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2220 (match_operand:HI 1 "s_register_operand" "r")
2221 (match_operand:SI 2 "s_register_operand" "=&r")])]
2224 arm_reload_out_hi (operands);
2228 (define_expand "movqi"
2229 [(set (match_operand:QI 0 "general_operand" "")
2230 (match_operand:QI 1 "general_operand" ""))]
2233 /* Everything except mem = const or mem = mem can be done easily */
2235 if (!(reload_in_progress || reload_completed))
2237 if (GET_CODE (operands[1]) == CONST_INT)
2239 rtx reg = gen_reg_rtx (SImode);
2241 emit_insn (gen_movsi (reg, operands[1]));
2242 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2244 if (GET_CODE (operands[0]) == MEM)
2245 operands[1] = force_reg (QImode, operands[1]);
2251 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2252 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
2253 "register_operand (operands[0], QImode)
2254 || register_operand (operands[1], QImode)"
2260 [(set_attr "type" "*,*,load,store1")])
2262 (define_expand "movsf"
2263 [(set (match_operand:SF 0 "general_operand" "")
2264 (match_operand:SF 1 "general_operand" ""))]
2267 if (GET_CODE (operands[1]) == CONST_DOUBLE
2268 && ((GET_CODE (operands[0]) == REG
2269 && REGNO (operands[0]) < 16)
2270 || ! (const_double_rtx_ok_for_fpu (operands[1])
2271 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2273 extern int optimize;
2274 rtx mem = force_const_mem (SFmode, operands[1]);
2275 rtx addr = gen_reg_rtx (SImode);
2278 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2279 emit_insn (gen_movsi (addr, ptr));
2282 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2283 operands[1] = gen_rtx (MEM, SFmode, addr);
2285 if (GET_CODE (operands[0]) == MEM)
2286 operands[1] = force_reg (SFmode, operands[1]);
2290 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2291 (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
2292 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode)"
2298 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2299 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
2301 ldr%?\\t%0, %1\\t%@ float
2302 str%?\\t%1, %0\\t%@ float"
2303 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2304 (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2306 (define_expand "movdf"
2307 [(set (match_operand:DF 0 "general_operand" "")
2308 (match_operand:DF 1 "general_operand" ""))]
2311 if (GET_CODE (operands[1]) == CONST_DOUBLE
2312 && ((GET_CODE (operands[0]) == REG
2313 && REGNO (operands[0]) < 16)
2314 || ! (const_double_rtx_ok_for_fpu (operands[1])
2315 || neg_const_double_rtx_ok_for_fpu (operands[1]))))
2317 extern int optimize;
2318 rtx mem = force_const_mem (DFmode, operands[1]);
2319 rtx addr = gen_reg_rtx (SImode);
2322 rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
2323 emit_insn (gen_movsi (addr, ptr));
2326 emit_insn (gen_movsi (addr, XEXP (mem, 0)));
2327 operands[1] = gen_rtx (MEM, DFmode, addr);
2329 if (GET_CODE (operands[0]) == MEM)
2330 operands[1] = force_reg (DFmode, operands[1]);
2333 ;; Reloading a df mode value stored in integer regs to memory can require a
2335 (define_expand "reload_outdf"
2336 [(match_operand:DF 0 "reload_memory_operand" "=o")
2337 (match_operand:DF 1 "s_register_operand" "r")
2338 (match_operand:SI 2 "s_register_operand" "=&r")]
2341 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2342 XEXP (XEXP (operands[0], 0), 1)));
2343 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2349 [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
2350 (match_operand:DF 1 "general_operand"
2351 "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
2352 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2357 switch (which_alternative)
2360 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2363 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2366 ops[0] = operands[0];
2367 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2368 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2369 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2370 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2372 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2373 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2377 return \"mvf%?d\\t%0, %1\";
2379 case 5: return \"mnf%?d\\t%0, #%N1\";
2380 case 6: return \"ldf%?d\\t%0, %1\";
2381 case 7: return \"stf%?d\\t%1, %0\";
2382 case 8: return output_mov_double_fpu_from_arm (operands);
2383 case 9: return output_mov_double_arm_from_fpu (operands);
2384 case 10: return output_move_double (operands);
2388 [(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
2390 "load,store2,load,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
2392 (define_expand "movxf"
2393 [(set (match_operand:XF 0 "general_operand" "")
2394 (match_operand:XF 1 "general_operand" ""))]
2395 "ENABLE_XF_PATTERNS"
2398 ;; Even when the XFmode patterns aren't enabled, we enable this after
2399 ;; reloading so that we can push floating point registers in the prologue.
2402 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2403 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2404 "ENABLE_XF_PATTERNS || reload_completed"
2406 switch (which_alternative)
2408 case 0: return \"mvf%?e\\t%0, %1\";
2409 case 1: return \"mnf%?e\\t%0, #%N1\";
2410 case 2: return \"ldf%?e\\t%0, %1\";
2411 case 3: return \"stf%?e\\t%1, %0\";
2412 case 4: return output_mov_long_double_fpu_from_arm (operands);
2413 case 5: return output_mov_long_double_arm_from_fpu (operands);
2414 case 6: return output_mov_long_double_arm_from_arm (operands);
2417 [(set_attr "length" "4,4,4,4,8,8,12")
2418 (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
2421 ;; load- and store-multiple insns
2422 ;; The arm can load/store any set of registers, provided that they are in
2423 ;; ascending order; but that is beyond GCC so stick with what it knows.
2425 (define_expand "load_multiple"
2426 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2427 (match_operand:SI 1 "" ""))
2428 (use (match_operand:SI 2 "" ""))])]
2431 /* Support only fixed point registers */
2432 if (GET_CODE (operands[2]) != CONST_INT
2433 || INTVAL (operands[2]) > 14
2434 || INTVAL (operands[2]) < 2
2435 || GET_CODE (operands[1]) != MEM
2436 || GET_CODE (operands[0]) != REG
2437 || REGNO (operands[0]) > 14
2438 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2442 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2443 force_reg (SImode, XEXP (operands[1], 0)),
2447 ;; Load multiple with write-back
2450 [(match_parallel 0 "load_multiple_operation"
2451 [(set (match_operand:SI 1 "s_register_operand" "+r")
2452 (plus:SI (match_dup 1)
2453 (match_operand:SI 2 "immediate_operand" "n")))
2454 (set (match_operand:SI 3 "s_register_operand" "=r")
2455 (mem:SI (match_dup 1)))])]
2456 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2460 int count = XVECLEN (operands[0], 0);
2462 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2463 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2464 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2466 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2470 [(set_attr "type" "load")])
2472 ;; Ordinary load multiple
2475 [(match_parallel 0 "load_multiple_operation"
2476 [(set (match_operand:SI 1 "s_register_operand" "=r")
2477 (match_operand:SI 2 "indirect_operand" "Q"))])]
2482 int count = XVECLEN (operands[0], 0);
2484 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2485 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2486 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2488 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2492 [(set_attr "type" "load")])
2494 (define_expand "store_multiple"
2495 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2496 (match_operand:SI 1 "" ""))
2497 (use (match_operand:SI 2 "" ""))])]
2500 /* Support only fixed point registers */
2501 if (GET_CODE (operands[2]) != CONST_INT
2502 || INTVAL (operands[2]) > 14
2503 || INTVAL (operands[2]) < 2
2504 || GET_CODE (operands[1]) != REG
2505 || GET_CODE (operands[0]) != MEM
2506 || REGNO (operands[1]) > 14
2507 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2511 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2512 force_reg (SImode, XEXP (operands[0], 0)),
2516 ;; Store multiple with write-back
2519 [(match_parallel 0 "store_multiple_operation"
2520 [(set (match_operand:SI 1 "s_register_operand" "+r")
2521 (plus:SI (match_dup 1)
2522 (match_operand:SI 2 "immediate_operand" "n")))
2523 (set (mem:SI (match_dup 1))
2524 (match_operand:SI 3 "s_register_operand" "r"))])]
2525 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2529 int count = XVECLEN (operands[0], 0);
2531 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2532 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2533 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2535 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2540 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2541 (const_string "store2")
2542 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2543 (const_string "store3")]
2544 (const_string "store4")))])
2546 ;; Ordinary store multiple
2549 [(match_parallel 0 "store_multiple_operation"
2550 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2551 (match_operand:SI 1 "s_register_operand" "r"))])]
2556 int count = XVECLEN (operands[0], 0);
2558 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2559 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2560 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2562 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2567 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2568 (const_string "store2")
2569 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2570 (const_string "store3")]
2571 (const_string "store4")))])
2573 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2574 ;; We could let this apply for blocks of less than this, but it clobbers so
2575 ;; many registers that there is then probably a better way.
2577 ;; If optimizing, output redundant moves with REG_NOTES on them, this
2578 ;; produces better code.
2580 (define_expand "movstrsi"
2581 [(set (match_operand:BLK 0 "general_operand" "=m")
2582 (match_operand:BLK 1 "general_operand" "m"))
2583 (use (match_operand:SI 2 "immediate_operand" "n"))
2584 (use (match_operand:SI 3 "immediate_operand" "n"))
2585 (clobber (reg:SI 0))
2586 (clobber (reg:SI 1))
2587 (clobber (reg:SI 2))
2588 (clobber (reg:SI 3))
2589 (clobber (match_scratch:SI 4 "=+r"))
2590 (clobber (match_scratch:SI 5 "=+r"))]
2596 rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16);
2597 rtx src = gen_reg_rtx (SImode);
2598 rtx dst = gen_reg_rtx (SImode);
2599 rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst;
2600 extern int optimize;
2602 if (GET_CODE (operands[2]) != CONST_INT
2603 || GET_CODE (operands[3]) != CONST_INT
2604 || INTVAL (operands[2]) % 4 != 0
2605 || INTVAL (operands[2]) < 4
2606 || INTVAL (operands[2]) > 64
2607 || INTVAL (operands[3]) < 4
2608 || INTVAL (operands[3]) % 4 != 0)
2610 emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0)));
2611 emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0)));
2615 for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4)
2617 emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go,
2619 emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go,
2622 for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--)
2625 note = emit_move_insn (gen_reg_rtx (SImode),
2626 gen_rtx (REG, SImode, r));
2627 REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
2628 gen_rtx (MEM, SImode,
2629 plus_constant (st_src, 4*(i+r))),
2631 REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
2632 gen_rtx (MEM, SImode,
2633 plus_constant (st_dst, 4*(i+r))),
2636 words_to_go -= words_to_go < 4 ? words_to_go : 4;
2642 emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src));
2643 emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
2644 emit_move_insn (gen_rtx (MEM, SImode, dst), sreg);
2645 emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
2649 /* Insns for the REG_NOTES: These notes tell the optimiser where the
2650 index registers have got to so that consecutive block moves of
2651 contiguous data work efficiently */
2653 end_src = emit_move_insn (fin_src, fin_src);
2654 REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL,
2655 plus_constant (st_src, INTVAL (operands[2])),
2656 REG_NOTES (end_src));
2657 end_dst = emit_move_insn (fin_dst, fin_dst);
2658 REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL,
2659 plus_constant (st_dst, INTVAL (operands[2])),
2660 REG_NOTES (end_dst));
2667 ;; Comparison and test insns
2669 (define_expand "cmpsi"
2671 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2672 (match_operand:SI 1 "arm_add_operand" "")))]
2676 arm_compare_op0 = operands[0];
2677 arm_compare_op1 = operands[1];
2683 (define_expand "cmpsf"
2685 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2686 (match_operand:SF 1 "fpu_rhs_operand" "")))]
2690 arm_compare_op0 = operands[0];
2691 arm_compare_op1 = operands[1];
2697 (define_expand "cmpdf"
2699 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2700 (match_operand:DF 1 "fpu_rhs_operand" "")))]
2704 arm_compare_op0 = operands[0];
2705 arm_compare_op1 = operands[1];
2711 (define_expand "cmpxf"
2713 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2714 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2715 "ENABLE_XF_PATTERNS"
2718 arm_compare_op0 = operands[0];
2719 arm_compare_op1 = operands[1];
2726 [(set (match_operand 0 "cc_register" "")
2727 (compare (match_operand:SI 1 "s_register_operand" "r,r")
2728 (match_operand:SI 2 "arm_add_operand" "rI,L")))]
2733 [(set_attr "conds" "set")])
2736 [(set (match_operand 0 "cc_register" "")
2737 (compare (match_operand:SI 1 "s_register_operand" "r")
2738 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2741 [(set_attr "conds" "set")])
2744 [(set (match_operand 0 "cc_register" "")
2745 (compare (match_operand:SI 1 "s_register_operand" "r")
2746 (match_operator:SI 2 "shift_operator"
2747 [(match_operand:SI 3 "s_register_operand" "r")
2748 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
2751 [(set_attr "conds" "set")])
2754 [(set (match_operand 0 "cc_register" "")
2755 (compare (match_operand:SI 1 "s_register_operand" "r")
2756 (neg:SI (match_operator:SI 2 "shift_operator"
2757 [(match_operand:SI 3 "s_register_operand" "r")
2758 (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
2761 [(set_attr "conds" "set")])
2765 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2766 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2771 [(set_attr "conds" "set")
2772 (set_attr "type" "f_2_r")])
2776 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
2777 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2782 [(set_attr "conds" "set")
2783 (set_attr "type" "f_2_r")])
2787 (compare:CCFP (float_extend:DF
2788 (match_operand:SF 0 "s_register_operand" "f,f"))
2789 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2794 [(set_attr "conds" "set")
2795 (set_attr "type" "f_2_r")])
2799 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2801 (match_operand:SF 1 "s_register_operand" "f"))))]
2804 [(set_attr "conds" "set")
2805 (set_attr "type" "f_2_r")])
2809 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2810 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2811 "ENABLE_XF_PATTERNS"
2815 [(set_attr "conds" "set")
2816 (set_attr "type" "f_2_r")])
2819 [(set (reg:CCFPE 24)
2820 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2821 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2826 [(set_attr "conds" "set")
2827 (set_attr "type" "f_2_r")])
2830 [(set (reg:CCFPE 24)
2831 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2832 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2837 [(set_attr "conds" "set")
2838 (set_attr "type" "f_2_r")])
2841 [(set (reg:CCFPE 24)
2842 (compare:CCFPE (float_extend:DF
2843 (match_operand:SF 0 "s_register_operand" "f,f"))
2844 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2849 [(set_attr "conds" "set")
2850 (set_attr "type" "f_2_r")])
2853 [(set (reg:CCFPE 24)
2854 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2856 (match_operand:SF 1 "s_register_operand" "f"))))]
2859 [(set_attr "conds" "set")
2860 (set_attr "type" "f_2_r")])
2863 [(set (reg:CCFPE 24)
2864 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2865 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2866 "ENABLE_XF_PATTERNS"
2870 [(set_attr "conds" "set")
2871 (set_attr "type" "f_2_r")])
2873 ; This insn allows redundant compares to be removed by cse, nothing should
2874 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2875 ; is deleted later on. The match_dup will match the mode here, so that
2876 ; mode changes of the condition codes aren't lost by this even though we don't
2877 ; specify what they are.
2880 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2882 "\\t%@ deleted compare"
2883 [(set_attr "conds" "set")
2884 (set_attr "length" "0")])
2887 ;; Conditional branch insns
2889 (define_expand "beq"
2891 (if_then_else (eq (match_dup 1) (const_int 0))
2892 (label_ref (match_operand 0 "" ""))
2897 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
2902 (define_expand "bne"
2904 (if_then_else (ne (match_dup 1) (const_int 0))
2905 (label_ref (match_operand 0 "" ""))
2910 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
2915 (define_expand "bgt"
2917 (if_then_else (gt (match_dup 1) (const_int 0))
2918 (label_ref (match_operand 0 "" ""))
2923 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
2928 (define_expand "ble"
2930 (if_then_else (le (match_dup 1) (const_int 0))
2931 (label_ref (match_operand 0 "" ""))
2936 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
2941 (define_expand "bge"
2943 (if_then_else (ge (match_dup 1) (const_int 0))
2944 (label_ref (match_operand 0 "" ""))
2949 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
2954 (define_expand "blt"
2956 (if_then_else (lt (match_dup 1) (const_int 0))
2957 (label_ref (match_operand 0 "" ""))
2962 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
2967 (define_expand "bgtu"
2969 (if_then_else (gtu (match_dup 1) (const_int 0))
2970 (label_ref (match_operand 0 "" ""))
2975 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
2980 (define_expand "bleu"
2982 (if_then_else (leu (match_dup 1) (const_int 0))
2983 (label_ref (match_operand 0 "" ""))
2988 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
2993 (define_expand "bgeu"
2995 (if_then_else (geu (match_dup 1) (const_int 0))
2996 (label_ref (match_operand 0 "" ""))
3001 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3006 (define_expand "bltu"
3008 (if_then_else (ltu (match_dup 1) (const_int 0))
3009 (label_ref (match_operand 0 "" ""))
3014 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3019 ;; patterns to match conditional branch insns
3023 (if_then_else (match_operator 1 "comparison_operator"
3024 [(reg 24) (const_int 0)])
3025 (label_ref (match_operand 0 "" ""))
3030 extern int arm_ccfsm_state;
3032 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3034 arm_ccfsm_state += 2;
3037 return \"b%d1\\t%l0\";
3039 [(set_attr "conds" "use")])
3043 (if_then_else (match_operator 1 "comparison_operator"
3044 [(reg 24) (const_int 0)])
3046 (label_ref (match_operand 0 "" ""))))]
3047 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3050 extern int arm_ccfsm_state;
3052 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3054 arm_ccfsm_state += 2;
3057 return \"b%D1\\t%l0\";
3059 [(set_attr "conds" "use")])
3064 (define_expand "seq"
3065 [(set (match_operand:SI 0 "s_register_operand" "=r")
3066 (eq:SI (match_dup 1) (const_int 0)))]
3070 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3075 (define_expand "sne"
3076 [(set (match_operand:SI 0 "s_register_operand" "=r")
3077 (ne:SI (match_dup 1) (const_int 0)))]
3081 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3086 (define_expand "sgt"
3087 [(set (match_operand:SI 0 "s_register_operand" "=r")
3088 (gt:SI (match_dup 1) (const_int 0)))]
3092 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3097 (define_expand "sle"
3098 [(set (match_operand:SI 0 "s_register_operand" "=r")
3099 (le:SI (match_dup 1) (const_int 0)))]
3103 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3108 (define_expand "sge"
3109 [(set (match_operand:SI 0 "s_register_operand" "=r")
3110 (ge:SI (match_dup 1) (const_int 0)))]
3114 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3119 (define_expand "slt"
3120 [(set (match_operand:SI 0 "s_register_operand" "=r")
3121 (lt:SI (match_dup 1) (const_int 0)))]
3125 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3130 (define_expand "sgtu"
3131 [(set (match_operand:SI 0 "s_register_operand" "=r")
3132 (gtu:SI (match_dup 1) (const_int 0)))]
3136 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3141 (define_expand "sleu"
3142 [(set (match_operand:SI 0 "s_register_operand" "=r")
3143 (leu:SI (match_dup 1) (const_int 0)))]
3147 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3152 (define_expand "sgeu"
3153 [(set (match_operand:SI 0 "s_register_operand" "=r")
3154 (geu:SI (match_dup 1) (const_int 0)))]
3158 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3163 (define_expand "sltu"
3164 [(set (match_operand:SI 0 "s_register_operand" "=r")
3165 (ltu:SI (match_dup 1) (const_int 0)))]
3169 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3175 [(set (match_operand:SI 0 "s_register_operand" "=r")
3176 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3178 "mov%d1\\t%0, #1\;mov%D1\\t%0, #0"
3179 [(set_attr "conds" "use")
3180 (set_attr "length" "8")])
3183 [(set (match_operand:SI 0 "s_register_operand" "=r")
3184 (neg:SI (match_operator:SI 1 "comparison_operator"
3185 [(reg 24) (const_int 0)])))]
3187 "mvn%d1\\t%0, #0\;mov%D1\\t%0, #0"
3188 [(set_attr "conds" "use")
3189 (set_attr "length" "8")])
3192 [(set (match_operand:SI 0 "s_register_operand" "=r")
3193 (not:SI (match_operator:SI 1 "comparison_operator"
3194 [(reg 24) (const_int 0)])))]
3196 "mvn%d1\\t%0, #1\;mov%D1\\t%0, #0"
3197 [(set_attr "conds" "use")
3198 (set_attr "length" "8")])
3201 ;; Jump and linkage insns
3205 (label_ref (match_operand 0 "" "")))]
3209 extern int arm_ccfsm_state;
3211 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3213 arm_ccfsm_state += 2;
3216 return \"b%?\\t%l0\";
3219 (define_expand "call"
3220 [(parallel [(call (match_operand 0 "memory_operand" "")
3221 (match_operand 1 "general_operand" ""))
3222 (clobber (reg:SI 14))])]
3227 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3228 (match_operand 1 "" "g"))
3229 (clobber (reg:SI 14))]
3232 return output_call (operands);
3234 [(set (attr "conds")
3235 (if_then_else (eq_attr "cpu" "arm6")
3236 (const_string "clob")
3237 (const_string "nocond")))
3238 ;; length is worst case, normally it is only two
3239 (set_attr "length" "12")
3240 (set_attr "type" "call")])
3243 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3244 (match_operand 1 "general_operand" "g"))
3245 (clobber (reg:SI 14))]
3248 return output_call_mem (operands);
3250 [(set (attr "conds")
3251 (if_then_else (eq_attr "cpu" "arm6")
3252 (const_string "clob")
3253 (const_string "nocond")))
3254 (set_attr "length" "12")
3255 (set_attr "type" "call")])
3257 (define_expand "call_value"
3258 [(parallel [(set (match_operand 0 "" "=rf")
3259 (call (match_operand 1 "memory_operand" "m")
3260 (match_operand 2 "general_operand" "g")))
3261 (clobber (reg:SI 14))])]
3266 [(set (match_operand 0 "" "=rf")
3267 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3268 (match_operand 2 "general_operand" "g")))
3269 (clobber (reg:SI 14))]
3272 return output_call (&operands[1]);
3274 [(set (attr "conds")
3275 (if_then_else (eq_attr "cpu" "arm6")
3276 (const_string "clob")
3277 (const_string "nocond")))
3278 (set_attr "length" "12")
3279 (set_attr "type" "call")])
3282 [(set (match_operand 0 "" "=rf")
3283 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3284 (match_operand 2 "general_operand" "g")))
3285 (clobber (reg:SI 14))]
3286 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3288 return output_call_mem (&operands[1]);
3290 [(set (attr "conds")
3291 (if_then_else (eq_attr "cpu" "arm6")
3292 (const_string "clob")
3293 (const_string "nocond")))
3294 (set_attr "length" "12")
3295 (set_attr "type" "call")])
3297 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3298 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3301 [(call (mem:SI (match_operand:SI 0 "" "i"))
3302 (match_operand:SI 1 "general_operand" "g"))
3303 (clobber (reg:SI 14))]
3304 "GET_CODE (operands[0]) == SYMBOL_REF"
3306 [(set (attr "conds")
3307 (if_then_else (eq_attr "cpu" "arm6")
3308 (const_string "clob")
3309 (const_string "nocond")))
3310 (set_attr "type" "call")])
3313 [(set (match_operand 0 "s_register_operand" "=rf")
3314 (call (mem:SI (match_operand:SI 1 "" "i"))
3315 (match_operand:SI 2 "general_operand" "g")))
3316 (clobber (reg:SI 14))]
3317 "GET_CODE(operands[1]) == SYMBOL_REF"
3319 [(set (attr "conds")
3320 (if_then_else (eq_attr "cpu" "arm6")
3321 (const_string "clob")
3322 (const_string "nocond")))
3323 (set_attr "type" "call")])
3325 ;; Often the return insn will be the same as loading from memory, so set attr
3326 (define_insn "return"
3331 extern int arm_ccfsm_state;
3333 if (arm_ccfsm_state == 2)
3335 arm_ccfsm_state += 2;
3338 return output_return_instruction (NULL, TRUE);
3340 [(set_attr "type" "load")])
3344 (if_then_else (match_operator 0 "comparison_operator"
3345 [(reg 24) (const_int 0)])
3351 extern int arm_ccfsm_state;
3353 if (arm_ccfsm_state == 2)
3355 arm_ccfsm_state += 2;
3358 return output_return_instruction (operands[0], TRUE);
3360 [(set_attr "conds" "use")
3361 (set_attr "type" "load")])
3365 (if_then_else (match_operator 0 "comparison_operator"
3366 [(reg 24) (const_int 0)])
3372 extern int arm_ccfsm_state;
3374 if (arm_ccfsm_state == 2)
3376 arm_ccfsm_state += 2;
3379 return output_return_instruction
3380 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3381 GET_MODE (operands[0]), XEXP (operands[0], 0),
3382 XEXP (operands[0], 1)),
3385 [(set_attr "conds" "use")
3386 (set_attr "type" "load")])
3388 ;; Call subroutine returning any type.
3390 (define_expand "untyped_call"
3391 [(parallel [(call (match_operand 0 "" "")
3393 (match_operand 1 "" "")
3394 (match_operand 2 "" "")])]
3400 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3402 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3404 rtx set = XVECEXP (operands[2], 0, i);
3405 emit_move_insn (SET_DEST (set), SET_SRC (set));
3408 /* The optimizer does not know that the call sets the function value
3409 registers we stored in the result block. We avoid problems by
3410 claiming that all hard registers are used and clobbered at this
3412 emit_insn (gen_blockage ());
3417 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3418 ;; all of memory. This blocks insns from being moved across this point.
3420 (define_insn "blockage"
3421 [(unspec_volatile [(const_int 0)] 0)]
3424 [(set_attr "length" "0")
3425 (set_attr "type" "block")])
3427 (define_insn "tablejump"
3429 (match_operand:SI 0 "s_register_operand" "r"))
3430 (use (label_ref (match_operand 1 "" "")))]
3432 "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
3436 (match_operand:SI 0 "memory_operand" "m"))
3437 (use (label_ref (match_operand 1 "" "")))]
3439 "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
3440 [(set_attr "type" "load")])
3442 (define_insn "indirect_jump"
3444 (match_operand:SI 0 "s_register_operand" "r"))]
3446 "mov%?\\t%|pc, %0\\t%@ indirect jump")
3450 (match_operand:SI 0 "memory_operand" "m"))]
3452 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3453 [(set_attr "type" "load")])
3460 "mov%?\\tr0, r0\\t%@ nop")
3462 ;; Patterns to allow combination of arithmetic, cond code and shifts
3465 [(set (match_operand:SI 0 "s_register_operand" "=r")
3466 (match_operator:SI 1 "shiftable_operator"
3467 [(match_operator:SI 3 "shift_operator"
3468 [(match_operand:SI 4 "s_register_operand" "r")
3469 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3470 (match_operand:SI 2 "s_register_operand" "r")]))]
3472 "%i1%?\\t%0, %2, %4%S3")
3475 [(set (reg:CC_NOOV 24)
3476 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3477 [(match_operator:SI 3 "shift_operator"
3478 [(match_operand:SI 4 "s_register_operand" "r")
3479 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3480 (match_operand:SI 2 "s_register_operand" "r")])
3482 (set (match_operand:SI 0 "s_register_operand" "=r")
3483 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3486 "%i1%?s\\t%0, %2, %4%S3"
3487 [(set_attr "conds" "set")])
3490 [(set (reg:CC_NOOV 24)
3491 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3492 [(match_operator:SI 3 "shift_operator"
3493 [(match_operand:SI 4 "s_register_operand" "r")
3494 (match_operand:SI 5 "reg_or_int_operand" "rI")])
3495 (match_operand:SI 2 "s_register_operand" "r")])
3497 (clobber (match_scratch:SI 0 "=r"))]
3499 "%i1%?s\\t%0, %2, %4%S3"
3500 [(set_attr "conds" "set")])
3503 [(set (match_operand:SI 0 "s_register_operand" "=r")
3504 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3505 (match_operator:SI 2 "shift_operator"
3506 [(match_operand:SI 3 "s_register_operand" "r")
3507 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
3509 "sub%?\\t%0, %1, %3%S2")
3512 [(set (reg:CC_NOOV 24)
3514 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3515 (match_operator:SI 2 "shift_operator"
3516 [(match_operand:SI 3 "s_register_operand" "r")
3517 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3519 (set (match_operand:SI 0 "s_register_operand" "=r")
3520 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3523 "sub%?s\\t%0, %1, %3%S2"
3524 [(set_attr "conds" "set")])
3527 [(set (reg:CC_NOOV 24)
3529 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3530 (match_operator:SI 2 "shift_operator"
3531 [(match_operand:SI 3 "s_register_operand" "r")
3532 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
3534 (clobber (match_scratch:SI 0 "=r"))]
3536 "sub%?s\\t%0, %1, %3%S2"
3537 [(set_attr "conds" "set")])
3539 ;; These variants of the above insns can occur if the first operand is the
3540 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3541 ;; seem to be a way around it. Most of the predicates have to be null
3542 ;; because the format can be generated part way through reload, so
3543 ;; if we don't match it as soon as it becomes available, reload doesn't know
3544 ;; how to reload pseudos that haven't got hard registers; the constraints will
3545 ;; sort everything out.
3548 [(set (match_operand:SI 0 "" "=&r")
3549 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3550 [(match_operand:SI 3 "" "r")
3551 (match_operand:SI 4 "" "rM")])
3552 (match_operand:SI 2 "" "r"))
3553 (match_operand:SI 1 "const_int_operand" "n")))]
3554 "reload_in_progress"
3556 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
3557 operands[2] = operands[1];
3558 operands[1] = operands[0];
3559 return output_add_immediate (operands);
3561 ; we have no idea how long the add_immediate is, it could be up to 4.
3562 [(set_attr "length" "20")])
3565 [(set (reg:CC_NOOV 24)
3566 (compare:CC_NOOV (plus:SI
3568 (match_operator:SI 5 "shift_operator"
3569 [(match_operand:SI 3 "" "r")
3570 (match_operand:SI 4 "" "rM")])
3571 (match_operand:SI 1 "" "r"))
3572 (match_operand:SI 2 "const_int_operand" "n"))
3574 (set (match_operand:SI 0 "" "=&r")
3575 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3578 "reload_in_progress"
3580 output_add_immediate (operands);
3581 return \"add%?s\\t%0, %0, %3%S5\";
3583 [(set_attr "conds" "set")
3584 (set_attr "length" "20")])
3587 [(set (reg:CC_NOOV 24)
3588 (compare:CC_NOOV (plus:SI
3590 (match_operator:SI 5 "shift_operator"
3591 [(match_operand:SI 3 "" "r")
3592 (match_operand:SI 4 "" "rM")])
3593 (match_operand:SI 1 "" "r"))
3594 (match_operand:SI 2 "const_int_operand" "n"))
3596 (clobber (match_scratch:SI 0 "=&r"))]
3597 "reload_in_progress"
3599 output_add_immediate (operands);
3600 return \"add%?s\\t%0, %0, %3%S5\";
3602 [(set_attr "conds" "set")
3603 (set_attr "length" "20")])
3605 ;; These are similar, but are needed when the mla pattern contains the
3606 ;; eliminated register as operand 3.
3609 [(set (match_operand:SI 0 "" "=&r,&r")
3610 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3611 (match_operand:SI 2 "" "r,r"))
3612 (match_operand:SI 3 "" "r,r"))
3613 (match_operand:SI 4 "const_int_operand" "n,n")))]
3614 "reload_in_progress"
3616 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3617 operands[2] = operands[4];
3618 operands[1] = operands[0];
3619 return output_add_immediate (operands);
3621 [(set_attr "length" "20")])
3624 [(set (reg:CC_NOOV 24)
3625 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3626 (match_operand:SI 3 "" "r")
3627 (match_operand:SI 4 "" "r"))
3628 (match_operand:SI 1 "" "r"))
3629 (match_operand:SI 2 "const_int_operand" "n"))
3631 (set (match_operand:SI 0 "" "=&r")
3632 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3634 "reload_in_progress"
3636 output_add_immediate (operands);
3637 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3640 [(set_attr "length" "20")
3641 (set_attr "conds" "set")])
3644 [(set (reg:CC_NOOV 24)
3645 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3646 (match_operand:SI 3 "" "r")
3647 (match_operand:SI 4 "" "r"))
3648 (match_operand:SI 1 "" "r"))
3649 (match_operand:SI 2 "const_int_operand" "n"))
3651 (clobber (match_scratch:SI 0 "=&r"))]
3652 "reload_in_progress"
3654 output_add_immediate (operands);
3655 return \"mla%?s\\t%0, %3, %4, %0\";
3657 [(set_attr "length" "20")
3658 (set_attr "conds" "set")])
3664 [(set (match_operand:SI 0 "s_register_operand" "=r")
3665 (and:SI (match_operator 1 "comparison_operator"
3666 [(reg 24) (const_int 0)])
3667 (match_operand:SI 2 "s_register_operand" "r")))]
3669 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3670 [(set_attr "conds" "use")
3671 (set_attr "length" "8")])
3674 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3675 (ior:SI (match_operator 2 "comparison_operator"
3676 [(reg 24) (const_int 0)])
3677 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3681 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3682 [(set_attr "conds" "use")
3683 (set_attr "length" "4,8")])
3686 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3687 (match_operator 1 "comparison_operator"
3688 [(match_operand:SI 2 "s_register_operand" "r,r")
3689 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
3693 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3694 return \"mov\\t%0, %2, lsr #31\";
3696 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3697 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3699 if (GET_CODE (operands[1]) == NE)
3701 if (which_alternative == 1)
3702 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3703 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3705 if (which_alternative == 1)
3706 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3708 output_asm_insn (\"cmp\\t%2, %3\", operands);
3709 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3711 [(set_attr "conds" "clob")
3712 (set_attr "length" "12")])
3715 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3716 (ior:SI (match_operator 1 "comparison_operator"
3717 [(match_operand:SI 2 "s_register_operand" "r")
3718 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3719 (match_operator 4 "comparison_operator"
3720 [(match_operand:SI 5 "s_register_operand" "r")
3721 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3726 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3727 GET_CODE (operands[1]));
3729 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3731 output_asm_insn (\"mov\\t%0, #0\", operands);
3732 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3733 || comparison_dominates_p (GET_CODE (operands[1]),
3734 GET_CODE (operands[4]))
3736 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3739 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3740 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3743 [(set_attr "conds" "clob")
3745 (set_attr "length" "20")])
3750 (match_operator 5 "equality_operator"
3751 [(ior:SI (match_operator 6 "comparison_operator"
3752 [(match_operand:SI 0 "s_register_operand" "")
3753 (match_operand:SI 1 "arm_add_operand" "")])
3754 (match_operator 7 "comparison_operator"
3755 [(match_operand:SI 2 "s_register_operand" "")
3756 (match_operand:SI 3 "arm_add_operand" "")]))
3758 (label_ref (match_operand 4 "" ""))
3761 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3762 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3763 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3765 (compare:CC (ior:CC (match_op_dup 6
3766 [(match_dup 0) (match_dup 1)])
3768 [(match_dup 2) (match_dup 3)]))
3771 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3772 (label_ref (match_dup 4))
3776 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3777 GET_CODE (operands[7]))
3778 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3780 if (GET_CODE (operands[5]) == NE)
3781 operands[5] = gen_rtx (code, CCmode,
3782 XEXP (operands[5], 0), XEXP (operands[5], 1));
3784 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3785 XEXP (operands[5], 0), XEXP (operands[5], 1));
3789 ;; Don't match these patterns if we can use a conditional compare, since they
3790 ;; tell the final prescan branch elimator code that full branch inlining
3796 (ne (ior:SI (match_operator 5 "comparison_operator"
3797 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3798 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3799 (match_operator 6 "comparison_operator"
3800 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3801 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
3803 (label_ref (match_operand 4 "" ""))
3806 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3807 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3808 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3811 extern int arm_ccfsm_state;
3813 if (which_alternative & 1)
3814 output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
3816 output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
3818 if (which_alternative >= 2)
3819 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3821 output_asm_insn (\"cmp\\t%2, %3\", operands);
3823 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3825 arm_ccfsm_state += 2;
3828 return \"b%d6\\t%l4\";
3830 [(set_attr "conds" "jump_clob")
3831 (set_attr "length" "16")])
3836 (ior:CC (match_operator 4 "comparison_operator"
3837 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
3838 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
3839 (match_operator 5 "comparison_operator"
3840 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
3841 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
3843 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3844 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3845 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3847 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3849 if (which_alternative >= 2)
3850 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3852 output_asm_insn (\"cmp\\t%2, %3\", operands);
3854 if (which_alternative & 1)
3855 return \"cmn%D5\\t%0, #%n1\";
3856 return \"cmp%D5\\t%0, %1\";
3859 if (which_alternative & 1)
3860 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3862 output_asm_insn (\"cmp\\t%0, %1\", operands);
3864 if (which_alternative >= 2)
3865 return \"cmn%D4\\t%2, #%n3\";
3866 return \"cmp%D4\\t%2, %3\";
3868 [(set_attr "conds" "set")
3869 (set_attr "length" "8")])
3872 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3873 (if_then_else (match_operator 3 "equality_operator"
3874 [(match_operator 4 "comparison_operator"
3875 [(reg 24) (const_int 0)])
3877 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3878 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3881 if (GET_CODE (operands[3]) == NE)
3883 if (which_alternative != 0)
3884 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3885 if (which_alternative != 1)
3886 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3889 if (which_alternative != 0)
3890 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3891 if (which_alternative != 1)
3892 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
3895 [(set_attr "conds" "use")
3896 (set_attr "length" "4,4,8")])
3899 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3900 (match_operator:SI 5 "shiftable_operator"
3901 [(match_operator:SI 4 "comparison_operator"
3902 [(match_operand:SI 2 "s_register_operand" "r,r")
3903 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3904 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3908 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
3909 return \"%i5\\t%0, %1, %2, lsr #31\";
3911 output_asm_insn (\"cmp\\t%2, %3\", operands);
3912 if (GET_CODE (operands[5]) == AND)
3913 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
3914 else if (which_alternative != 0)
3915 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3916 return \"%i5%d4\\t%0, %1, #1\";
3918 [(set_attr "conds" "clob")
3919 (set_attr "length" "12")])
3922 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3923 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
3924 (match_operator:SI 4 "comparison_operator"
3925 [(match_operand:SI 2 "s_register_operand" "r,r")
3926 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
3930 output_asm_insn (\"cmp\\t%2, %3\", operands);
3931 if (which_alternative != 0)
3932 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3933 return \"sub%d4\\t%0, %1, #1\";
3935 [(set_attr "conds" "clob")
3936 (set_attr "length" "8,12")])
3939 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3940 (and:SI (match_operator 1 "comparison_operator"
3941 [(match_operand:SI 2 "s_register_operand" "r")
3942 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3943 (match_operator 4 "comparison_operator"
3944 [(match_operand:SI 5 "s_register_operand" "r")
3945 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3951 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
3952 reverse_condition (GET_CODE (operands[4])))
3954 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
3955 reverse_condition (GET_CODE (operands[1])))
3957 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3959 output_asm_insn (\"mov\\t%0, #1\", operands);
3960 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
3962 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
3963 : \"cmp%d1\\t%5, %6\", operands);
3967 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
3968 output_asm_insn (\"cmp\\t%5, %6\", operands);
3970 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
3973 [(set_attr "conds" "clob")
3974 (set_attr "length" "20")])
3978 (if_then_else (match_operator 1 "equality_operator"
3979 [(and:SI (match_operator 2 "comparison_operator"
3980 [(match_operand:SI 3 "s_register_operand" "")
3981 (match_operand:SI 4 "arm_add_operand" "")])
3982 (match_operator 0 "comparison_operator"
3983 [(match_operand:SI 5 "s_register_operand" "")
3984 (match_operand:SI 6 "arm_add_operand" "")]))
3986 (label_ref (match_operand 7 "" ""))
3989 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
3990 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
3991 reverse_condition (GET_CODE (operands[0])))
3992 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
3993 reverse_condition (GET_CODE (operands[2]))))"
3995 (compare:CC (ior:CC (match_op_dup 2
3996 [(match_dup 3) (match_dup 4)])
3998 [(match_dup 5) (match_dup 6)]))
4001 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4002 (label_ref (match_dup 7))
4006 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4007 This is safe since we only do it for integer comparisons. */
4008 enum rtx_code code =
4009 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4010 reverse_condition (GET_CODE (operands[0])))
4011 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4013 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4014 GET_MODE (operands[2]), operands[3], operands[4]);
4015 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4016 GET_MODE (operands[0]), operands[5], operands[6]);
4017 if (GET_CODE (operands[1]) == NE)
4018 operands[1] = gen_rtx (code, CCmode,
4019 XEXP (operands[1], 0), XEXP (operands[1], 1));
4021 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4022 XEXP (operands[1], 0), XEXP (operands[1], 1));
4026 ;; Don't match these patterns if we can use a conditional compare, since they
4027 ;; tell the final prescan branch elimator code that full branch inlining
4033 (eq (and:SI (match_operator 1 "comparison_operator"
4034 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4035 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
4036 (match_operator 4 "comparison_operator"
4037 [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
4038 (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
4040 (label_ref (match_operand 0 "" ""))
4043 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4044 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4045 reverse_condition (GET_CODE (operands[4])))
4046 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4047 reverse_condition (GET_CODE (operands[1]))))"
4050 extern int arm_ccfsm_state;
4052 if (which_alternative & 1)
4053 output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
4055 output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
4057 if (which_alternative >= 2)
4058 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4060 output_asm_insn (\"cmp\\t%5, %6\", operands);
4062 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4064 arm_ccfsm_state += 2;
4067 return \"b%D4\\t%l0\";
4069 [(set_attr "conds" "jump_clob")
4070 (set_attr "length" "16")])
4073 [(set (match_operand:SI 0 "s_register_operand" "=r")
4074 (neg:SI (match_operator 3 "comparison_operator"
4075 [(match_operand:SI 1 "s_register_operand" "r")
4076 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4080 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4081 return \"mov\\t%0, %1, asr #31\";
4083 if (GET_CODE (operands[3]) == NE)
4084 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4086 if (GET_CODE (operands[3]) == GT)
4087 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4089 output_asm_insn (\"cmp\\t%1, %2\", operands);
4090 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4091 return \"mvn%d3\\t%0, #0\";
4093 [(set_attr "conds" "clob")
4094 (set_attr "length" "12")])
4096 (define_insn "movcond"
4097 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4099 (match_operator 5 "comparison_operator"
4100 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4101 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4102 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4103 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4107 if (GET_CODE (operands[5]) == LT
4108 && (operands[4] == const0_rtx))
4110 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4112 if (operands[2] == const0_rtx)
4113 return \"and\\t%0, %1, %3, asr #31\";
4114 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4116 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4118 if (operands[1] == const0_rtx)
4119 return \"bic\\t%0, %2, %3, asr #31\";
4120 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4122 /* The only case that falls through to here is when both ops 1 & 2
4126 if (GET_CODE (operands[5]) == GE
4127 && (operands[4] == const0_rtx))
4129 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4131 if (operands[2] == const0_rtx)
4132 return \"bic\\t%0, %1, %3, asr #31\";
4133 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4135 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4137 if (operands[1] == const0_rtx)
4138 return \"and\\t%0, %2, %3, asr #31\";
4139 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4141 /* The only case that falls through to here is when both ops 1 & 2
4144 if (GET_CODE (operands[4]) == CONST_INT
4145 && !const_ok_for_arm (INTVAL (operands[4])))
4146 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4148 output_asm_insn (\"cmp\\t%3, %4\", operands);
4149 if (which_alternative != 0)
4150 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4151 if (which_alternative != 1)
4152 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4155 [(set_attr "conds" "clob")
4156 (set_attr "length" "8,8,12")])
4159 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4160 (if_then_else:SI (match_operator 9 "comparison_operator"
4161 [(match_operand:SI 5 "s_register_operand" "r,r")
4162 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4163 (match_operator:SI 8 "shiftable_operator"
4164 [(match_operand:SI 1 "s_register_operand" "r,r")
4165 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4166 (match_operator:SI 7 "shiftable_operator"
4167 [(match_operand:SI 3 "s_register_operand" "r,r")
4168 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4172 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4173 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4174 [(set_attr "conds" "clob")
4175 (set_attr "length" "12")])
4178 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4179 (if_then_else:SI (match_operator 6 "comparison_operator"
4180 [(match_operand:SI 2 "s_register_operand" "r,r")
4181 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4182 (match_operator:SI 7 "shiftable_operator"
4183 [(match_operand:SI 4 "s_register_operand" "r,r")
4184 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4185 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4189 /* If we have an operation where (op x 0) is the identity operation and
4190 the condtional operator is LT or GE and we are comparing against zero and
4191 everything is in registers then we can do this in two instructions */
4192 if (operands[3] == const0_rtx
4193 && GET_CODE (operands[7]) != AND
4194 && GET_CODE (operands[5]) == REG
4195 && GET_CODE (operands[1]) == REG
4196 && REGNO (operands[1]) == REGNO (operands[4])
4197 && REGNO (operands[4]) != REGNO (operands[0]))
4199 if (GET_CODE (operands[6]) == LT)
4200 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4201 else if (GET_CODE (operands[6]) == GE)
4202 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4204 if (GET_CODE (operands[3]) == CONST_INT
4205 && !const_ok_for_arm (INTVAL (operands[3])))
4206 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4208 output_asm_insn (\"cmp\\t%2, %3\", operands);
4209 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4210 if (which_alternative != 0)
4212 if (GET_CODE (operands[1]) == MEM)
4213 return \"ldr%D6\\t%0, %1\";
4215 return \"mov%D6\\t%0, %1\";
4219 [(set_attr "conds" "clob")
4220 (set_attr "length" "8,12")])
4223 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4224 (if_then_else:SI (match_operator 6 "comparison_operator"
4225 [(match_operand:SI 4 "s_register_operand" "r,r")
4226 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4227 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4228 (match_operator:SI 7 "shiftable_operator"
4229 [(match_operand:SI 2 "s_register_operand" "r,r")
4230 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4234 /* If we have an operation where (op x 0) is the identity operation and
4235 the condtional operator is LT or GE and we are comparing against zero and
4236 everything is in registers then we can do this in two instructions */
4237 if (operands[5] == const0_rtx
4238 && GET_CODE (operands[7]) != AND
4239 && GET_CODE (operands[3]) == REG
4240 && GET_CODE (operands[1]) == REG
4241 && REGNO (operands[1]) == REGNO (operands[2])
4242 && REGNO (operands[2]) != REGNO (operands[0]))
4244 if (GET_CODE (operands[6]) == GE)
4245 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4246 else if (GET_CODE (operands[6]) == LT)
4247 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4250 if (GET_CODE (operands[5]) == CONST_INT
4251 && !const_ok_for_arm (INTVAL (operands[5])))
4252 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4254 output_asm_insn (\"cmp\\t%4, %5\", operands);
4256 if (which_alternative != 0)
4258 if (GET_CODE (operands[1]) == MEM)
4259 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4261 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4263 return \"%I7%D6\\t%0, %2, %3\";
4265 [(set_attr "conds" "clob")
4266 (set_attr "length" "8,12")])
4269 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4270 (if_then_else:SI (match_operator 6 "comparison_operator"
4271 [(match_operand:SI 4 "s_register_operand" "r,r")
4272 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4274 (match_operand:SI 2 "s_register_operand" "r,r")
4275 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4276 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4281 if (GET_CODE (operands[5]) == CONST_INT
4282 && !const_ok_for_arm (INTVAL (operands[5])))
4283 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4285 output_asm_insn (\"cmp\\t%4, %5\", operands);
4286 if (GET_CODE (operands[3]) == CONST_INT
4287 && !const_ok_for_arm (INTVAL (operands[3])))
4288 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4290 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4291 if (which_alternative != 0)
4293 if (GET_CODE (operands[1]) == MEM)
4294 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4296 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4301 [(set_attr "conds" "clob")
4302 (set_attr "length" "8,12")])
4305 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4306 (if_then_else:SI (match_operator 6 "comparison_operator"
4307 [(match_operand:SI 4 "s_register_operand" "r,r")
4308 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4309 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4311 (match_operand:SI 2 "s_register_operand" "r,r")
4312 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4317 if (GET_CODE (operands[5]) == CONST_INT
4318 && !const_ok_for_arm (INTVAL (operands[5])))
4319 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4321 output_asm_insn (\"cmp\\t%4, %5\", operands);
4322 if (GET_CODE (operands[3]) == CONST_INT
4323 && !const_ok_for_arm (INTVAL (operands[3])))
4324 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4326 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4327 if (which_alternative != 0)
4329 if (GET_CODE (operands[6]) == MEM)
4330 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4332 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4337 [(set_attr "conds" "clob")
4338 (set_attr "length" "8,12")])
4341 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4342 (if_then_else:SI (match_operator 5 "comparison_operator"
4343 [(match_operand:SI 3 "s_register_operand" "r,r")
4344 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4345 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4347 (match_operand:SI 2 "s_register_operand" "r,r"))))
4351 [(set_attr "conds" "clob")
4352 (set_attr "length" "8,12")])
4355 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4357 (match_operator 5 "comparison_operator"
4358 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4359 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4361 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4362 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4366 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4367 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4368 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4369 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4370 [(set_attr "conds" "clob")
4371 (set_attr "length" "8,8,12,12")])
4374 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4376 (match_operator 6 "comparison_operator"
4377 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4378 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4379 (match_operator:SI 7 "shift_operator"
4380 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4381 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4382 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4386 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4387 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4388 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4389 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4390 [(set_attr "conds" "clob")
4391 (set_attr "length" "8,8,12,12")])
4394 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4396 (match_operator 6 "comparison_operator"
4397 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4398 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4399 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4400 (match_operator:SI 7 "shift_operator"
4401 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4402 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4406 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4407 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4408 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4409 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4410 [(set_attr "conds" "clob")
4411 (set_attr "length" "8,8,12,12")])
4414 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4416 (match_operator 7 "comparison_operator"
4417 [(match_operand:SI 5 "s_register_operand" "r,r")
4418 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4419 (match_operator:SI 8 "shift_operator"
4420 [(match_operand:SI 1 "s_register_operand" "r,r")
4421 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4422 (match_operator:SI 9 "shift_operator"
4423 [(match_operand:SI 3 "s_register_operand" "r,r")
4424 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4428 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4429 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4430 [(set_attr "conds" "clob")
4431 (set_attr "length" "12")])
4434 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4436 (match_operator 6 "comparison_operator"
4437 [(match_operand:SI 4 "s_register_operand" "r,r")
4438 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4439 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4440 (match_operator:SI 7 "shiftable_operator"
4441 [(match_operand:SI 2 "s_register_operand" "r,r")
4442 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4446 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4447 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4448 [(set_attr "conds" "clob")
4449 (set_attr "length" "12")])
4452 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4454 (match_operator 6 "comparison_operator"
4455 [(match_operand:SI 4 "s_register_operand" "r,r")
4456 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4457 (match_operator:SI 7 "shiftable_operator"
4458 [(match_operand:SI 2 "s_register_operand" "r,r")
4459 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4460 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4464 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4465 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4466 [(set_attr "conds" "clob")
4467 (set_attr "length" "12")])
4470 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4472 (match_operator 5 "comparison_operator"
4473 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4474 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4475 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4476 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4477 (clobber (reg:CC 24))]
4480 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4481 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4482 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4483 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4484 [(set_attr "conds" "clob")
4485 (set_attr "length" "8,8,12,12")])
4488 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4490 (match_operator 5 "comparison_operator"
4491 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4492 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4493 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4494 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4495 (clobber (reg:CC 24))]
4498 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4499 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4500 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4501 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4502 [(set_attr "conds" "clob")
4503 (set_attr "length" "8,8,12,12")])
4506 [(set (match_operand:SI 0 "s_register_operand" "=r")
4507 (match_operator:SI 1 "shiftable_operator"
4508 [(match_operand:SI 2 "memory_operand" "m")
4509 (match_operand:SI 3 "memory_operand" "m")]))
4510 (clobber (match_scratch:SI 4 "=r"))]
4511 "adjacent_mem_locations (operands[2], operands[3])"
4516 int val1 = 0, val2 = 0;
4518 if (REGNO (operands[0]) > REGNO (operands[4]))
4520 ldm[1] = operands[4];
4521 ldm[2] = operands[0];
4525 ldm[1] = operands[0];
4526 ldm[2] = operands[4];
4528 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4529 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4530 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4531 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4532 arith[0] = operands[0];
4533 arith[3] = operands[1];
4547 ldm[0] = ops[0] = operands[4];
4548 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4549 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4550 output_add_immediate (ops);
4552 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4554 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4558 ldm[0] = XEXP (operands[3], 0);
4560 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4562 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4566 ldm[0] = XEXP (operands[2], 0);
4568 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4570 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4572 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4576 [(set_attr "length" "12")
4577 (set_attr "type" "load")])
4579 ;; the arm can support extended pre-inc instructions
4581 ;; In all these cases, we use operands 0 and 1 for the register being
4582 ;; incremented because those are the operands that local-alloc will
4583 ;; tie and these are the pair most likely to be tieable (and the ones
4584 ;; that will benefit the most).
4586 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4587 ;; elimination will cause too many headaches.
4590 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4591 (match_operand:SI 2 "index_operand" "rJ")))
4592 (match_operand:QI 3 "s_register_operand" "r"))
4593 (set (match_operand:SI 0 "s_register_operand" "=r")
4594 (plus:SI (match_dup 1) (match_dup 2)))]
4595 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4596 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4597 && (GET_CODE (operands[2]) != REG
4598 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4599 "str%?b\\t%3, [%0, %2]!"
4600 [(set_attr "type" "store1")])
4603 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4604 (match_operand:SI 2 "s_register_operand" "r")))
4605 (match_operand:QI 3 "s_register_operand" "r"))
4606 (set (match_operand:SI 0 "s_register_operand" "=r")
4607 (minus:SI (match_dup 1) (match_dup 2)))]
4608 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4609 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4610 && (GET_CODE (operands[2]) != REG
4611 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4612 "str%?b\\t%3, [%0, -%2]!"
4613 [(set_attr "type" "store1")])
4616 [(set (match_operand:QI 3 "s_register_operand" "=r")
4617 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4618 (match_operand:SI 2 "index_operand" "rJ"))))
4619 (set (match_operand:SI 0 "s_register_operand" "=r")
4620 (plus:SI (match_dup 1) (match_dup 2)))]
4621 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4622 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4623 && (GET_CODE (operands[2]) != REG
4624 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4625 "ldr%?b\\t%3, [%0, %2]!"
4626 [(set_attr "type" "load")])
4629 [(set (match_operand:QI 3 "s_register_operand" "=r")
4630 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4631 (match_operand:SI 2 "s_register_operand" "r"))))
4632 (set (match_operand:SI 0 "s_register_operand" "=r")
4633 (minus:SI (match_dup 1) (match_dup 2)))]
4634 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4635 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4636 && (GET_CODE (operands[2]) != REG
4637 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4638 "ldr%?b\\t%3, [%0, -%2]!"
4639 [(set_attr "type" "load")])
4642 [(set (match_operand:SI 3 "s_register_operand" "=r")
4644 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4645 (match_operand:SI 2 "index_operand" "rJ")))))
4646 (set (match_operand:SI 0 "s_register_operand" "=r")
4647 (plus:SI (match_dup 1) (match_dup 2)))]
4648 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4649 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4650 && (GET_CODE (operands[2]) != REG
4651 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4652 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4653 [(set_attr "type" "load")])
4656 [(set (match_operand:SI 3 "s_register_operand" "=r")
4658 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4659 (match_operand:SI 2 "s_register_operand" "r")))))
4660 (set (match_operand:SI 0 "s_register_operand" "=r")
4661 (minus:SI (match_dup 1) (match_dup 2)))]
4662 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4663 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4664 && (GET_CODE (operands[2]) != REG
4665 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4666 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4667 [(set_attr "type" "load")])
4670 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4671 (match_operand:SI 2 "index_operand" "rJ")))
4672 (match_operand:SI 3 "s_register_operand" "r"))
4673 (set (match_operand:SI 0 "s_register_operand" "=r")
4674 (plus:SI (match_dup 1) (match_dup 2)))]
4675 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4676 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4677 && (GET_CODE (operands[2]) != REG
4678 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4679 "str%?\\t%3, [%0, %2]!"
4680 [(set_attr "type" "store1")])
4683 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4684 (match_operand:SI 2 "s_register_operand" "r")))
4685 (match_operand:SI 3 "s_register_operand" "r"))
4686 (set (match_operand:SI 0 "s_register_operand" "=r")
4687 (minus:SI (match_dup 1) (match_dup 2)))]
4688 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4689 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4690 && (GET_CODE (operands[2]) != REG
4691 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4692 "str%?\\t%3, [%0, -%2]!"
4693 [(set_attr "type" "store1")])
4696 [(set (match_operand:SI 3 "s_register_operand" "=r")
4697 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4698 (match_operand:SI 2 "index_operand" "rJ"))))
4699 (set (match_operand:SI 0 "s_register_operand" "=r")
4700 (plus:SI (match_dup 1) (match_dup 2)))]
4701 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4702 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4703 && (GET_CODE (operands[2]) != REG
4704 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4705 "ldr%?\\t%3, [%0, %2]!"
4706 [(set_attr "type" "load")])
4709 [(set (match_operand:SI 3 "s_register_operand" "=r")
4710 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4711 (match_operand:SI 2 "s_register_operand" "r"))))
4712 (set (match_operand:SI 0 "s_register_operand" "=r")
4713 (minus:SI (match_dup 1) (match_dup 2)))]
4714 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4715 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4716 && (GET_CODE (operands[2]) != REG
4717 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4718 "ldr%?\\t%3, [%0, -%2]!"
4719 [(set_attr "type" "load")])
4722 [(set (match_operand:HI 3 "s_register_operand" "=r")
4723 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4724 (match_operand:SI 2 "index_operand" "rJ"))))
4725 (set (match_operand:SI 0 "s_register_operand" "=r")
4726 (plus:SI (match_dup 1) (match_dup 2)))]
4727 "(! BYTES_BIG_ENDIAN)
4728 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4729 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4730 && (GET_CODE (operands[2]) != REG
4731 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4732 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4733 [(set_attr "type" "load")])
4736 [(set (match_operand:HI 3 "s_register_operand" "=r")
4737 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4738 (match_operand:SI 2 "s_register_operand" "r"))))
4739 (set (match_operand:SI 0 "s_register_operand" "=r")
4740 (minus:SI (match_dup 1) (match_dup 2)))]
4741 "(!BYTES_BIG_ENDIAN)
4742 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4743 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4744 && (GET_CODE (operands[2]) != REG
4745 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4746 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4747 [(set_attr "type" "load")])
4750 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4751 [(match_operand:SI 3 "s_register_operand" "r")
4752 (match_operand:SI 4 "const_shift_operand" "n")])
4753 (match_operand:SI 1 "s_register_operand" "0")))
4754 (match_operand:QI 5 "s_register_operand" "r"))
4755 (set (match_operand:SI 0 "s_register_operand" "=r")
4756 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4758 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4759 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4760 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4761 "str%?b\\t%5, [%0, %3%S2]!"
4762 [(set_attr "type" "store1")])
4765 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4766 (match_operator:SI 2 "shift_operator"
4767 [(match_operand:SI 3 "s_register_operand" "r")
4768 (match_operand:SI 4 "const_shift_operand" "n")])))
4769 (match_operand:QI 5 "s_register_operand" "r"))
4770 (set (match_operand:SI 0 "s_register_operand" "=r")
4771 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4773 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4774 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4775 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4776 "str%?b\\t%5, [%0, -%3%S2]!"
4777 [(set_attr "type" "store1")])
4780 [(set (match_operand:QI 5 "s_register_operand" "=r")
4781 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4782 [(match_operand:SI 3 "s_register_operand" "r")
4783 (match_operand:SI 4 "const_shift_operand" "n")])
4784 (match_operand:SI 1 "s_register_operand" "0"))))
4785 (set (match_operand:SI 0 "s_register_operand" "=r")
4786 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4788 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4789 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4790 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4791 "ldr%?b\\t%5, [%0, %3%S2]!"
4792 [(set_attr "type" "load")])
4795 [(set (match_operand:QI 5 "s_register_operand" "=r")
4796 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4797 (match_operator:SI 2 "shift_operator"
4798 [(match_operand:SI 3 "s_register_operand" "r")
4799 (match_operand:SI 4 "const_shift_operand" "n")]))))
4800 (set (match_operand:SI 0 "s_register_operand" "=r")
4801 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4803 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4804 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4805 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4806 "ldr%?b\\t%5, [%0, -%3%S2]!"
4807 [(set_attr "type" "load")])
4810 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4811 [(match_operand:SI 3 "s_register_operand" "r")
4812 (match_operand:SI 4 "const_shift_operand" "n")])
4813 (match_operand:SI 1 "s_register_operand" "0")))
4814 (match_operand:SI 5 "s_register_operand" "r"))
4815 (set (match_operand:SI 0 "s_register_operand" "=r")
4816 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4818 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4819 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4820 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4821 "str%?\\t%5, [%0, %3%S2]!"
4822 [(set_attr "type" "store1")])
4825 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4826 (match_operator:SI 2 "shift_operator"
4827 [(match_operand:SI 3 "s_register_operand" "r")
4828 (match_operand:SI 4 "const_shift_operand" "n")])))
4829 (match_operand:SI 5 "s_register_operand" "r"))
4830 (set (match_operand:SI 0 "s_register_operand" "=r")
4831 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4833 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4834 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4835 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4836 "str%?\\t%5, [%0, -%3%S2]!"
4837 [(set_attr "type" "store1")])
4840 [(set (match_operand:SI 5 "s_register_operand" "=r")
4841 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4842 [(match_operand:SI 3 "s_register_operand" "r")
4843 (match_operand:SI 4 "const_shift_operand" "n")])
4844 (match_operand:SI 1 "s_register_operand" "0"))))
4845 (set (match_operand:SI 0 "s_register_operand" "=r")
4846 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4848 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4849 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4850 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4851 "ldr%?\\t%5, [%0, %3%S2]!"
4852 [(set_attr "type" "load")])
4855 [(set (match_operand:SI 5 "s_register_operand" "=r")
4856 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4857 (match_operator:SI 2 "shift_operator"
4858 [(match_operand:SI 3 "s_register_operand" "r")
4859 (match_operand:SI 4 "const_shift_operand" "n")]))))
4860 (set (match_operand:SI 0 "s_register_operand" "=r")
4861 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4863 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4864 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4865 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4866 "ldr%?\\t%5, [%0, -%3%S2]!"
4867 [(set_attr "type" "load")])
4870 [(set (match_operand:HI 5 "s_register_operand" "=r")
4871 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
4872 [(match_operand:SI 3 "s_register_operand" "r")
4873 (match_operand:SI 4 "const_shift_operand" "n")])
4874 (match_operand:SI 1 "s_register_operand" "0"))))
4875 (set (match_operand:SI 0 "s_register_operand" "=r")
4876 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4878 "(! BYTES_BIG_ENDIAN)
4879 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4880 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4881 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4882 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
4883 [(set_attr "type" "load")])
4886 [(set (match_operand:HI 5 "s_register_operand" "=r")
4887 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4888 (match_operator:SI 2 "shift_operator"
4889 [(match_operand:SI 3 "s_register_operand" "r")
4890 (match_operand:SI 4 "const_shift_operand" "n")]))))
4891 (set (match_operand:SI 0 "s_register_operand" "=r")
4892 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4894 "(! BYTES_BIG_ENDIAN)
4895 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
4896 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4897 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4898 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
4899 [(set_attr "type" "load")])
4901 ; It can also support extended post-inc expressions, but combine doesn't
4903 ; It doesn't seem worth adding peepholes for anything but the most common
4904 ; cases since, unlike combine, the increment must immediately follow the load
4905 ; for this pattern to match.
4906 ; When loading we must watch to see that the base register isn't trampled by
4907 ; the load. In such cases this isn't a post-inc expression.
4910 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
4911 (match_operand:QI 2 "s_register_operand" "r"))
4913 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4915 "str%?b\\t%2, [%0], %1")
4918 [(set (match_operand:QI 0 "s_register_operand" "=r")
4919 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
4921 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
4922 "REGNO(operands[0]) != REGNO(operands[1])
4923 && (GET_CODE (operands[2]) != REG
4924 || REGNO(operands[0]) != REGNO (operands[2]))"
4925 "ldr%?b\\t%0, [%1], %2")
4928 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
4929 (match_operand:SI 2 "s_register_operand" "r"))
4931 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
4933 "str%?\\t%2, [%0], %1")
4936 [(set (match_operand:HI 0 "s_register_operand" "=r")
4937 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
4939 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
4940 "(! BYTES_BIG_ENDIAN)
4941 && REGNO(operands[0]) != REGNO(operands[1])
4942 && (GET_CODE (operands[2]) != REG
4943 || REGNO(operands[0]) != REGNO (operands[2]))"
4944 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
4947 [(set (match_operand:SI 0 "s_register_operand" "=r")
4948 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
4950 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
4951 "REGNO(operands[0]) != REGNO(operands[1])
4952 && (GET_CODE (operands[2]) != REG
4953 || REGNO(operands[0]) != REGNO (operands[2]))"
4954 "ldr%?\\t%0, [%1], %2")
4957 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
4958 (match_operand:SI 1 "index_operand" "rJ")))
4959 (match_operand:QI 2 "s_register_operand" "r"))
4960 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
4962 "str%?b\\t%2, [%0, %1]!")
4965 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
4966 [(match_operand:SI 0 "s_register_operand" "r")
4967 (match_operand:SI 1 "const_int_operand" "n")])
4968 (match_operand:SI 2 "s_register_operand" "+r")))
4969 (match_operand:QI 3 "s_register_operand" "r"))
4970 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
4973 "str%?b\\t%3, [%2, %0%S4]!")
4975 ; This pattern is never tried by combine, so do it as a peephole
4978 [(set (match_operand:SI 0 "s_register_operand" "=r")
4979 (match_operand:SI 1 "s_register_operand" "r"))
4980 (set (match_operand 2 "cc_register" "")
4981 (compare (match_dup 1) (const_int 0)))]
4983 "sub%?s\\t%0, %1, #0"
4984 [(set_attr "conds" "set")])
4986 ; Peepholes to spot possible load- and store-multiples, if the ordering is
4987 ; reversed, check that the memory references aren't volatile.
4990 [(set (match_operand:SI 0 "s_register_operand" "=r")
4991 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
4993 (set (match_operand:SI 2 "s_register_operand" "=r")
4994 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
4995 (set (match_operand:SI 3 "s_register_operand" "=r")
4996 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
4997 (set (match_operand:SI 4 "s_register_operand" "=r")
4998 (mem:SI (match_dup 1)))]
4999 "REGNO (operands[0]) > REGNO (operands[2])
5000 && REGNO (operands[2]) > REGNO (operands[3])
5001 && REGNO (operands[3]) > REGNO (operands[4])
5002 && !(REGNO (operands[1]) == REGNO (operands[0])
5003 || REGNO (operands[1]) == REGNO (operands[2])
5004 || REGNO (operands[1]) == REGNO (operands[3])
5005 || REGNO (operands[1]) == REGNO (operands[4]))
5006 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5007 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5008 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5009 (prev_nonnote_insn (insn)))))
5010 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5012 (prev_nonnote_insn (insn))))))"
5013 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5016 [(set (match_operand:SI 0 "s_register_operand" "=r")
5017 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5019 (set (match_operand:SI 2 "s_register_operand" "=r")
5020 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5021 (set (match_operand:SI 3 "s_register_operand" "=r")
5022 (mem:SI (match_dup 1)))]
5023 "REGNO (operands[0]) > REGNO (operands[2])
5024 && REGNO (operands[2]) > REGNO (operands[3])
5025 && !(REGNO (operands[1]) == REGNO (operands[0])
5026 || REGNO (operands[1]) == REGNO (operands[2])
5027 || REGNO (operands[1]) == REGNO (operands[3]))
5028 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5029 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5030 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5031 (prev_nonnote_insn (insn)))))"
5032 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5035 [(set (match_operand:SI 0 "s_register_operand" "=r")
5036 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5038 (set (match_operand:SI 2 "s_register_operand" "=r")
5039 (mem:SI (match_dup 1)))]
5040 "REGNO (operands[0]) > REGNO (operands[2])
5041 && !(REGNO (operands[1]) == REGNO (operands[0])
5042 || REGNO (operands[1]) == REGNO (operands[2]))
5043 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5044 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5045 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5048 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5050 (match_operand:SI 0 "s_register_operand" "r"))
5051 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5052 (match_operand:SI 2 "s_register_operand" "r"))
5053 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5054 (match_operand:SI 3 "s_register_operand" "r"))
5055 (set (mem:SI (match_dup 1))
5056 (match_operand:SI 4 "s_register_operand" "r"))]
5057 "REGNO (operands[0]) > REGNO (operands[2])
5058 && REGNO (operands[2]) > REGNO (operands[3])
5059 && REGNO (operands[3]) > REGNO (operands[4])
5060 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5061 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5062 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5063 (prev_nonnote_insn (insn)))))
5064 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5066 (prev_nonnote_insn (insn))))))"
5067 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5070 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5072 (match_operand:SI 0 "s_register_operand" "r"))
5073 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5074 (match_operand:SI 2 "s_register_operand" "r"))
5075 (set (mem:SI (match_dup 1))
5076 (match_operand:SI 3 "s_register_operand" "r"))]
5077 "REGNO (operands[0]) > REGNO (operands[2])
5078 && REGNO (operands[2]) > REGNO (operands[3])
5079 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5080 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5081 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5082 (prev_nonnote_insn (insn)))))"
5083 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5086 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5088 (match_operand:SI 0 "s_register_operand" "r"))
5089 (set (mem:SI (match_dup 1))
5090 (match_operand:SI 2 "s_register_operand" "r"))]
5091 "REGNO (operands[0]) > REGNO (operands[2])
5092 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5093 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5094 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5096 ;; A call followed by return can be replaced by restoring the regs and
5097 ;; jumping to the subroutine, provided we aren't passing the address of
5098 ;; any of our local variables. If we call alloca then this is unsafe
5099 ;; since restoring the frame frees the memory, which is not what we want.
5100 ;; Sometimes the return might have been targeted by the final prescan:
5101 ;; if so then emit a propper return insn as well.
5102 ;; Unfortunately, if the frame pointer is required, we don't know if the
5103 ;; current function has any implicit stack pointer adjustments that will
5104 ;; be restored by the return: we can't therefore do a tail call.
5105 ;; Another unfortunate that we can't handle is if current_function_args_size
5106 ;; is non-zero: in this case elimination of the argument pointer assumed
5107 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5111 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5112 (match_operand:SI 1 "general_operand" "g"))
5113 (clobber (reg:SI 14))])
5115 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5116 && !get_frame_size () && !current_function_calls_alloca
5117 && !frame_pointer_needed && !current_function_args_size)"
5120 extern rtx arm_target_insn;
5121 extern int arm_ccfsm_state, arm_current_cc;
5123 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5125 arm_current_cc ^= 1;
5126 output_return_instruction (NULL, TRUE);
5127 arm_ccfsm_state = 0;
5128 arm_target_insn = NULL;
5131 output_return_instruction (NULL, FALSE);
5132 return \"b%?\\t%a0\";
5134 [(set (attr "conds")
5135 (if_then_else (eq_attr "cpu" "arm6")
5136 (const_string "clob")
5137 (const_string "nocond")))
5138 (set_attr "length" "8")])
5141 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5142 (call (mem:SI (match_operand:SI 1 "" "i"))
5143 (match_operand:SI 2 "general_operand" "g")))
5144 (clobber (reg:SI 14))])
5146 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5147 && !get_frame_size () && !current_function_calls_alloca
5148 && !frame_pointer_needed && !current_function_args_size)"
5151 extern rtx arm_target_insn;
5152 extern int arm_ccfsm_state, arm_current_cc;
5154 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5156 arm_current_cc ^= 1;
5157 output_return_instruction (NULL, TRUE);
5158 arm_ccfsm_state = 0;
5159 arm_target_insn = NULL;
5162 output_return_instruction (NULL, FALSE);
5163 return \"b%?\\t%a1\";
5165 [(set (attr "conds")
5166 (if_then_else (eq_attr "cpu" "arm6")
5167 (const_string "clob")
5168 (const_string "nocond")))
5169 (set_attr "length" "8")])
5171 ;; As above but when this function is not void, we must be returning the
5172 ;; result of the called subroutine.
5175 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5176 (call (mem:SI (match_operand:SI 1 "" "i"))
5177 (match_operand:SI 2 "general_operand" "g")))
5178 (clobber (reg:SI 14))])
5181 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5182 && !get_frame_size () && !current_function_calls_alloca
5183 && !frame_pointer_needed && !current_function_args_size)"
5186 extern rtx arm_target_insn;
5187 extern int arm_ccfsm_state, arm_current_cc;
5189 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5191 arm_current_cc ^= 1;
5192 output_return_instruction (NULL, TRUE);
5193 arm_ccfsm_state = 0;
5194 arm_target_insn = NULL;
5197 output_return_instruction (NULL, FALSE);
5198 return \"b%?\\t%a1\";
5200 [(set (attr "conds")
5201 (if_then_else (eq_attr "cpu" "arm6")
5202 (const_string "clob")
5203 (const_string "nocond")))
5204 (set_attr "length" "8")])
5206 ;; If calling a subroutine and then jumping back to somewhere else, but not
5207 ;; too far away, then we can set the link register with the branch address
5208 ;; and jump direct to the subroutine. On return from the subroutine
5209 ;; execution continues at the branch; this avoids a prefetch stall.
5210 ;; We use the length attribute (via short_branch ()) to establish whether or
5211 ;; not this is possible, this is the same asthe sparc does.
5214 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5215 (match_operand:SI 1 "general_operand" "g"))
5216 (clobber (reg:SI 14))])
5218 (label_ref (match_operand 2 "" "")))]
5219 "GET_CODE (operands[0]) == SYMBOL_REF
5220 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5221 && arm_insn_not_targeted (insn)"
5224 int backward = arm_backwards_branch (INSN_UID (insn),
5225 INSN_UID (operands[2]));
5228 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5229 * above, leaving it out means that the code will still run on an arm 2 or 3
5234 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5236 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5241 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5243 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5245 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5247 return \"b%?\\t%a0\";
5249 [(set (attr "conds")
5250 (if_then_else (eq_attr "cpu" "arm6")
5251 (const_string "clob")
5252 (const_string "nocond")))
5253 (set (attr "length")
5254 (if_then_else (eq_attr "cpu" "arm6")
5259 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5260 (call (mem:SI (match_operand:SI 1 "" "i"))
5261 (match_operand:SI 2 "general_operand" "g")))
5262 (clobber (reg:SI 14))])
5264 (label_ref (match_operand 3 "" "")))]
5265 "GET_CODE (operands[0]) == SYMBOL_REF
5266 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5267 && arm_insn_not_targeted (insn)"
5270 int backward = arm_backwards_branch (INSN_UID (insn),
5271 INSN_UID (operands[3]));
5274 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5275 * above, leaving it out means that the code will still run on an arm 2 or 3
5280 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5282 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5287 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5289 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5291 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5293 return \"b%?\\t%a1\";
5295 [(set (attr "conds")
5296 (if_then_else (eq_attr "cpu" "arm6")
5297 (const_string "clob")
5298 (const_string "nocond")))
5299 (set (attr "length")
5300 (if_then_else (eq_attr "cpu" "arm6")
5306 (if_then_else (match_operator 0 "comparison_operator"
5307 [(match_operator:SI 1 "shift_operator"
5308 [(match_operand:SI 2 "s_register_operand" "r")
5309 (match_operand:SI 3 "reg_or_int_operand" "rM")])
5310 (match_operand:SI 4 "s_register_operand" "r")])
5311 (label_ref (match_operand 5 "" ""))
5316 (compare:CC (match_dup 4)
5317 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5319 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5320 (label_ref (match_dup 5))
5323 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5324 operands[1], operands[2]);
5328 [(set (match_operand:SI 0 "s_register_operand" "")
5329 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5331 (neg:SI (match_operator:SI 2 "comparison_operator"
5332 [(match_operand:SI 3 "s_register_operand" "")
5333 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5334 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5336 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5337 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5341 ;; This pattern can be used because cc_noov mode implies that the following
5342 ;; branch will be an equality (EQ or NE), so the sign extension is not
5343 ;; needed. Combine doesn't eliminate these because by the time it sees the
5344 ;; branch it no-longer knows that the data came from memory.
5347 [(set (reg:CC_NOOV 24)
5349 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5351 (match_operand 1 "immediate_operand" "I")))
5352 (clobber (match_scratch:SI 2 "=r"))]
5353 "((unsigned long) INTVAL (operands[1]))
5354 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5356 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5357 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5358 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5361 [(set_attr "conds" "set")
5362 (set_attr "length" "8")
5363 (set_attr "type" "load")])
5365 (define_expand "prologue"
5366 [(clobber (const_int 0))]
5369 arm_expand_prologue ();
5373 (define_expand "save_stack_nonlocal"
5374 [(match_operand:DI 0 "memory_operand" "")
5375 (match_operand:SI 1 "s_register_operand" "")]
5379 /* We also need to save the frame pointer for non-local gotos */
5380 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
5381 hard_frame_pointer_rtx);
5382 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
5386 (define_expand "restore_stack_nonlocal"
5387 [(match_operand:SI 0 "s_register_operand" "")
5388 (match_operand:DI 1 "memory_operand" "")]
5392 /* Restore the frame pointer first, the stack pointer second. */
5393 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
5394 emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0,
5399 ;; This split is only used during output to reduce the number of patterns
5400 ;; that need assembler instructions adding to them. We allowed the setting
5401 ;; of the conditions to be implicit during rtl generation so that
5402 ;; the conditional compare patterns would work. However this conflicts to
5403 ;; some extend with the conditional data operations, so we have to split them
5407 [(set (match_operand:SI 0 "s_register_operand" "")
5408 (if_then_else:SI (match_operator 1 "comparison_operator"
5409 [(match_operand 2 "" "") (match_operand 3 "" "")])
5410 (match_operand 4 "" "")
5411 (match_operand 5 "" "")))
5414 [(set (match_dup 6) (match_dup 7))
5416 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5421 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5424 operands[6] = gen_rtx (REG, mode, 24);
5425 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5431 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5432 (if_then_else:SI (match_operator 4 "comparison_operator"
5433 [(match_operand 3 "cc_register" "") (const_int 0)])
5434 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5436 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5440 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5441 [(set_attr "conds" "use")
5442 (set_attr "length" "4,8")])
5444 ;; The next two patterns occur when an AND operation is followed by a
5445 ;; scc insn sequence
5448 [(set (match_operand:SI 0 "s_register_operand" "=r")
5449 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5451 (match_operand:SI 2 "immediate_operand" "n")))]
5454 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5455 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5456 return \"mvnne\\t%0, #0\";
5458 [(set_attr "conds" "clob")
5459 (set_attr "length" "8")])
5462 [(set (match_operand:SI 0 "s_register_operand" "=r")
5464 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5466 (match_operand:SI 2 "immediate_operand" "n"))))]
5469 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5470 output_asm_insn (\"tst\\t%1, %2\", operands);
5471 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5472 return \"movne\\t%0, #0\";
5474 [(set_attr "conds" "clob")
5475 (set_attr "length" "12")])
5477 ;; Push multiple registers to the stack. The first register is in the
5478 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5481 [(match_parallel 2 "multi_register_push"
5482 [(set (match_operand:BLK 0 "memory_operand" "=m")
5483 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5489 extern int lr_save_eliminated;
5491 if (lr_save_eliminated)
5493 if (XVECLEN (operands[2], 0) > 1)
5497 strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
5498 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5500 strcat (pattern, \", %|\");
5501 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5504 strcat (pattern, \"}\");
5505 output_asm_insn (pattern, operands);
5508 [(set_attr "type" "store4")])