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
37 ; condition codes: this one is used by final_prescan_insn to speed up
38 ; conditionalizing instructions. It saves having to scan the rtl to see if
39 ; it uses or alters the condition codes.
41 ; USE means that the condition codes are used by the insn in the process of
42 ; outputting code, this means (at present) that we can't use the insn in
45 ; SET means that the purpose of the insn is to set the condition codes in a
46 ; well defined manner.
48 ; CLOB means that the condition codes are altered in an undefined manner, if
49 ; they are altered at all
51 ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
52 ; but are if the branch wasn't taken; the effect is to limit the branch
53 ; elimination scanning.
55 ; NOCOND means that the condition codes are niether altered nor affect the
58 (define_attr "conds" "use,set,clob,jump_clob,nocond"
59 (const_string "nocond"))
61 ; CPU attribute is used to determine whether condition codes are clobbered
62 ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
63 ; arm2 and arm3 the condition codes are restored by the return.
65 (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
67 ; LENGTH of an instruction (in bytes)
68 (define_attr "length" "" (const_int 4))
70 ; An assembler sequence may clobber the condition codes without us knowing
71 (define_asm_attributes
72 [(set_attr "conds" "clob")
73 (set_attr "length" "4")])
75 ; TYPE attribute is used to detect floating point instructions which, if
76 ; running on a co-processor can run in parallel with other, basic instructions
77 ; If write-buffer scheduling is enabled then it can also be used in the
78 ; scheduling of writes.
80 ; Classification of each insn
81 ; normal any data instruction that doesn't hit memory or fp regs
82 ; block blockage insn, this blocks all functional units
83 ; float a floating point arithmetic operation (subject to expansion)
84 ; float_em a floating point arithmetic operation that is normally emulated
85 ; f_load a floating point load from memory
86 ; f_store a floating point store to memory
87 ; f_mem_r a transfer of a floating point register to a real reg via mem
88 ; r_mem_f the reverse of f_mem_r
89 ; f_2_r fast transfer float to arm (no memory needed)
90 ; r_2_f fast transfer arm to float
91 ; call a subroutine call
92 ; load any load from memory
93 ; store1 store 1 word to memory from arm registers
94 ; store2 store 2 words
95 ; store3 store 3 words
96 ; store4 store 4 words
99 "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"
100 (const_string "normal"))
102 (define_attr "write_conflict" "no,yes"
103 (if_then_else (eq_attr "type"
104 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
106 (const_string "no")))
108 ; The write buffer on some of the arm6 processors is hard to model exactly.
109 ; There is room in the buffer for up to two addresses and up to eight words
110 ; of memory, but the two needn't be split evenly. When writing the two
111 ; addresses are fully pipelined. However, a read from memory that is not
112 ; currently in the cache will block until the writes have completed.
113 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
114 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
115 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
116 ; cycle to add as well.
118 ;; (define_function_unit {name} {num-units} {n-users} {test}
119 ;; {ready-delay} {issue-delay} [{conflict-list}])
120 ;; This is not well tuned, but I don't have all the details.
121 (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0)
123 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
124 [(eq_attr "write_conflict" "yes")])
125 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
126 [(eq_attr "write_conflict" "yes")])
127 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
128 [(eq_attr "write_conflict" "yes")])
129 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
130 [(eq_attr "write_conflict" "yes")])
131 (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
132 [(eq_attr "write_conflict" "yes")])
134 ;; Note: For DImode insns, there is normally no reason why operands should
135 ;; not be in the same register, what we don't want is for something being
136 ;; written to partially overlap something that is an input.
140 (define_insn "adddi3"
141 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
142 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
143 (match_operand:DI 2 "s_register_operand" "r,0")))
144 (clobber (reg:CC 24))]
146 "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
147 [(set_attr "conds" "clob")
148 (set_attr "length" "8")])
151 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
152 (plus:DI (sign_extend:DI
153 (match_operand:SI 1 "s_register_operand" "r,r"))
154 (match_operand:DI 2 "s_register_operand" "r,0")))
155 (clobber (reg:CC 24))]
157 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
158 [(set_attr "conds" "clob")
159 (set_attr "length" "8")])
162 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
163 (plus:DI (zero_extend:DI
164 (match_operand:SI 1 "s_register_operand" "r,r"))
165 (match_operand:DI 2 "s_register_operand" "r,0")))
166 (clobber (reg:CC 24))]
168 "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
169 [(set_attr "conds" "clob")
170 (set_attr "length" "8")])
172 (define_insn "addsi3"
173 [(set (match_operand:SI 0 "s_register_operand" "=r")
174 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
175 (match_operand:SI 2 "arm_add_operand" "rL")))]
178 if (GET_CODE (operands[2]) == CONST_INT
179 && !const_ok_for_arm (INTVAL (operands[2])))
180 return \"sub%?\\t%0, %1, #%n2\";
181 return \"add%?\\t%0, %1, %2\";
185 [(set (reg:CC_NOOV 24)
186 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "s_register_operand" "r")
187 (match_operand:SI 2 "arm_add_operand" "rL"))
189 (set (match_operand:SI 0 "s_register_operand" "=r")
190 (plus:SI (match_dup 1) (match_dup 2)))]
193 if (GET_CODE (operands[2]) == CONST_INT
194 && !const_ok_for_arm (INTVAL (operands[2])))
195 return \"sub%?s\\t%0, %1, #%n2\";
196 return \"add%?s\\t%0, %1, %2\";
198 [(set_attr "conds" "set")])
202 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
203 (neg:SI (match_operand:SI 2 "arm_add_operand" "rL"))))
204 (set (match_operand:SI 0 "s_register_operand" "=r")
205 (plus:SI (match_dup 1) (match_dup 2)))]
208 if (GET_CODE (operands[2]) == CONST_INT
209 && !const_ok_for_arm (INTVAL (operands[2])))
210 return \"sub%?s\\t%0, %1, #%n2\";
211 return \"add%?s\\t%0, %1, %2\";
213 [(set_attr "conds" "set")])
215 (define_insn "incscc"
216 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
217 (plus:SI (match_operator:SI 2 "comparison_operator"
218 [(reg 24) (const_int 0)])
219 (match_operand:SI 1 "s_register_operand" "0,?r")))]
222 if (which_alternative == 1)
223 output_asm_insn (\"mov%D2\\t%0, %1\", operands);
224 return \"add%d2\\t%0, %1, #1\";
226 [(set_attr "conds" "use")
227 (set_attr "length" "*,8")])
229 ; If a constant is too big to fit in a single instruction then the constant
230 ; will be pre-loaded into a register taking at least two insns, we might be
231 ; able to merge it with an add, but it depends on the exact value.
234 [(set (match_operand:SI 0 "s_register_operand" "=r")
235 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
236 (match_operand:SI 2 "immediate_operand" "n")))]
237 "!(const_ok_for_arm (INTVAL (operands[2]))
238 || const_ok_for_arm (-INTVAL (operands[2])))"
239 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
240 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
243 unsigned int val = (unsigned) INTVAL (operands[2]);
247 /* this code is similar to the approach followed in movsi, but it must
248 generate exactly two insns */
250 for (i = 30; i >= 0; i -= 2)
256 if (const_ok_for_arm (temp = (val & ~(255 << i))))
261 /* we might be able to do this as (larger number - small number) */
262 temp = ((val >> i) & 255) + 1;
263 if (temp > 255 && i < 24)
266 temp = ((val >> i) & 255) + 1;
268 if (const_ok_for_arm ((temp << i) - val))
271 temp = (unsigned) - (int) (i - val);
278 /* if we got here, we have found a way of doing it in two instructions.
279 the two constants are in val and temp */
280 operands[2] = GEN_INT ((int)val);
281 operands[3] = GEN_INT ((int)temp);
285 (define_insn "addsf3"
286 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
287 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
288 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
294 switch (which_alternative)
297 return \"adf%?s\\t%0, %1, %2\";
299 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
300 r = REAL_VALUE_NEGATE (r);
301 operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
302 output_asm_insn (\"suf%?s\\t%0, %1, %2\", operands);
307 [(set_attr "type" "float")])
309 (define_insn "adddf3"
310 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
311 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
312 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
318 switch (which_alternative)
321 return \"adf%?d\\t%0, %1, %2\";
323 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
324 r = REAL_VALUE_NEGATE (r);
325 operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
326 output_asm_insn (\"suf%?d\\t%0, %1, %2\", operands);
331 [(set_attr "type" "float")])
334 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
335 (plus:DF (float_extend:DF
336 (match_operand:SF 1 "s_register_operand" "f,f"))
337 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
343 switch (which_alternative)
346 return \"adf%?d\\t%0, %1, %2\";
348 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
349 r = REAL_VALUE_NEGATE (r);
350 operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
351 output_asm_insn (\"suf%?d\\t%0, %1, %2\", operands);
356 [(set_attr "type" "float")])
359 [(set (match_operand:DF 0 "s_register_operand" "=f")
360 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
362 (match_operand:SF 2 "s_register_operand" "f"))))]
364 "adf%?d\\t%0, %1, %2"
365 [(set_attr "type" "float")])
368 [(set (match_operand:DF 0 "s_register_operand" "=f")
369 (plus:DF (float_extend:DF
370 (match_operand:SF 1 "s_register_operand" "f"))
372 (match_operand:SF 2 "s_register_operand" "f"))))]
374 "adf%?d\\t%0, %1, %2"
375 [(set_attr "type" "float")])
377 (define_insn "addxf3"
378 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
379 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
380 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
386 switch (which_alternative)
389 return \"adf%?e\\t%0, %1, %2\";
391 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
392 r = REAL_VALUE_NEGATE (r);
393 operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
394 output_asm_insn (\"suf%?e\\t%0, %1, %2\", operands);
399 [(set_attr "type" "float")])
401 (define_insn "subdi3"
402 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
403 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
404 (match_operand:DI 2 "s_register_operand" "r,0,0")))
405 (clobber (reg:CC 24))]
407 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
408 [(set_attr "conds" "clob")
409 (set_attr "length" "8")])
412 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
413 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
415 (match_operand:SI 2 "s_register_operand" "r,r"))))
416 (clobber (reg:CC 24))]
418 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
419 [(set_attr "conds" "clob")
420 (set_attr "length" "8")])
423 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
424 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
426 (match_operand:SI 2 "s_register_operand" "r,r"))))
427 (clobber (reg:CC 24))]
429 "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
430 [(set_attr "conds" "clob")
431 (set_attr "length" "8")])
434 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
435 (minus:DI (zero_extend:DI
436 (match_operand:SI 2 "s_register_operand" "r,r"))
437 (match_operand:DI 1 "s_register_operand" "?r,0")))
438 (clobber (reg:CC 24))]
440 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
441 [(set_attr "conds" "clob")
442 (set_attr "length" "8")])
445 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
446 (minus:DI (sign_extend:DI
447 (match_operand:SI 2 "s_register_operand" "r,r"))
448 (match_operand:DI 1 "s_register_operand" "?r,0")))
449 (clobber (reg:CC 24))]
451 "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
452 [(set_attr "conds" "clob")
453 (set_attr "length" "8")])
456 [(set (match_operand:DI 0 "s_register_operand" "=r")
457 (minus:DI (zero_extend:DI
458 (match_operand:SI 1 "s_register_operand" "r"))
460 (match_operand:SI 2 "s_register_operand" "r"))))
461 (clobber (reg:CC 24))]
463 "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
464 [(set_attr "conds" "clob")
465 (set_attr "length" "8")])
467 (define_insn "subsi3"
468 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
469 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
470 (match_operand:SI 2 "arm_rhs_operand" "rI,r")))]
477 [(set (reg:CC_NOOV 24)
478 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
479 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
481 (set (match_operand:SI 0 "s_register_operand" "=r,r")
482 (minus:SI (match_dup 1) (match_dup 2)))]
487 [(set_attr "conds" "set")])
489 (define_insn "decscc"
490 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
491 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
492 (match_operator:SI 2 "comparison_operator"
493 [(reg 24) (const_int 0)])))]
497 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
498 [(set_attr "conds" "use")
499 (set_attr "length" "*,8")])
501 (define_insn "subsf3"
502 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
503 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
504 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
509 [(set_attr "type" "float")])
511 (define_insn "subdf3"
512 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
513 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
514 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
519 [(set_attr "type" "float")])
522 [(set (match_operand:DF 0 "s_register_operand" "=f")
523 (minus:DF (float_extend:DF
524 (match_operand:SF 1 "s_register_operand" "f"))
525 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
527 "suf%?d\\t%0, %1, %2"
528 [(set_attr "type" "float")])
531 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
532 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
534 (match_operand:SF 2 "s_register_operand" "f,f"))))]
539 [(set_attr "type" "float")])
542 [(set (match_operand:DF 0 "s_register_operand" "=f")
543 (minus:DF (float_extend:DF
544 (match_operand:SF 1 "s_register_operand" "f"))
546 (match_operand:SF 2 "s_register_operand" "f"))))]
548 "suf%?d\\t%0, %1, %2"
549 [(set_attr "type" "float")])
551 (define_insn "subxf3"
552 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
553 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
554 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
559 [(set_attr "type" "float")])
561 ;; Multiplication insns
563 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
564 (define_insn "mulsi3"
565 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
566 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
567 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
569 "mul%?\\t%0, %2, %1")
572 [(set (reg:CC_NOOV 24)
573 (compare:CC_NOOV (mult:SI
574 (match_operand:SI 2 "s_register_operand" "r,r")
575 (match_operand:SI 1 "s_register_operand" "%?r,0"))
577 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
578 (mult:SI (match_dup 2) (match_dup 1)))]
580 "mul%?s\\t%0, %2, %1"
581 [(set_attr "conds" "set")])
584 [(set (reg:CC_NOOV 24)
585 (compare:CC_NOOV (mult:SI
586 (match_operand:SI 2 "s_register_operand" "r,r")
587 (match_operand:SI 1 "s_register_operand" "%?r,0"))
589 (clobber (match_scratch:SI 0 "=&r,&r"))]
591 "mul%?s\\t%0, %2, %1"
592 [(set_attr "conds" "set")])
594 ;; Unnamed templates to match MLA instruction.
597 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
599 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
600 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
601 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
603 "mla%?\\t%0, %2, %1, %3")
606 [(set (reg:CC_NOOV 24)
607 (compare:CC_NOOV (plus:SI
609 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
610 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
611 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
613 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
614 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
617 "mla%?s\\t%0, %2, %1, %3"
618 [(set_attr "conds" "set")])
621 [(set (reg:CC_NOOV 24)
622 (compare:CC_NOOV (plus:SI
624 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
625 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
626 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
628 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
630 "mla%?s\\t%0, %2, %1, %3"
631 [(set_attr "conds" "set")])
633 (define_insn "mulsf3"
634 [(set (match_operand:SF 0 "s_register_operand" "=f")
635 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
636 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
638 "fml%?s\\t%0, %1, %2"
639 [(set_attr "type" "float")])
641 (define_insn "muldf3"
642 [(set (match_operand:DF 0 "s_register_operand" "=f")
643 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
644 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
646 "muf%?d\\t%0, %1, %2"
647 [(set_attr "type" "float")])
650 [(set (match_operand:DF 0 "s_register_operand" "=f")
651 (mult:DF (float_extend:DF
652 (match_operand:SF 1 "s_register_operand" "f"))
653 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
655 "muf%?d\\t%0, %1, %2"
656 [(set_attr "type" "float")])
659 [(set (match_operand:DF 0 "s_register_operand" "=f")
660 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
662 (match_operand:SF 2 "s_register_operand" "f"))))]
664 "muf%?d\\t%0, %1, %2"
665 [(set_attr "type" "float")])
668 [(set (match_operand:DF 0 "s_register_operand" "=f")
669 (mult:DF (float_extend:DF
670 (match_operand:SF 1 "s_register_operand" "f"))
672 (match_operand:SF 2 "s_register_operand" "f"))))]
674 "muf%?d\\t%0, %1, %2"
675 [(set_attr "type" "float")])
677 (define_insn "mulxf3"
678 [(set (match_operand:XF 0 "s_register_operand" "=f")
679 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
680 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
682 "muf%?e\\t%0, %1, %2"
683 [(set_attr "type" "float")])
687 (define_insn "divsf3"
688 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
689 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
690 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
695 [(set_attr "type" "float")])
697 (define_insn "divdf3"
698 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
699 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
700 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
705 [(set_attr "type" "float")])
708 [(set (match_operand:DF 0 "s_register_operand" "=f")
709 (div:DF (float_extend:DF
710 (match_operand:SF 1 "s_register_operand" "f"))
711 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
713 "dvf%?d\\t%0, %1, %2"
714 [(set_attr "type" "float")])
717 [(set (match_operand:DF 0 "s_register_operand" "=f")
718 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
720 (match_operand:SF 2 "s_register_operand" "f"))))]
722 "rdf%?d\\t%0, %2, %1"
723 [(set_attr "type" "float")])
726 [(set (match_operand:DF 0 "s_register_operand" "=f")
727 (div:DF (float_extend:DF
728 (match_operand:SF 1 "s_register_operand" "f"))
730 (match_operand:SF 2 "s_register_operand" "f"))))]
732 "dvf%?d\\t%0, %1, %2"
733 [(set_attr "type" "float")])
735 (define_insn "divxf3"
736 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
737 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
738 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
743 [(set_attr "type" "float")])
747 (define_insn "modsf3"
748 [(set (match_operand:SF 0 "s_register_operand" "=f")
749 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
750 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
752 "rmf%?s\\t%0, %1, %2"
753 [(set_attr "type" "float")])
755 (define_insn "moddf3"
756 [(set (match_operand:DF 0 "s_register_operand" "=f")
757 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
758 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
760 "rmf%?d\\t%0, %1, %2"
761 [(set_attr "type" "float")])
764 [(set (match_operand:DF 0 "s_register_operand" "=f")
765 (mod:DF (float_extend:DF
766 (match_operand:SF 1 "s_register_operand" "f"))
767 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
769 "rmf%?d\\t%0, %1, %2"
770 [(set_attr "type" "float")])
773 [(set (match_operand:DF 0 "s_register_operand" "=f")
774 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
776 (match_operand:SF 2 "s_register_operand" "f"))))]
778 "rmf%?d\\t%0, %1, %2"
779 [(set_attr "type" "float")])
782 [(set (match_operand:DF 0 "s_register_operand" "=f")
783 (mod:DF (float_extend:DF
784 (match_operand:SF 1 "s_register_operand" "f"))
786 (match_operand:SF 2 "s_register_operand" "f"))))]
788 "rmf%?d\\t%0, %1, %2"
789 [(set_attr "type" "float")])
791 (define_insn "modxf3"
792 [(set (match_operand:XF 0 "s_register_operand" "=f")
793 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
794 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
796 "rmf%?e\\t%0, %1, %2"
797 [(set_attr "type" "float")])
799 ;; Boolean and,ior,xor insns
801 (define_insn "anddi3"
802 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
803 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
804 (match_operand:DI 2 "s_register_operand" "r,0")))]
806 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
807 [(set_attr "length" "8")])
810 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
811 (and:DI (zero_extend:DI
812 (match_operand:SI 2 "s_register_operand" "r,r"))
813 (match_operand:DI 1 "s_register_operand" "?r,0")))]
815 "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
816 [(set_attr "length" "8")])
819 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
820 (and:DI (sign_extend:DI
821 (match_operand:SI 2 "s_register_operand" "r,r"))
822 (match_operand:DI 1 "s_register_operand" "?r,0")))]
824 "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
825 [(set_attr "length" "8")])
827 (define_insn "andsi3"
828 [(set (match_operand:SI 0 "s_register_operand" "=r")
829 (and:SI (match_operand:SI 1 "s_register_operand" "r")
830 (match_operand:SI 2 "arm_not_operand" "rK")))]
833 if (GET_CODE (operands[2]) == CONST_INT
834 && !const_ok_for_arm (INTVAL (operands[2])))
836 operands[2] = GEN_INT (~INTVAL (operands[2]));
837 output_asm_insn (\"bic%?\\t%0, %1, %2\", operands);
840 return \"and%?\\t%0, %1, %2\";
844 [(set (reg:CC_NOOV 24)
845 (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r")
846 (match_operand:SI 2 "arm_not_operand" "rK"))
848 (set (match_operand:SI 0 "s_register_operand" "=r")
849 (and:SI (match_dup 1) (match_dup 2)))]
852 if (GET_CODE (operands[2]) == CONST_INT
853 && !const_ok_for_arm (INTVAL (operands[2])))
855 operands[2] = GEN_INT (~INTVAL (operands[2]));
856 output_asm_insn (\"bic%?s\\t%0, %1, %2\", operands);
859 return \"and%?s\\t%0, %1, %2\";
861 [(set_attr "conds" "set")])
864 [(set (reg:CC_NOOV 24)
865 (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
866 (match_operand:SI 1 "arm_rhs_operand" "rI"))
870 [(set_attr "conds" "set")])
873 [(set (reg:CC_NOOV 24)
874 (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
875 (match_operand:SI 1 "immediate_operand" "K"))
877 (clobber (match_scratch:SI 3 "=r"))]
878 "const_ok_for_arm (~INTVAL (operands[1]))"
880 operands[1] = GEN_INT (~INTVAL (operands[1]));
881 output_asm_insn (\"bic%?s\\t%3, %0, %1\", operands);
884 [(set_attr "conds" "set")])
887 [(set (reg:CC_NOOV 24)
888 (compare:CC_NOOV (zero_extract:SI
889 (match_operand:SI 0 "s_register_operand" "r")
890 (match_operand:SI 1 "immediate_operand" "n")
891 (match_operand:SI 2 "immediate_operand" "n"))
893 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
894 && INTVAL (operands[1]) > 0
895 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
896 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
899 unsigned int mask = 0;
900 int cnt = INTVAL (operands[1]);
903 mask = (mask << 1) | 1;
904 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
905 output_asm_insn (\"tst%?\\t%0, %1\", operands);
909 [(set_attr "conds" "set")])
912 [(set (reg:CC_NOOV 24)
913 (compare:CC_NOOV (zero_extract:SI
914 (match_operand:QI 0 "memory_operand" "m")
915 (match_operand 1 "immediate_operand" "n")
916 (match_operand 2 "immediate_operand" "n"))
918 (clobber (match_scratch:QI 3 "=r"))]
919 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
920 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
923 unsigned int mask = 0;
924 int cnt = INTVAL (operands[1]);
927 mask = (mask << 1) | 1;
928 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
929 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
930 output_asm_insn (\"tst%?\\t%3, %1\", operands);
934 [(set_attr "conds" "set")
935 (set_attr "length" "8")])
937 ;; constants for op 2 will never be given to these patterns.
939 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
940 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
941 (match_operand:DI 1 "s_register_operand" "0,r")))]
943 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
944 [(set_attr "length" "8")])
947 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
948 (and:DI (not:DI (zero_extend:DI
949 (match_operand:SI 2 "s_register_operand" "r,r")))
950 (match_operand:DI 1 "s_register_operand" "0,?r")))]
954 bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
955 [(set_attr "length" "4,8")])
958 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
959 (and:DI (not:DI (sign_extend:DI
960 (match_operand:SI 2 "s_register_operand" "r,r")))
961 (match_operand:DI 1 "s_register_operand" "?r,0")))]
963 "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
964 [(set_attr "length" "8")])
967 [(set (match_operand:SI 0 "s_register_operand" "=r")
968 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
969 (match_operand:SI 1 "s_register_operand" "r")))]
971 "bic%?\\t%0, %1, %2")
974 [(set (reg:CC_NOOV 24)
976 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
977 (match_operand:SI 1 "s_register_operand" "r"))
979 (set (match_operand:SI 0 "s_register_operand" "=r")
980 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
982 "bic%?s\\t%0, %1, %2"
983 [(set_attr "conds" "set")])
986 [(set (reg:CC_NOOV 24)
988 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
989 (match_operand:SI 1 "s_register_operand" "r"))
991 (clobber (match_scratch:SI 0 "=r"))]
993 "bic%?s\\t%0, %1, %2"
994 [(set_attr "conds" "set")])
996 (define_insn "iordi3"
997 [(set (match_operand:DI 0 "s_register_operand" "=&r")
998 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
999 (match_operand:DI 2 "s_register_operand" "r")))]
1001 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
1002 [(set_attr "length" "8")])
1005 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1006 (ior:DI (zero_extend:DI
1007 (match_operand:SI 2 "s_register_operand" "r,r"))
1008 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1012 orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1013 [(set_attr "length" "4,8")])
1016 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1017 (ior:DI (sign_extend:DI
1018 (match_operand:SI 2 "s_register_operand" "r,r"))
1019 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1021 "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1022 [(set_attr "length" "8")])
1024 (define_insn "iorsi3"
1025 [(set (match_operand:SI 0 "s_register_operand" "=r")
1026 (ior:SI (match_operand:SI 1 "s_register_operand" "r")
1027 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1029 "orr%?\\t%0, %1, %2")
1032 [(set (reg:CC_NOOV 24)
1033 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1034 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1036 (set (match_operand:SI 0 "s_register_operand" "=r")
1037 (ior:SI (match_dup 1) (match_dup 2)))]
1039 "orr%?s\\t%0, %1, %2"
1040 [(set_attr "conds" "set")])
1043 [(set (reg:CC_NOOV 24)
1044 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1045 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1047 (clobber (match_scratch:SI 0 "=r"))]
1049 "orr%?s\\t%0, %1, %2"
1050 [(set_attr "conds" "set")])
1052 (define_insn "xordi3"
1053 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1054 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1055 (match_operand:DI 2 "s_register_operand" "r,0")))]
1057 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
1058 [(set_attr "length" "8")])
1061 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1062 (xor:DI (zero_extend:DI
1063 (match_operand:SI 2 "s_register_operand" "r,r"))
1064 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1068 eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
1069 [(set_attr "length" "4,8")])
1072 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1073 (xor:DI (sign_extend:DI
1074 (match_operand:SI 2 "s_register_operand" "r,r"))
1075 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1077 "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1078 [(set_attr "length" "8")])
1080 (define_insn "xorsi3"
1081 [(set (match_operand:SI 0 "s_register_operand" "=r")
1082 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1083 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1085 "eor%?\\t%0, %1, %2")
1088 [(set (reg:CC_NOOV 24)
1089 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1090 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1092 (set (match_operand:SI 0 "s_register_operand" "=r")
1093 (xor:SI (match_dup 1) (match_dup 2)))]
1095 "eor%?s\\t%0, %1, %2"
1096 [(set_attr "conds" "set")])
1099 [(set (reg:CC_NOOV 24)
1100 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1101 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1105 [(set_attr "conds" "set")])
1107 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1108 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1112 [(set (match_operand:SI 0 "s_register_operand" "=r")
1113 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1114 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1115 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1116 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1118 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1119 (not:SI (match_dup 3))))
1120 (set (match_dup 0) (not:SI (match_dup 4)))]
1125 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1126 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1127 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1128 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1130 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1131 [(set_attr "length" "8")])
1135 ;; Minimum and maximum insns
1137 (define_insn "smaxsi3"
1138 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1139 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1140 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1141 (clobber (reg:CC 24))]
1144 cmp\\t%1, %2\;movlt\\t%0, %2
1145 cmp\\t%1, %2\;movge\\t%0, %1
1146 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1147 [(set_attr "conds" "clob")
1148 (set_attr "length" "8,8,12")])
1150 (define_insn "sminsi3"
1151 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1152 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1153 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1154 (clobber (reg:CC 24))]
1157 cmp\\t%1, %2\;movge\\t%0, %2
1158 cmp\\t%1, %2\;movlt\\t%0, %1
1159 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1160 [(set_attr "conds" "clob")
1161 (set_attr "length" "8,8,12")])
1163 (define_insn "umaxsi3"
1164 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1165 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1166 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1167 (clobber (reg:CC 24))]
1170 cmp\\t%1, %2\;movcc\\t%0, %2
1171 cmp\\t%1, %2\;movcs\\t%0, %1
1172 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1173 [(set_attr "conds" "clob")
1174 (set_attr "length" "8,8,12")])
1176 (define_insn "uminsi3"
1177 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1178 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1179 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1180 (clobber (reg:CC 24))]
1183 cmp\\t%1, %2\;movcs\\t%0, %2
1184 cmp\\t%1, %2\;movcc\\t%0, %1
1185 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1186 [(set_attr "conds" "clob")
1187 (set_attr "length" "8,8,12")])
1190 [(set (match_operand:SI 0 "memory_operand" "=m")
1191 (match_operator:SI 3 "minmax_operator"
1192 [(match_operand:SI 1 "s_register_operand" "r")
1193 (match_operand:SI 2 "s_register_operand" "r")]))
1194 (clobber (reg:CC 24))]
1197 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1199 output_asm_insn (\"cmp\\t%1, %2\", operands);
1200 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1201 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1204 [(set_attr "conds" "clob")
1205 (set_attr "length" "12")
1206 (set_attr "type" "store1")])
1209 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1210 (match_operator:SI 4 "shiftable_operator"
1211 [(match_operator:SI 5 "minmax_operator"
1212 [(match_operand:SI 2 "s_register_operand" "r,r")
1213 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1214 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1215 (clobber (reg:CC 24))]
1219 enum rtx_code code = GET_CODE (operands[4]);
1221 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1223 output_asm_insn (\"cmp\\t%2, %3\", operands);
1224 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1225 if (which_alternative != 0 || operands[3] != const0_rtx
1226 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1227 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1231 [(set_attr "conds" "clob")
1232 (set_attr "length" "12")])
1235 ;; Shift and rotation insns
1237 (define_insn "ashlsi3"
1238 [(set (match_operand:SI 0 "s_register_operand" "=r")
1239 (ashift:SI (match_operand:SI 1 "s_register_operand" "r")
1240 (match_operand:SI 2 "arm_rhs_operand" "rn")))]
1242 "mov%?\\t%0, %1, asl %2")
1244 (define_insn "ashrsi3"
1245 [(set (match_operand:SI 0 "s_register_operand" "=r")
1246 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
1247 (match_operand:SI 2 "arm_rhs_operand" "rn")))]
1249 "mov%?\\t%0, %1, asr %2")
1251 (define_insn "lshrsi3"
1252 [(set (match_operand:SI 0 "s_register_operand" "=r")
1253 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
1254 (match_operand:SI 2 "arm_rhs_operand" "rn")))]
1256 "mov%?\\t%0, %1, lsr %2")
1258 ;; rotlsi3 is not defined yet to see what happens
1260 (define_insn "rotrsi3"
1261 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1262 (rotatert:SI (match_operand:SI 1 "s_register_operand" "r,r")
1263 (match_operand:SI 2 "arm_rhs_operand" "r,n")))]
1266 switch (which_alternative)
1269 return \"mov%?\\t%0, %1, ror %2\";
1271 if (INTVAL(operands[2]) > 31)
1272 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1273 output_asm_insn (\"mov%?\\t%0, %1, ror %2\", operands);
1279 [(set (reg:CC_NOOV 24)
1280 (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
1281 [(match_operand:SI 2 "s_register_operand" "r")
1282 (match_operand:SI 3 "arm_rhs_operand" "rn")])
1284 (set (match_operand:SI 0 "s_register_operand" "=r")
1285 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))]
1287 "mov%?s\\t%0, %2, %S1"
1288 [(set_attr "conds" "set")])
1291 [(set (reg:CC_NOOV 24)
1292 (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
1293 [(match_operand:SI 2 "s_register_operand" "r")
1294 (match_operand:SI 3 "arm_rhs_operand" "rn")])
1296 (clobber (match_scratch:SI 0 "=r"))]
1298 "mov%?s\\t%0, %2, %S1"
1299 [(set_attr "conds" "set")])
1302 [(set (match_operand:SI 0 "s_register_operand" "=r")
1303 (not:SI (match_operator:SI 1 "shift_operator"
1304 [(match_operand:SI 2 "s_register_operand" "r")
1305 (match_operand:SI 3 "arm_rhs_operand" "rn")])))]
1307 "mvn%?\\t%0, %2, %S1")
1310 [(set (reg:CC_NOOV 24)
1311 (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
1312 [(match_operand:SI 2 "s_register_operand" "r")
1313 (match_operand:SI 3 "arm_rhs_operand" "rn")]))
1315 (set (match_operand:SI 0 "s_register_operand" "=r")
1316 (not:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])))]
1318 "mvn%?s\\t%0, %2, %S1"
1319 [(set_attr "conds" "set")])
1322 [(set (reg:CC_NOOV 24)
1323 (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
1324 [(match_operand:SI 2 "s_register_operand" "r")
1325 (match_operand:SI 3 "arm_rhs_operand" "rn")]))
1327 (clobber (match_scratch:SI 0 "=r"))]
1329 "mvn%?s\\t%0, %2, %S1"
1330 [(set_attr "conds" "set")])
1333 ;; Unary arithmetic insns
1335 (define_insn "negdi2"
1336 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1337 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1339 "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
1340 [(set_attr "conds" "clob")
1341 (set_attr "length" "8")])
1343 (define_insn "negsi2"
1344 [(set (match_operand:SI 0 "s_register_operand" "=r")
1345 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1347 "rsb%?\\t%0, %1, #0")
1349 (define_insn "negsf2"
1350 [(set (match_operand:SF 0 "s_register_operand" "=f")
1351 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1354 [(set_attr "type" "float")])
1356 (define_insn "negdf2"
1357 [(set (match_operand:DF 0 "s_register_operand" "=f")
1358 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1361 [(set_attr "type" "float")])
1364 [(set (match_operand:DF 0 "s_register_operand" "=f")
1365 (neg:DF (float_extend:DF
1366 (match_operand:SF 1 "s_register_operand" "f"))))]
1369 [(set_attr "type" "float")])
1371 (define_insn "negxf2"
1372 [(set (match_operand:XF 0 "s_register_operand" "=f")
1373 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1374 "ENABLE_XF_PATTERNS"
1376 [(set_attr "type" "float")])
1378 ;; abssi2 doesn't really clobber the condition codes if a different register
1379 ;; is being set. To keep things simple, assume during rtl manipulations that
1380 ;; it does, but tell the final scan operator the truth. Similarly for
1383 (define_insn "abssi2"
1384 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1385 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1389 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1390 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1391 [(set_attr "conds" "clob,*")
1392 (set_attr "length" "8")])
1395 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1396 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1400 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1401 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1402 [(set_attr "conds" "clob,*")
1403 (set_attr "length" "8")])
1405 (define_insn "abssf2"
1406 [(set (match_operand:SF 0 "s_register_operand" "=f")
1407 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1410 [(set_attr "type" "float")])
1412 (define_insn "absdf2"
1413 [(set (match_operand:DF 0 "s_register_operand" "=f")
1414 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1417 [(set_attr "type" "float")])
1420 [(set (match_operand:DF 0 "s_register_operand" "=f")
1421 (abs:DF (float_extend:DF
1422 (match_operand:SF 1 "s_register_operand" "f"))))]
1425 [(set_attr "type" "float")])
1427 (define_insn "absxf2"
1428 [(set (match_operand:XF 0 "s_register_operand" "=f")
1429 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1430 "ENABLE_XF_PATTERNS"
1432 [(set_attr "type" "float")])
1434 (define_insn "sqrtsf2"
1435 [(set (match_operand:SF 0 "s_register_operand" "=f")
1436 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1439 [(set_attr "type" "float_em")])
1441 (define_insn "sqrtdf2"
1442 [(set (match_operand:DF 0 "s_register_operand" "=f")
1443 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1446 [(set_attr "type" "float_em")])
1449 [(set (match_operand:DF 0 "s_register_operand" "=f")
1450 (sqrt:DF (float_extend:DF
1451 (match_operand:SF 1 "s_register_operand" "f"))))]
1454 [(set_attr "type" "float_em")])
1456 (define_insn "sqrtxf2"
1457 [(set (match_operand:XF 0 "s_register_operand" "=f")
1458 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1459 "ENABLE_XF_PATTERNS"
1461 [(set_attr "type" "float_em")])
1463 (define_insn "sinsf2"
1464 [(set (match_operand:SF 0 "s_register_operand" "=f")
1465 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1468 [(set_attr "type" "float_em")])
1470 (define_insn "sindf2"
1471 [(set (match_operand:DF 0 "s_register_operand" "=f")
1472 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1475 [(set_attr "type" "float_em")])
1478 [(set (match_operand:DF 0 "s_register_operand" "=f")
1479 (unspec:DF [(float_extend:DF
1480 (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1483 [(set_attr "type" "float_em")])
1485 (define_insn "sinxf2"
1486 [(set (match_operand:XF 0 "s_register_operand" "=f")
1487 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1488 "ENABLE_XF_PATTERNS"
1490 [(set_attr "type" "float_em")])
1492 (define_insn "cossf2"
1493 [(set (match_operand:SF 0 "s_register_operand" "=f")
1494 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1497 [(set_attr "type" "float_em")])
1499 (define_insn "cosdf2"
1500 [(set (match_operand:DF 0 "s_register_operand" "=f")
1501 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1504 [(set_attr "type" "float_em")])
1507 [(set (match_operand:DF 0 "s_register_operand" "=f")
1508 (unspec:DF [(float_extend:DF
1509 (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1512 [(set_attr "type" "float_em")])
1514 (define_insn "cosxf2"
1515 [(set (match_operand:XF 0 "s_register_operand" "=f")
1516 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1517 "ENABLE_XF_PATTERNS"
1519 [(set_attr "type" "float_em")])
1521 (define_insn "one_cmpldi2"
1522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1523 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1525 "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
1526 [(set_attr "length" "8")])
1528 (define_insn "one_cmplsi2"
1529 [(set (match_operand:SI 0 "s_register_operand" "=r")
1530 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1535 [(set (reg:CC_NOOV 24)
1536 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1538 (set (match_operand:SI 0 "s_register_operand" "=r")
1539 (not:SI (match_dup 1)))]
1542 [(set_attr "conds" "set")])
1545 [(set (reg:CC_NOOV 24)
1546 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1548 (clobber (match_scratch:SI 0 "=r"))]
1551 [(set_attr "conds" "set")])
1553 ;; Fixed <--> Floating conversion insns
1555 (define_insn "floatsisf2"
1556 [(set (match_operand:SF 0 "s_register_operand" "=f")
1557 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1560 [(set_attr "type" "r_2_f")])
1562 (define_insn "floatsidf2"
1563 [(set (match_operand:DF 0 "s_register_operand" "=f")
1564 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1567 [(set_attr "type" "r_2_f")])
1569 (define_insn "floatsixf2"
1570 [(set (match_operand:XF 0 "s_register_operand" "=f")
1571 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1572 "ENABLE_XF_PATTERNS"
1574 [(set_attr "type" "r_2_f")])
1576 (define_insn "fix_truncsfsi2"
1577 [(set (match_operand:SI 0 "s_register_operand" "=r")
1578 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
1581 [(set_attr "type" "f_2_r")])
1583 (define_insn "fix_truncdfsi2"
1584 [(set (match_operand:SI 0 "s_register_operand" "=r")
1585 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
1588 [(set_attr "type" "f_2_r")])
1590 (define_insn "fix_truncxfsi2"
1591 [(set (match_operand:SI 0 "s_register_operand" "=r")
1592 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1593 "ENABLE_XF_PATTERNS"
1595 [(set_attr "type" "f_2_r")])
1599 (define_insn "truncdfsf2"
1600 [(set (match_operand:SF 0 "s_register_operand" "=f")
1602 (match_operand:DF 1 "s_register_operand" "f")))]
1605 [(set_attr "type" "float")])
1607 (define_insn "truncxfsf2"
1608 [(set (match_operand:SF 0 "s_register_operand" "=f")
1610 (match_operand:XF 1 "s_register_operand" "f")))]
1611 "ENABLE_XF_PATTERNS"
1613 [(set_attr "type" "float")])
1615 (define_insn "truncxfdf2"
1616 [(set (match_operand:DF 0 "s_register_operand" "=f")
1618 (match_operand:XF 1 "s_register_operand" "f")))]
1619 "ENABLE_XF_PATTERNS"
1621 [(set_attr "type" "float")])
1623 ;; Zero and sign extension instructions.
1625 (define_insn "zero_extendsidi2"
1626 [(set (match_operand:DI 0 "s_register_operand" "=r")
1627 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1630 if (REGNO (operands[1]) != REGNO (operands[0]))
1631 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1632 return \"mov%?\\t%R0, #0\";
1634 [(set_attr "length" "8")])
1636 (define_insn "zero_extendqidi2"
1637 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
1638 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1641 and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
1642 ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
1643 [(set_attr "length" "8")
1644 (set_attr "type" "*,load")])
1646 (define_insn "extendsidi2"
1647 [(set (match_operand:DI 0 "s_register_operand" "=r")
1648 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1651 if (REGNO (operands[1]) != REGNO (operands[0]))
1652 output_asm_insn (\"mov%?\\t%0, %1\", operands);
1653 return \"mov%?\\t%R0, %0, asr #31\";
1655 [(set_attr "length" "8")])
1657 (define_expand "zero_extendhisi2"
1659 (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1661 (set (match_operand:SI 0 "s_register_operand" "")
1662 (lshiftrt:SI (match_dup 2)
1666 { operands[1] = gen_lowpart (SImode, operands[1]);
1667 operands[2] = gen_reg_rtx (SImode); }")
1669 (define_insn "zero_extendqihi2"
1670 [(set (match_operand:HI 0 "s_register_operand" "=r")
1672 (match_operand:QI 1 "s_register_operand" "r")))]
1674 "and%?\\t%0, %1, #255\\t%@ zero_extendqihi2")
1677 [(set (reg:CC_NOOV 24)
1678 (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
1680 (set (match_operand:SI 0 "s_register_operand" "=r")
1681 (zero_extend:HI (match_dup 1)))]
1683 "and%?s\\t%0, %1, #255"
1684 [(set_attr "conds" "set")])
1687 [(set (reg:CC_NOOV 24)
1688 (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
1692 [(set_attr "conds" "set")])
1694 (define_insn "zero_extendqisi2"
1695 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1697 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1700 and%?\\t%0, %1, #255\\t%@ zero_extendqisi2
1701 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
1702 [(set_attr "type" "*,load")])
1705 [(set (reg:CC_NOOV 24)
1706 (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
1708 (set (match_operand:SI 0 "s_register_operand" "=r")
1709 (zero_extend:SI (match_dup 1)))]
1711 "and%?s\\t%0, %1, #255"
1712 [(set_attr "conds" "set")])
1715 [(set (reg:CC_NOOV 24)
1716 (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
1718 (set (match_operand:QI 0 "s_register_operand" "=r")
1721 "and%?s\\t%0, %1, #255"
1722 [(set_attr "conds" "set")])
1724 (define_expand "extendhisi2"
1726 (ashift:SI (match_operand:HI 1 "s_register_operand" "")
1728 (set (match_operand:SI 0 "s_register_operand" "")
1729 (ashiftrt:SI (match_dup 2)
1733 { operands[1] = gen_lowpart (SImode, operands[1]);
1734 operands[2] = gen_reg_rtx (SImode); }")
1736 (define_expand "extendqihi2"
1738 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1740 (set (match_operand:HI 0 "s_register_operand" "")
1741 (ashiftrt:SI (match_dup 2)
1745 { operands[0] = gen_lowpart (SImode, operands[0]);
1746 operands[1] = gen_lowpart (SImode, operands[1]);
1747 operands[2] = gen_reg_rtx (SImode); }")
1749 (define_expand "extendqisi2"
1751 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
1753 (set (match_operand:SI 0 "s_register_operand" "")
1754 (ashiftrt:SI (match_dup 2)
1758 { operands[1] = gen_lowpart (SImode, operands[1]);
1759 operands[2] = gen_reg_rtx (SImode); }")
1761 (define_insn "extendsfdf2"
1762 [(set (match_operand:DF 0 "s_register_operand" "=f")
1763 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
1766 [(set_attr "type" "float")])
1768 (define_insn "extendsfxf2"
1769 [(set (match_operand:XF 0 "s_register_operand" "=f")
1770 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
1771 "ENABLE_XF_PATTERNS"
1774 (define_insn "extenddfxf2"
1775 [(set (match_operand:XF 0 "s_register_operand" "=f")
1776 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
1777 "ENABLE_XF_PATTERNS"
1779 [(set_attr "type" "float")])
1782 ;; Move insns (including loads and stores)
1784 ;; XXX Just some ideas about movti.
1785 ;; I don't think these are a good idea on the arm, there just aren't enough
1787 ;;(define_expand "loadti"
1788 ;; [(set (match_operand:TI 0 "s_register_operand" "")
1789 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
1792 ;;(define_expand "storeti"
1793 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
1794 ;; (match_operand:TI 1 "s_register_operand" ""))]
1797 ;;(define_expand "movti"
1798 ;; [(set (match_operand:TI 0 "general_operand" "")
1799 ;; (match_operand:TI 1 "general_operand" ""))]
1805 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1806 ;; operands[1] = copy_to_reg (operands[1]);
1807 ;; if (GET_CODE (operands[0]) == MEM)
1808 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
1809 ;; else if (GET_CODE (operands[1]) == MEM)
1810 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
1814 ;; emit_insn (insn);
1818 ;; Recognise garbage generated above.
1821 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
1822 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
1826 ;; register mem = (which_alternative < 3);
1827 ;; register char *template;
1829 ;; operands[mem] = XEXP (operands[mem], 0);
1830 ;; switch (which_alternative)
1832 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
1833 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
1834 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
1835 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
1836 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
1837 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
1839 ;; output_asm_insn (template, operands);
1844 (define_insn "movdi"
1845 [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
1846 (match_operand:DI 1 "di_operand" "rK,n,o<>,r,F"))]
1849 return (output_move_double (operands));
1851 [(set_attr "length" "8,32,8,8,32")
1852 (set_attr "type" "*,*,load,store2,*")])
1854 (define_expand "movsi"
1855 [(set (match_operand:SI 0 "general_operand" "")
1856 (match_operand:SI 1 "general_operand" ""))]
1859 /* Everything except mem = const or mem = mem can be done easily */
1860 if (GET_CODE (operands[0]) == MEM)
1861 operands[1] = force_reg (SImode, operands[1]);
1862 if (GET_CODE (operands[1]) == CONST_INT
1863 && !(const_ok_for_arm (INTVAL (operands[1]))
1864 || const_ok_for_arm (~INTVAL (operands[1]))))
1866 int n = INTVAL (operands[1]);
1867 rtx tmpreg, tmpreg2;
1868 int i, n_ones = 0, first = 1, last = 0;
1870 if (GET_CODE (operands[0]) != REG
1871 && GET_CODE (operands[0]) != SUBREG)
1873 for (i = 0; i < 32; i++)
1876 /* These loops go the opposite way around to those in arm.c so that
1877 the last constant may be more likely to be eliminted into the
1882 n = (~n) & 0xffffffff;
1883 for (i = 30; i >= 0; i -= 2)
1890 if ((n & (255 << i)) == n)
1896 emit_insn (gen_movsi (tmpreg = (reload_in_progress
1897 || reload_completed)
1899 : gen_reg_rtx (SImode),
1900 equal = gen_rtx (CONST_INT, VOIDmode,
1901 ~(n & (255 << i)))));
1908 emit_insn (gen_subsi3 (tmpreg2 = (reload_in_progress
1912 : gen_reg_rtx (SImode),
1914 constant = gen_rtx (CONST_INT, VOIDmode,
1924 for (i = 30; i >= 0; i -= 2)
1931 if ((n & (255 << i)) == n)
1937 emit_insn (gen_movsi (tmpreg = (reload_in_progress
1938 || reload_completed)
1940 : gen_reg_rtx (SImode),
1941 equal = gen_rtx (CONST_INT, VOIDmode,
1949 emit_insn (gen_addsi3 (tmpreg2 = (reload_in_progress
1953 : gen_reg_rtx (SImode),
1955 constant = gen_rtx (CONST_INT, VOIDmode,
1968 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r")
1969 (match_operand:SI 1 "general_operand" "R,m,K,r,r,S"))]
1970 "(register_operand (operands[0], SImode)
1971 && (GET_CODE (operands[1]) != CONST_INT
1972 || const_ok_for_arm (INTVAL (operands[1]))
1973 || const_ok_for_arm (~INTVAL (operands[1])))
1974 && (GET_CODE (operands[1]) != SYMBOL_REF
1975 || CONSTANT_ADDRESS_P (operands[1])))
1976 || register_operand (operands[1], SImode)"
1978 switch (which_alternative)
1981 /* NB Calling get_attr_length may cause the insn to be re-extracted... */
1982 if (get_attr_length (insn) == 8)
1984 /* ... so modify the operands here. */
1985 operands[1] = XEXP (operands[1], 0);
1986 output_asm_insn (\"sub%?\\t%0, pc, #(8 + . - %a1) & ~4095\",
1988 output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
1994 operands[1] = XEXP (operands[1], 0);
1995 output_asm_insn (\"ldr%?\\t%0, [pc, %1 - . - 8]\", operands);
2000 if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2001 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
2003 return \"ldr%?\\t%0, %1\";
2006 return \"mov%?\\t%0, %1\";
2008 if (!const_ok_for_arm (INTVAL (operands[1])))
2010 operands[1] = GEN_INT (~INTVAL (operands[1]));
2011 output_asm_insn (\"mvn%?\\t%0, %1\", operands);
2014 return \"mov%?\\t%0, %1\";
2016 return \"str%?\\t%1, %0\";
2018 return output_load_symbol (insn, operands);
2021 [(set (attr "length")
2022 (cond [(eq_attr "alternative" "0")
2026 (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
2030 (eq_attr "alternative" "5") (const_int 16)]
2032 (set_attr "type" "load,load,*,*,store1,*")])
2034 ;; If copying one reg to another we can set the condition codes according to
2035 ;; its value. Such a move is common after a return from subroutine and the
2036 ;; result is being tested against zero.
2039 [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
2041 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2045 sub%?s\\t%0, %1, #0"
2046 [(set_attr "conds" "set")])
2048 ;; Subroutine to store a half word from a register into memory.
2049 ;; Operand 0 is the source register (HImode)
2050 ;; Operand 1 is the destination address in a register (SImode)
2052 ;; In both this routine and the next, we must be careful not to spill
2053 ;; a memory address of reg+large_const into a seperate PLUS insn, since this
2054 ;; can generate unrecognizable rtl.
2056 (define_expand "storehi"
2057 [;; store the low byte
2058 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2059 ;; extract the high byte
2061 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2062 ;; store the high byte
2063 (set (mem:QI (match_dup 4))
2064 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2068 enum rtx_code code = GET_CODE (operands[1]);
2070 if ((code == PLUS || code == MINUS)
2071 && (GET_CODE (XEXP (operands[1], 1)) == REG
2072 || GET_CODE (XEXP (operands[1], 0)) != REG))
2073 operands[1] = force_reg (SImode, operands[1]);
2074 operands[4] = plus_constant (operands[1], 1);
2075 operands[3] = gen_lowpart (QImode, operands[0]);
2076 operands[0] = gen_lowpart (SImode, operands[0]);
2077 operands[2] = gen_reg_rtx (SImode);
2081 ;; Subroutine to store a half word integer constant into memory.
2082 ;; Operand 0 is the constant
2083 ;; Operand 1 is the destination address in a register (SImode)
2085 (define_expand "storeinthi"
2086 [;; store the low byte
2087 (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" ""))
2088 ;; store the high byte
2089 (set (mem:QI (match_dup 3)) (match_dup 2))]
2093 int value = INTVAL (operands[0]);
2094 enum rtx_code code = GET_CODE (operands[1]);
2096 if ((code == PLUS || code == MINUS)
2097 && (GET_CODE (XEXP (operands[1], 1)) == REG
2098 || GET_CODE (XEXP (operands[1], 0)) != REG))
2099 operands[1] = force_reg (SImode, operands[1]);
2101 operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
2102 operands[2] = force_reg (QImode,
2103 gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
2104 operands[3] = plus_constant (operands[1], 1);
2108 (define_expand "movhi"
2109 [(set (match_operand:HI 0 "general_operand" "")
2110 (match_operand:HI 1 "general_operand" ""))]
2116 if (reload_in_progress || reload_completed)
2117 insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
2120 if (GET_CODE (operands[0]) == MEM)
2122 if (GET_CODE (operands[1]) == CONST_INT)
2124 insn = gen_storeinthi (operands[1], XEXP (operands[0],0));
2128 if (GET_CODE (operands[1]) == MEM)
2129 operands[1] = force_reg (HImode, operands[1]);
2130 insn = gen_storehi (operands[1], XEXP (operands[0], 0));
2133 else if (GET_CODE (operands[1]) == CONST_INT
2134 && !(const_ok_for_arm (INTVAL (operands[1]))
2135 || const_ok_for_arm (~INTVAL (operands[1]))))
2139 /* no need to be clever, this will always take two insns.
2140 The top sixteen bits should be all zeros or all ones. */
2141 if (INTVAL (operands[1]) < 0)
2143 emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
2144 GEN_INT (INTVAL (operands[1])
2146 emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
2147 GEN_INT (-((~INTVAL (operands[1]))
2152 emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
2153 GEN_INT (INTVAL (operands[1]) & 0xff00)));
2154 emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
2155 GEN_INT (INTVAL (operands[1]) & 0x00ff)));
2157 insn = gen_rtx (SET, HImode, operands[0],
2158 gen_rtx (SUBREG, HImode, reg2, 0));
2161 insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
2168 ;; Pattern to recognise insn generated default case above
2171 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2172 (match_operand:HI 1 "general_operand" "r,K,m,r"))]
2173 "(register_operand (operands[0], HImode)
2174 && (GET_CODE (operands[1]) != CONST_INT
2175 || const_ok_for_arm (INTVAL (operands[1]))
2176 || const_ok_for_arm (~INTVAL (operands[1]))))
2177 || register_operand (operands[1], HImode)"
2179 switch (which_alternative)
2182 if (!const_ok_for_arm (INTVAL (operands[1])))
2184 operands[1] = GEN_INT (~INTVAL (operands[1]));
2185 output_asm_insn (\"mvn%?\\t%0, %1\", operands);
2190 return \"mov%?\\t%0, %1\\t%@ movhi\";
2192 return \"ldr%?\\t%0, %1\\t%@ movhi\";
2194 return \"str%?\\t%1, %0\\t%@ movhi\";
2197 [(set_attr "type" "*,*,load,store1")])
2199 (define_expand "reload_outhi"
2200 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2201 (match_operand:HI 1 "s_register_operand" "r")
2202 (match_operand:SI 2 "s_register_operand" "=&r")])]
2205 arm_reload_out_hi (operands);
2209 (define_expand "movqi"
2210 [(set (match_operand:QI 0 "general_operand" "")
2211 (match_operand:QI 1 "general_operand" ""))]
2214 /* Everything except mem = const or mem = mem can be done easily */
2216 if (!(reload_in_progress || reload_completed))
2219 if (GET_CODE (operands[1]) == CONST_INT)
2221 emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), operands[1]));
2222 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2225 if (GET_CODE (operands[0]) == MEM)
2226 operands[1] = force_reg (QImode, operands[1]);
2231 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2232 (match_operand:QI 1 "general_operand" "r,K,m,r"))]
2233 "register_operand (operands[0], QImode)
2234 || register_operand (operands[1], QImode)"
2236 switch (which_alternative)
2239 if (INTVAL (operands[1]) < 0)
2241 operands[1] = GEN_INT (~INTVAL (operands[1]));
2242 output_asm_insn (\"mvn%?\\t%0, %1\", operands);
2246 return \"mov%?\\t%0, %1\";
2248 return \"ldr%?b\\t%0, %1\";
2250 return \"str%?b\\t%1, %0\";
2253 [(set_attr "type" "*,*,load,store1")])
2255 (define_insn "movsf"
2256 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2257 (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
2263 switch (which_alternative)
2266 return \"mvf%?s\\t%0, %1\";
2268 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2269 r = REAL_VALUE_NEGATE (r);
2270 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2271 output_asm_insn (\"mnf%?s\\t%0, %1\", operands);
2274 return \"ldf%?s\\t%0, %1\";
2276 return \"stf%?s\\t%1, %0\";
2278 return \"str%?\\t%1, [sp, #-4]!\;ldf%?s\\t%0, [sp], #4\";
2280 return \"stf%?s\\t%1, [sp, #-4]!\;ldr%?\\t%0, [sp], #4\";
2282 return \"mov%?\\t%0, %1\";
2284 return \"ldr%?\\t%0, %1\\t%@ float\";
2286 return \"str%?\\t%1, %0\\t%@ float\";
2290 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2291 (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2293 (define_expand "movdf"
2294 [(parallel [(set (match_operand:DF 0 "general_operand" "")
2295 (match_operand:DF 1 "general_operand" ""))
2296 (clobber (match_scratch:SI 2 ""))])]
2299 if (GET_CODE (operands[0]) == MEM)
2300 operands[1] = force_reg (DFmode, operands[1]);
2303 ;; Reloading a df mode value stored in integer regs to memory can require a
2305 (define_expand "reload_outdf"
2306 [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=o")
2307 (match_operand:DF 1 "s_register_operand" "r"))
2308 (clobber (match_operand:SI 2 "s_register_operand" "=&r"))])]
2313 [(set (match_operand:DF 0 "general_operand" "=r,Q,r,o,f,f,f,f,m,!f,!r,r")
2314 (match_operand:DF 1 "general_operand"
2315 "Q,r,?o,?r,?f,!G,!H,m,f,r,f,??r"))
2316 (clobber (match_scratch:SI 2 "=X,X,X,&r,X,X,X,X,X,X,X,X"))]
2317 "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
2323 switch (which_alternative)
2326 return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
2329 return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
2332 ops[0] = operands[0];
2333 ops[1] = XEXP (XEXP (operands[1], 0), 0);
2334 ops[2] = XEXP (XEXP (operands[1], 0), 1);
2335 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2336 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2338 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2339 return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
2342 ops[0] = operands[2];
2343 ops[1] = XEXP (XEXP (operands[0], 0), 0);
2344 ops[2] = XEXP (XEXP (operands[0], 0), 1);
2345 if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
2346 output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
2348 output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
2349 return \"stm%?ia\\t%2, {%1, %R1}\\t%@ double\";
2353 return \"mvf%?d\\t%0, %1\";
2356 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2357 r = REAL_VALUE_NEGATE (r);
2358 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2359 output_asm_insn (\"mnf%?d\\t%0, %1\", operands);
2362 case 7: return \"ldf%?d\\t%0, %1\";
2363 case 8: return \"stf%?d\\t%1, %0\";
2364 case 9: return output_mov_double_fpu_from_arm (operands);
2365 case 10: return output_mov_double_arm_from_fpu (operands);
2366 case 11: return output_move_double (operands);
2370 [(set_attr "length" "4,4,8,8,4,4,4,4,4,8,8,8")
2372 "load,store2,load,store2,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
2374 (define_insn "movxf"
2375 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2376 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2377 "ENABLE_XF_PATTERNS"
2382 switch (which_alternative)
2384 case 0: return \"mvf%?e\\t%0, %1\";
2386 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2387 r = REAL_VALUE_NEGATE (r);
2388 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2389 output_asm_insn (\"mnf%?e\\t%0, %1\", operands);
2392 case 2: return \"ldf%?e\\t%0, %1\";
2393 case 3: return \"stf%?e\\t%1, %0\";
2394 case 4: return output_mov_long_double_fpu_from_arm (operands);
2395 case 5: return output_mov_long_double_arm_from_fpu (operands);
2396 case 6: return output_mov_long_double_arm_from_arm (operands);
2400 [(set_attr "length" "4,4,4,4,8,8,12")
2401 (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
2404 ;; load- and store-multiple insns
2405 ;; The arm can load/store any set of registers, provided that they are in
2406 ;; ascending order; but that is beyond GCC so stick with what it knows.
2408 (define_expand "load_multiple"
2409 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2410 (match_operand:SI 1 "" ""))
2411 (use (match_operand:SI 2 "" ""))])]
2414 /* Support only fixed point registers */
2415 if (GET_CODE (operands[2]) != CONST_INT
2416 || INTVAL (operands[2]) > 14
2417 || INTVAL (operands[2]) < 2
2418 || GET_CODE (operands[1]) != MEM
2419 || GET_CODE (operands[0]) != REG
2420 || REGNO (operands[0]) > 14
2421 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2425 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2426 force_reg (SImode, XEXP (operands[1], 0)),
2430 ;; Load multiple with write-back
2433 [(match_parallel 0 "load_multiple_operation"
2434 [(set (match_operand:SI 1 "s_register_operand" "+r")
2435 (plus:SI (match_dup 1)
2436 (match_operand:SI 2 "immediate_operand" "n")))
2437 (set (match_operand:SI 3 "s_register_operand" "=r")
2438 (mem:SI (match_dup 1)))])]
2439 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2443 int count = XVECLEN (operands[0], 0);
2445 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2446 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2447 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2449 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2453 [(set_attr "type" "load")])
2455 ;; Ordinary load multiple
2458 [(match_parallel 0 "load_multiple_operation"
2459 [(set (match_operand:SI 1 "s_register_operand" "=r")
2460 (match_operand:SI 2 "indirect_operand" "Q"))])]
2465 int count = XVECLEN (operands[0], 0);
2467 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2468 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
2469 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
2471 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
2475 [(set_attr "type" "load")])
2477 (define_expand "store_multiple"
2478 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2479 (match_operand:SI 1 "" ""))
2480 (use (match_operand:SI 2 "" ""))])]
2483 /* Support only fixed point registers */
2484 if (GET_CODE (operands[2]) != CONST_INT
2485 || INTVAL (operands[2]) > 14
2486 || INTVAL (operands[2]) < 2
2487 || GET_CODE (operands[1]) != REG
2488 || GET_CODE (operands[0]) != MEM
2489 || REGNO (operands[1]) > 14
2490 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
2494 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
2495 force_reg (SImode, XEXP (operands[0], 0)),
2499 ;; Store multiple with write-back
2502 [(match_parallel 0 "store_multiple_operation"
2503 [(set (match_operand:SI 1 "s_register_operand" "+r")
2504 (plus:SI (match_dup 1)
2505 (match_operand:SI 2 "immediate_operand" "n")))
2506 (set (mem:SI (match_dup 1))
2507 (match_operand:SI 3 "s_register_operand" "r"))])]
2508 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2512 int count = XVECLEN (operands[0], 0);
2514 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2515 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
2516 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
2518 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
2523 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2524 (const_string "store2")
2525 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
2526 (const_string "store3")]
2527 (const_string "store4")))])
2529 ;; Ordinary store multiple
2532 [(match_parallel 0 "store_multiple_operation"
2533 [(set (match_operand:SI 2 "indirect_operand" "=Q")
2534 (match_operand:SI 1 "s_register_operand" "r"))])]
2539 int count = XVECLEN (operands[0], 0);
2541 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
2542 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
2543 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
2545 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
2550 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
2551 (const_string "store2")
2552 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
2553 (const_string "store3")]
2554 (const_string "store4")))])
2556 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
2557 ;; We could let this apply for blocks of less than this, but it clobbers so
2558 ;; many registers that there is then probably a better way.
2560 ;; If optimizing, output redundant moves with REG_NOTES on them, this
2561 ;; produces better code.
2563 (define_expand "movstrsi"
2564 [(set (match_operand:BLK 0 "general_operand" "=m")
2565 (match_operand:BLK 1 "general_operand" "m"))
2566 (use (match_operand:SI 2 "immediate_operand" "n"))
2567 (use (match_operand:SI 3 "immediate_operand" "n"))
2568 (clobber (reg:SI 0))
2569 (clobber (reg:SI 1))
2570 (clobber (reg:SI 2))
2571 (clobber (reg:SI 3))
2572 (clobber (match_scratch:SI 4 "=+r"))
2573 (clobber (match_scratch:SI 5 "=+r"))]
2579 rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16);
2580 rtx src = gen_reg_rtx (SImode);
2581 rtx dst = gen_reg_rtx (SImode);
2582 rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst;
2583 extern int optimize;
2585 if (GET_CODE (operands[2]) != CONST_INT
2586 || GET_CODE (operands[3]) != CONST_INT
2587 || INTVAL (operands[2]) % 4 != 0
2588 || INTVAL (operands[2]) < 4
2589 || INTVAL (operands[2]) > 64
2590 || INTVAL (operands[3]) < 4
2591 || INTVAL (operands[3]) % 4 != 0)
2593 emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0)));
2594 emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0)));
2598 for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4)
2600 emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go,
2602 emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go,
2605 for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--)
2608 note = emit_move_insn (gen_reg_rtx (SImode),
2609 gen_rtx (REG, SImode, r));
2610 REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
2611 gen_rtx (MEM, SImode,
2612 plus_constant (st_src, 4*(i+r))),
2614 REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
2615 gen_rtx (MEM, SImode,
2616 plus_constant (st_dst, 4*(i+r))),
2619 words_to_go -= words_to_go < 4 ? words_to_go : 4;
2625 emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src));
2626 emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
2627 emit_move_insn (gen_rtx (MEM, SImode, dst), sreg);
2628 emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
2632 /* Insns for the REG_NOTES: These notes tell the optimiser where the
2633 index registers have got to so that consecutive block moves of
2634 contiguous data work efficiently */
2636 end_src = emit_move_insn (fin_src, fin_src);
2637 REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL,
2638 plus_constant (st_src, INTVAL (operands[2])),
2639 REG_NOTES (end_src));
2640 end_dst = emit_move_insn (fin_dst, fin_dst);
2641 REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL,
2642 plus_constant (st_dst, INTVAL (operands[2])),
2643 REG_NOTES (end_dst));
2650 ;; Comparison and test insns
2652 (define_expand "cmpsi"
2654 (compare:CC (match_operand:SI 0 "s_register_operand" "")
2655 (match_operand:SI 1 "arm_add_operand" "")))]
2659 arm_compare_op0 = operands[0];
2660 arm_compare_op1 = operands[1];
2666 (define_expand "cmpsf"
2668 (compare:CC (match_operand:SF 0 "s_register_operand" "")
2669 (match_operand:SF 1 "fpu_rhs_operand" "")))]
2673 arm_compare_op0 = operands[0];
2674 arm_compare_op1 = operands[1];
2680 (define_expand "cmpdf"
2682 (compare:CC (match_operand:DF 0 "s_register_operand" "")
2683 (match_operand:DF 1 "fpu_rhs_operand" "")))]
2687 arm_compare_op0 = operands[0];
2688 arm_compare_op1 = operands[1];
2694 (define_expand "cmpxf"
2696 (compare:CC (match_operand:XF 0 "s_register_operand" "")
2697 (match_operand:XF 1 "fpu_rhs_operand" "")))]
2698 "ENABLE_XF_PATTERNS"
2701 arm_compare_op0 = operands[0];
2702 arm_compare_op1 = operands[1];
2709 [(set (match_operand 0 "cc_register" "")
2710 (compare (match_operand:SI 1 "s_register_operand" "r")
2711 (match_operand:SI 2 "arm_add_operand" "rL")))]
2714 if (GET_CODE (operands[2]) == CONST_INT
2715 && !const_ok_for_arm (INTVAL (operands[2])))
2716 return \"cmn%?\\t%1, #%n2\";
2717 return \"cmp%?\\t%1, %2\";
2719 [(set_attr "conds" "set")])
2722 [(set (match_operand 0 "cc_register" "")
2723 (compare (match_operand:SI 1 "s_register_operand" "r")
2724 (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
2727 [(set_attr "conds" "set")])
2730 [(set (match_operand 0 "cc_register" "")
2731 (compare (match_operand:SI 1 "s_register_operand" "r")
2732 (match_operator:SI 2 "shift_operator"
2733 [(match_operand:SI 3 "s_register_operand" "r")
2734 (match_operand:SI 4 "arm_rhs_operand" "rn")])))]
2736 "cmp%?\\t%1, %3, %S2"
2737 [(set_attr "conds" "set")])
2740 [(set (match_operand 0 "cc_register" "")
2741 (compare (match_operand:SI 1 "s_register_operand" "r")
2742 (neg:SI (match_operator:SI 2 "shift_operator"
2743 [(match_operand:SI 3 "s_register_operand" "r")
2744 (match_operand:SI 4 "arm_rhs_operand" "rn")]))))]
2746 "cmn%?\\t%1, %3, %S2"
2747 [(set_attr "conds" "set")])
2751 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
2752 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2758 switch (which_alternative)
2761 return \"cmf%?\\t%0, %1\";
2763 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2764 r = REAL_VALUE_NEGATE (r);
2765 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2766 output_asm_insn (\"cnf%?\\t%0, %1\", operands);
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")))]
2783 switch (which_alternative)
2786 return \"cmf%?\\t%0, %1\";
2788 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2789 r = REAL_VALUE_NEGATE (r);
2790 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2791 output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2796 [(set_attr "conds" "set")
2797 (set_attr "type" "f_2_r")])
2801 (compare:CCFP (float_extend:DF
2802 (match_operand:SF 0 "s_register_operand" "f,f"))
2803 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2809 switch (which_alternative)
2812 return \"cmf%?\\t%0, %1\";
2814 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2815 r = REAL_VALUE_NEGATE (r);
2816 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2817 output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2822 [(set_attr "conds" "set")
2823 (set_attr "type" "f_2_r")])
2827 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
2829 (match_operand:SF 1 "s_register_operand" "f"))))]
2832 [(set_attr "conds" "set")
2833 (set_attr "type" "f_2_r")])
2837 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
2838 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2839 "ENABLE_XF_PATTERNS"
2844 switch (which_alternative)
2847 return \"cmf%?\\t%0, %1\";
2849 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2850 r = REAL_VALUE_NEGATE (r);
2851 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2852 output_asm_insn (\"cnf%?\\t%0, %1\", operands);
2857 [(set_attr "conds" "set")
2858 (set_attr "type" "f_2_r")])
2861 [(set (reg:CCFPE 24)
2862 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
2863 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
2869 switch (which_alternative)
2872 return \"cmf%?e\\t%0, %1\";
2874 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2875 r = REAL_VALUE_NEGATE (r);
2876 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2877 output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2882 [(set_attr "conds" "set")
2883 (set_attr "type" "f_2_r")])
2886 [(set (reg:CCFPE 24)
2887 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
2888 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2894 switch (which_alternative)
2897 return \"cmf%?e\\t%0, %1\";
2899 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2900 r = REAL_VALUE_NEGATE (r);
2901 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2902 output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2907 [(set_attr "conds" "set")
2908 (set_attr "type" "f_2_r")])
2911 [(set (reg:CCFPE 24)
2912 (compare:CCFPE (float_extend:DF
2913 (match_operand:SF 0 "s_register_operand" "f,f"))
2914 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
2920 switch (which_alternative)
2923 return \"cmf%?e\\t%0, %1\";
2925 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2926 r = REAL_VALUE_NEGATE (r);
2927 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2928 output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2933 [(set_attr "conds" "set")
2934 (set_attr "type" "f_2_r")])
2937 [(set (reg:CCFPE 24)
2938 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
2940 (match_operand:SF 1 "s_register_operand" "f"))))]
2943 [(set_attr "conds" "set")
2944 (set_attr "type" "f_2_r")])
2947 [(set (reg:CCFPE 24)
2948 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
2949 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
2950 "ENABLE_XF_PATTERNS"
2955 switch (which_alternative)
2958 return \"cmf%?e\\t%0, %1\";
2960 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2961 r = REAL_VALUE_NEGATE (r);
2962 operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
2963 output_asm_insn (\"cnf%?e\\t%0, %1\", operands);
2968 [(set_attr "conds" "set")
2969 (set_attr "type" "f_2_r")])
2971 ; This insn allows redundant compares to be removed by cse, nothing should
2972 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
2973 ; is deleted later on. The match_dup will match the mode here, so that
2974 ; mode changes of the condition codes aren't lost by this even though we don't
2975 ; specify what they are.
2978 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
2980 "\\t%@ deleted compare"
2981 [(set_attr "conds" "set")
2982 (set_attr "length" "0")])
2985 ;; Conditional branch insns
2987 (define_expand "beq"
2989 (if_then_else (eq (match_dup 1) (const_int 0))
2990 (label_ref (match_operand 0 "" ""))
2995 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3000 (define_expand "bne"
3002 (if_then_else (ne (match_dup 1) (const_int 0))
3003 (label_ref (match_operand 0 "" ""))
3008 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3013 (define_expand "bgt"
3015 (if_then_else (gt (match_dup 1) (const_int 0))
3016 (label_ref (match_operand 0 "" ""))
3021 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3026 (define_expand "ble"
3028 (if_then_else (le (match_dup 1) (const_int 0))
3029 (label_ref (match_operand 0 "" ""))
3034 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3039 (define_expand "bge"
3041 (if_then_else (ge (match_dup 1) (const_int 0))
3042 (label_ref (match_operand 0 "" ""))
3047 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3052 (define_expand "blt"
3054 (if_then_else (lt (match_dup 1) (const_int 0))
3055 (label_ref (match_operand 0 "" ""))
3060 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3065 (define_expand "bgtu"
3067 (if_then_else (gtu (match_dup 1) (const_int 0))
3068 (label_ref (match_operand 0 "" ""))
3073 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3078 (define_expand "bleu"
3080 (if_then_else (leu (match_dup 1) (const_int 0))
3081 (label_ref (match_operand 0 "" ""))
3086 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3091 (define_expand "bgeu"
3093 (if_then_else (geu (match_dup 1) (const_int 0))
3094 (label_ref (match_operand 0 "" ""))
3099 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3104 (define_expand "bltu"
3106 (if_then_else (ltu (match_dup 1) (const_int 0))
3107 (label_ref (match_operand 0 "" ""))
3112 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3117 ;; patterns to match conditional branch insns
3121 (if_then_else (match_operator 1 "comparison_operator"
3122 [(reg 24) (const_int 0)])
3123 (label_ref (match_operand 0 "" ""))
3128 extern int arm_ccfsm_state;
3130 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3132 arm_ccfsm_state += 2;
3135 return \"b%d1\\t%l0\";
3137 [(set_attr "conds" "use")])
3141 (if_then_else (match_operator 1 "comparison_operator"
3142 [(reg 24) (const_int 0)])
3144 (label_ref (match_operand 0 "" ""))))]
3148 extern int arm_ccfsm_state;
3150 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3152 arm_ccfsm_state += 2;
3155 return \"b%D1\\t%l0\";
3157 [(set_attr "conds" "use")])
3162 (define_expand "seq"
3163 [(set (match_operand:SI 0 "s_register_operand" "=r")
3164 (eq:SI (match_dup 1) (const_int 0)))]
3168 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3173 (define_expand "sne"
3174 [(set (match_operand:SI 0 "s_register_operand" "=r")
3175 (ne:SI (match_dup 1) (const_int 0)))]
3179 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3184 (define_expand "sgt"
3185 [(set (match_operand:SI 0 "s_register_operand" "=r")
3186 (gt:SI (match_dup 1) (const_int 0)))]
3190 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3195 (define_expand "sle"
3196 [(set (match_operand:SI 0 "s_register_operand" "=r")
3197 (le:SI (match_dup 1) (const_int 0)))]
3201 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3206 (define_expand "sge"
3207 [(set (match_operand:SI 0 "s_register_operand" "=r")
3208 (ge:SI (match_dup 1) (const_int 0)))]
3212 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3217 (define_expand "slt"
3218 [(set (match_operand:SI 0 "s_register_operand" "=r")
3219 (lt:SI (match_dup 1) (const_int 0)))]
3223 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3228 (define_expand "sgtu"
3229 [(set (match_operand:SI 0 "s_register_operand" "=r")
3230 (gtu:SI (match_dup 1) (const_int 0)))]
3234 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3239 (define_expand "sleu"
3240 [(set (match_operand:SI 0 "s_register_operand" "=r")
3241 (leu:SI (match_dup 1) (const_int 0)))]
3245 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3250 (define_expand "sgeu"
3251 [(set (match_operand:SI 0 "s_register_operand" "=r")
3252 (geu:SI (match_dup 1) (const_int 0)))]
3256 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3261 (define_expand "sltu"
3262 [(set (match_operand:SI 0 "s_register_operand" "=r")
3263 (ltu:SI (match_dup 1) (const_int 0)))]
3267 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3273 [(set (match_operand:SI 0 "s_register_operand" "=r")
3274 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3276 "mov%d1\\t%0, #1\;mov%D1\\t%0, #0"
3277 [(set_attr "conds" "use")
3278 (set_attr "length" "8")])
3281 [(set (match_operand:SI 0 "s_register_operand" "=r")
3282 (neg:SI (match_operator:SI 1 "comparison_operator"
3283 [(reg 24) (const_int 0)])))]
3285 "mvn%d1\\t%0, #0\;mov%D1\\t%0, #0"
3286 [(set_attr "conds" "use")
3287 (set_attr "length" "8")])
3290 [(set (match_operand:SI 0 "s_register_operand" "=r")
3291 (not:SI (match_operator:SI 1 "comparison_operator"
3292 [(reg 24) (const_int 0)])))]
3294 "mvn%d1\\t%0, #1\;mov%D1\\t%0, #0"
3295 [(set_attr "conds" "use")
3296 (set_attr "length" "8")])
3299 ;; Jump and linkage insns
3303 (label_ref (match_operand 0 "" "")))]
3307 extern int arm_ccfsm_state;
3309 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3311 arm_ccfsm_state += 2;
3314 return \"b%?\\t%l0\";
3317 (define_expand "call"
3318 [(parallel [(call (match_operand 0 "memory_operand" "")
3319 (match_operand 1 "general_operand" ""))
3320 (clobber (reg:SI 14))])]
3325 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3326 (match_operand 1 "" "g"))
3327 (clobber (reg:SI 14))]
3330 return (output_call (operands));
3332 [(set (attr "conds")
3333 (if_then_else (eq_attr "cpu" "arm6")
3334 (const_string "clob")
3335 (const_string "nocond")))
3336 ;; length is worst case, normally it is only two
3337 (set_attr "length" "12")
3338 (set_attr "type" "call")])
3341 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3342 (match_operand 1 "general_operand" "g"))
3343 (clobber (reg:SI 14))]
3346 return (output_call_mem (operands));
3348 [(set (attr "conds")
3349 (if_then_else (eq_attr "cpu" "arm6")
3350 (const_string "clob")
3351 (const_string "nocond")))
3352 (set_attr "length" "12")
3353 (set_attr "type" "call")])
3355 (define_expand "call_value"
3356 [(parallel [(set (match_operand 0 "" "=rf")
3357 (call (match_operand 1 "memory_operand" "m")
3358 (match_operand 2 "general_operand" "g")))
3359 (clobber (reg:SI 14))])]
3364 [(set (match_operand 0 "" "=rf")
3365 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3366 (match_operand 2 "general_operand" "g")))
3367 (clobber (reg:SI 14))]
3370 return (output_call (&operands[1]));
3372 [(set (attr "conds")
3373 (if_then_else (eq_attr "cpu" "arm6")
3374 (const_string "clob")
3375 (const_string "nocond")))
3376 (set_attr "length" "12")
3377 (set_attr "type" "call")])
3380 [(set (match_operand 0 "" "=rf")
3381 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3382 (match_operand 2 "general_operand" "g")))
3383 (clobber (reg:SI 14))]
3384 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3386 return (output_call_mem (&operands[1]));
3388 [(set (attr "conds")
3389 (if_then_else (eq_attr "cpu" "arm6")
3390 (const_string "clob")
3391 (const_string "nocond")))
3392 (set_attr "length" "12")
3393 (set_attr "type" "call")])
3395 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3396 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3399 [(call (mem:SI (match_operand:SI 0 "" "i"))
3400 (match_operand:SI 1 "general_operand" "g"))
3401 (clobber (reg:SI 14))]
3402 "GET_CODE (operands[0]) == SYMBOL_REF"
3404 [(set (attr "conds")
3405 (if_then_else (eq_attr "cpu" "arm6")
3406 (const_string "clob")
3407 (const_string "nocond")))
3408 (set_attr "type" "call")])
3411 [(set (match_operand 0 "s_register_operand" "=rf")
3412 (call (mem:SI (match_operand:SI 1 "" "i"))
3413 (match_operand:SI 2 "general_operand" "g")))
3414 (clobber (reg:SI 14))]
3415 "GET_CODE(operands[1]) == SYMBOL_REF"
3417 [(set (attr "conds")
3418 (if_then_else (eq_attr "cpu" "arm6")
3419 (const_string "clob")
3420 (const_string "nocond")))
3421 (set_attr "type" "call")])
3423 ;; Often the return insn will be the same as loading from memory, so set attr
3424 (define_insn "return"
3429 extern int arm_ccfsm_state;
3431 if (arm_ccfsm_state == 2)
3433 arm_ccfsm_state += 2;
3436 return output_return_instruction (NULL, TRUE);
3438 [(set_attr "type" "load")])
3442 (if_then_else (match_operator 0 "comparison_operator"
3443 [(reg 24) (const_int 0)])
3449 extern int arm_ccfsm_state;
3451 if (arm_ccfsm_state == 2)
3453 arm_ccfsm_state += 2;
3456 return output_return_instruction (operands[0], TRUE);
3458 [(set_attr "conds" "use")
3459 (set_attr "type" "load")])
3463 (if_then_else (match_operator 0 "comparison_operator"
3464 [(reg 24) (const_int 0)])
3470 extern int arm_ccfsm_state;
3472 if (arm_ccfsm_state == 2)
3474 arm_ccfsm_state += 2;
3477 return output_return_instruction
3478 (gen_rtx (reverse_condition (GET_CODE (operands[0])),
3479 GET_MODE (operands[0]), XEXP (operands[0], 0),
3480 XEXP (operands[0], 1)),
3483 [(set_attr "conds" "use")
3484 (set_attr "type" "load")])
3486 ;; Call subroutine returning any type.
3488 (define_expand "untyped_call"
3489 [(parallel [(call (match_operand 0 "" "")
3491 (match_operand 1 "" "")
3492 (match_operand 2 "" "")])]
3498 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3500 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3502 rtx set = XVECEXP (operands[2], 0, i);
3503 emit_move_insn (SET_DEST (set), SET_SRC (set));
3506 /* The optimizer does not know that the call sets the function value
3507 registers we stored in the result block. We avoid problems by
3508 claiming that all hard registers are used and clobbered at this
3510 emit_insn (gen_blockage ());
3515 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3516 ;; all of memory. This blocks insns from being moved across this point.
3518 (define_insn "blockage"
3519 [(unspec_volatile [(const_int 0)] 0)]
3522 [(set_attr "length" "0")
3523 (set_attr "type" "block")])
3525 (define_insn "tablejump"
3527 (match_operand:SI 0 "s_register_operand" "r"))
3528 (use (label_ref (match_operand 1 "" "")))]
3530 "mov%?\\tpc, %0\\t%@ table jump, label %l1")
3534 (match_operand:SI 0 "memory_operand" "m"))
3535 (use (label_ref (match_operand 1 "" "")))]
3537 "ldr%?\\tpc, %0\\t%@ table jump, label %l1"
3538 [(set_attr "type" "load")])
3540 (define_insn "indirect_jump"
3542 (match_operand:SI 0 "s_register_operand" "r"))]
3544 "mov%?\\tpc, %0\\t%@ indirect jump")
3548 (match_operand:SI 0 "memory_operand" "m"))]
3550 "ldr%?\\tpc, %0\\t%@ indirect jump"
3551 [(set_attr "type" "load")])
3558 "mov%?\\tr0, r0\\t%@ nop")
3560 ;; Patterns to allow combination of arithmetic, cond code and shifts
3563 [(set (match_operand:SI 0 "s_register_operand" "=r")
3564 (match_operator:SI 1 "shiftable_operator"
3565 [(match_operator:SI 3 "shift_operator"
3566 [(match_operand:SI 4 "s_register_operand" "r")
3567 (match_operand:SI 5 "nonmemory_operand" "rI")])
3568 (match_operand:SI 2 "s_register_operand" "r")]))]
3570 "%i1%?\\t%0, %2, %4, %S3")
3573 [(set (reg:CC_NOOV 24)
3574 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3575 [(match_operator:SI 3 "shift_operator"
3576 [(match_operand:SI 4 "s_register_operand" "r")
3577 (match_operand:SI 5 "nonmemory_operand" "rI")])
3578 (match_operand:SI 2 "s_register_operand" "r")])
3580 (set (match_operand:SI 0 "s_register_operand" "=r")
3581 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
3584 "%i1%?s\\t%0, %2, %4, %S3"
3585 [(set_attr "conds" "set")])
3588 [(set (reg:CC_NOOV 24)
3589 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
3590 [(match_operator:SI 3 "shift_operator"
3591 [(match_operand:SI 4 "s_register_operand" "r")
3592 (match_operand:SI 5 "nonmemory_operand" "rI")])
3593 (match_operand:SI 2 "s_register_operand" "r")])
3595 (clobber (match_scratch:SI 0 "=r"))]
3597 "%i1%?s\\t%0, %2, %4, %S3"
3598 [(set_attr "conds" "set")])
3601 [(set (match_operand:SI 0 "s_register_operand" "=r")
3602 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3603 (match_operator:SI 2 "shift_operator"
3604 [(match_operand:SI 3 "s_register_operand" "r")
3605 (match_operand:SI 4 "nonmemory_operand" "rn")])))]
3607 "sub%?\\t%0, %1, %3, %S2")
3610 [(set (reg:CC_NOOV 24)
3612 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3613 (match_operator:SI 2 "shift_operator"
3614 [(match_operand:SI 3 "s_register_operand" "r")
3615 (match_operand:SI 4 "nonmemory_operand" "rn")]))
3617 (set (match_operand:SI 0 "s_register_operand" "=r")
3618 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
3621 "sub%?s\\t%0, %1, %3, %S2"
3622 [(set_attr "conds" "set")])
3625 [(set (reg:CC_NOOV 24)
3627 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
3628 (match_operator:SI 2 "shift_operator"
3629 [(match_operand:SI 3 "s_register_operand" "r")
3630 (match_operand:SI 4 "nonmemory_operand" "rn")]))
3632 (clobber (match_scratch:SI 0 "=r"))]
3634 "sub%?s\\t%0, %1, %3, %S2"
3635 [(set_attr "conds" "set")])
3637 ;; These variants of the above insns can occur if the first operand is the
3638 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
3639 ;; seem to be a way around it. Most of the predicates have to be null
3640 ;; because the format can be generated part way through reload, so
3641 ;; if we don't match it as soon as it becomes available, reload doesn't know
3642 ;; how to reload pseudos that haven't got hard registers; the constraints will
3643 ;; sort everything out.
3646 [(set (match_operand:SI 0 "" "=&r")
3647 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
3648 [(match_operand:SI 3 "" "r")
3649 (match_operand:SI 4 "" "rn")])
3650 (match_operand:SI 2 "" "r"))
3651 (match_operand:SI 1 "const_int_operand" "n")))]
3652 "reload_in_progress"
3654 output_asm_insn (\"add%?\\t%0, %2, %3, %S5\", operands);
3655 operands[2] = operands[1];
3656 operands[1] = operands[0];
3657 return output_add_immediate (operands);
3659 ; we have no idea how long the add_immediate is, it could be up to 4.
3660 [(set_attr "length" "20")])
3663 [(set (reg:CC_NOOV 24)
3664 (compare:CC_NOOV (plus:SI
3666 (match_operator:SI 5 "shift_operator"
3667 [(match_operand:SI 3 "" "r")
3668 (match_operand:SI 4 "" "rn")])
3669 (match_operand:SI 1 "" "r"))
3670 (match_operand:SI 2 "const_int_operand" "n"))
3672 (set (match_operand:SI 0 "" "=&r")
3673 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
3676 "reload_in_progress"
3678 output_add_immediate (operands);
3679 return \"add%?s\\t%0, %0, %3, %S5\";
3681 [(set_attr "conds" "set")
3682 (set_attr "length" "20")])
3685 [(set (reg:CC_NOOV 24)
3686 (compare:CC_NOOV (plus:SI
3688 (match_operator:SI 5 "shift_operator"
3689 [(match_operand:SI 3 "" "r")
3690 (match_operand:SI 4 "" "rn")])
3691 (match_operand:SI 1 "" "r"))
3692 (match_operand:SI 2 "const_int_operand" "n"))
3694 (clobber (match_scratch:SI 0 "=&r"))]
3695 "reload_in_progress"
3697 output_add_immediate (operands);
3698 return \"add%?s\\t%0, %0, %3, %S5\";
3700 [(set_attr "conds" "set")
3701 (set_attr "length" "20")])
3703 ;; These are similar, but are needed when the mla pattern contains the
3704 ;; eliminated register as operand 3.
3707 [(set (match_operand:SI 0 "" "=&r,&r")
3708 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
3709 (match_operand:SI 2 "" "r,r"))
3710 (match_operand:SI 3 "" "r,r"))
3711 (match_operand:SI 4 "const_int_operand" "n,n")))]
3712 "reload_in_progress"
3714 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
3715 operands[2] = operands[4];
3716 operands[1] = operands[0];
3717 return output_add_immediate (operands);
3719 [(set_attr "length" "20")])
3722 [(set (reg:CC_NOOV 24)
3723 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3724 (match_operand:SI 3 "" "r")
3725 (match_operand:SI 4 "" "r"))
3726 (match_operand:SI 1 "" "r"))
3727 (match_operand:SI 2 "const_int_operand" "n"))
3729 (set (match_operand:SI 0 "" "=&r")
3730 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
3732 "reload_in_progress"
3734 output_add_immediate (operands);
3735 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
3738 [(set_attr "length" "20")
3739 (set_attr "conds" "set")])
3742 [(set (reg:CC_NOOV 24)
3743 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
3744 (match_operand:SI 3 "" "r")
3745 (match_operand:SI 4 "" "r"))
3746 (match_operand:SI 1 "" "r"))
3747 (match_operand:SI 2 "const_int_operand" "n"))
3749 (clobber (match_scratch:SI 0 "=&r"))]
3750 "reload_in_progress"
3752 output_add_immediate (operands);
3753 return \"mla%?s\\t%0, %3, %4, %0\";
3755 [(set_attr "length" "20")
3756 (set_attr "conds" "set")])
3762 [(set (match_operand:SI 0 "s_register_operand" "=r")
3763 (and:SI (match_operator 1 "comparison_operator"
3764 [(reg 24) (const_int 0)])
3765 (match_operand:SI 2 "s_register_operand" "r")))]
3767 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
3768 [(set_attr "conds" "use")
3769 (set_attr "length" "8")])
3772 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3773 (ior:SI (match_operator 2 "comparison_operator"
3774 [(reg 24) (const_int 0)])
3775 (match_operand:SI 1 "s_register_operand" "0,?r")))]
3779 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
3780 [(set_attr "conds" "use")
3781 (set_attr "length" "4,8")])
3784 [(set (match_operand:SI 0 "s_register_operand" "=r")
3785 (match_operator 1 "comparison_operator"
3786 [(match_operand:SI 2 "s_register_operand" "r")
3787 (match_operand:SI 3 "arm_add_operand" "rL")]))
3791 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
3792 return \"mov\\t%0, %2, lsr #31\";
3794 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
3795 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
3797 if (GET_CODE (operands[1]) == NE)
3799 if (GET_CODE (operands[3]) == CONST_INT
3800 && !const_ok_for_arm (INTVAL (operands[3])))
3801 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
3802 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
3804 if (GET_CODE (operands[3]) == CONST_INT
3805 && !const_ok_for_arm (INTVAL (operands[3])))
3806 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3808 output_asm_insn (\"cmp\\t%2, %3\", operands);
3809 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
3811 [(set_attr "conds" "clob")
3812 (set_attr "length" "12")])
3815 [(set (match_operand:SI 0 "s_register_operand" "=&r")
3816 (ior:SI (match_operator 1 "comparison_operator"
3817 [(match_operand:SI 2 "s_register_operand" "r")
3818 (match_operand:SI 3 "arm_rhs_operand" "rI")])
3819 (match_operator 4 "comparison_operator"
3820 [(match_operand:SI 5 "s_register_operand" "r")
3821 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
3826 int dominant = comparison_dominates_p (GET_CODE (operands[4]),
3827 GET_CODE (operands[1]));
3829 output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
3831 output_asm_insn (\"mov\\t%0, #0\", operands);
3832 if (GET_CODE (operands[1]) == GET_CODE (operands[4])
3833 || comparison_dominates_p (GET_CODE (operands[1]),
3834 GET_CODE (operands[4]))
3836 output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
3839 output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
3840 return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
3843 [(set_attr "conds" "clob")
3845 (set_attr "length" "20")])
3849 (if_then_else (match_operator 5 "equality_operator"
3850 [(ior:SI (match_operator 6 "comparison_operator"
3851 [(match_operand:SI 0 "s_register_operand" "r")
3852 (match_operand:SI 1 "arm_add_operand" "rL")])
3853 (match_operator 7 "comparison_operator"
3854 [(match_operand:SI 2 "s_register_operand" "r")
3855 (match_operand:SI 3 "arm_add_operand" "rL")]))
3857 (label_ref (match_operand 4 "" ""))
3860 "(GET_CODE (operands[6]) == GET_CODE (operands[7])
3861 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
3862 || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
3864 (compare:CC (ior:CC (match_op_dup 6
3865 [(match_dup 0) (match_dup 1)])
3867 [(match_dup 2) (match_dup 3)]))
3870 (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
3871 (label_ref (match_dup 4))
3875 enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
3876 GET_CODE (operands[7]))
3877 ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
3879 if (GET_CODE (operands[5]) == NE)
3880 operands[5] = gen_rtx (code, CCmode,
3881 XEXP (operands[5], 0), XEXP (operands[5], 1));
3883 operands[5] = gen_rtx (reverse_condition (code), CCmode,
3884 XEXP (operands[5], 0), XEXP (operands[5], 1));
3888 ;; Don't match these patterns if we can use a conditional compare, since they
3889 ;; tell the final prescan branch elimator code that full branch inlining
3895 (ior:SI (match_operator 5 "comparison_operator"
3896 [(match_operand:SI 0 "s_register_operand" "r")
3897 (match_operand:SI 1 "arm_add_operand" "rL")])
3898 (match_operator 6 "comparison_operator"
3899 [(match_operand:SI 2 "s_register_operand" "r")
3900 (match_operand:SI 3 "arm_rhs_operand" "rL")]))
3902 (label_ref (match_operand 4 "" ""))
3905 "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
3906 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
3907 || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
3910 extern int arm_ccfsm_state;
3912 if (GET_CODE (operands[1]) == CONST_INT
3913 && !const_ok_for_arm (INTVAL (operands[1])))
3914 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3916 output_asm_insn (\"cmp\\t%0, %1\", operands);
3918 output_asm_insn (\"b%d5\\t%l4\", operands);
3919 if (GET_CODE (operands[3]) == CONST_INT
3920 && !const_ok_for_arm (INTVAL (operands[3])))
3921 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3923 output_asm_insn (\"cmp\\t%2, %3\", operands);
3925 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3927 arm_ccfsm_state += 2;
3930 return \"b%d6\\t%l4\";
3932 [(set_attr "conds" "jump_clob")
3933 (set_attr "length" "16")])
3937 (compare:CC (ior:CC (match_operator 4 "comparison_operator"
3938 [(match_operand:SI 0 "s_register_operand" "r")
3939 (match_operand:SI 1 "arm_add_operand" "rL")])
3940 (match_operator 5 "comparison_operator"
3941 [(match_operand:SI 2 "s_register_operand" "r")
3942 (match_operand:SI 3 "arm_add_operand" "rL")]))
3944 "(GET_CODE (operands[4]) == GET_CODE (operands[5])
3945 || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
3946 || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
3948 if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
3950 if (GET_CODE (operands[3]) == CONST_INT
3951 && !const_ok_for_arm (INTVAL (operands[3])))
3952 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
3954 output_asm_insn (\"cmp\\t%2, %3\", operands);
3956 if (GET_CODE (operands[1]) == CONST_INT
3957 && !const_ok_for_arm (INTVAL (operands[1])))
3958 return \"cmn%D5\\t%0, #%n1\";
3959 return \"cmp%D5\\t%0, %1\";
3962 if (GET_CODE (operands[1]) == CONST_INT
3963 && !const_ok_for_arm (INTVAL (operands[1])))
3964 output_asm_insn (\"cmn\\t%0, #%n1\", operands);
3966 output_asm_insn (\"cmp\\t%0, %1\", operands);
3968 if (GET_CODE (operands[3]) == CONST_INT
3969 && !const_ok_for_arm (INTVAL (operands[3])))
3970 return \"cmn%D4\\t%2, #%n3\";
3971 return \"cmp%D4\\t%2, %3\";
3973 [(set_attr "conds" "set")
3974 (set_attr "length" "8")])
3977 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3978 (if_then_else (match_operator 3 "equality_operator"
3979 [(match_operator 4 "comparison_operator"
3980 [(reg 24) (const_int 0)])
3982 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
3983 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
3986 if (GET_CODE (operands[3]) == NE)
3988 if (which_alternative != 0)
3989 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
3990 if (which_alternative != 1)
3991 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
3994 if (which_alternative != 0)
3995 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
3996 if (which_alternative != 1)
3997 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
4000 [(set_attr "conds" "use")
4001 (set_attr "length" "4,4,8")])
4004 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4005 (match_operator:SI 5 "shiftable_operator"
4006 [(match_operator:SI 4 "comparison_operator"
4007 [(match_operand:SI 2 "s_register_operand" "r,r")
4008 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4009 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4013 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4014 return \"%i5\\t%0, %1, %2, lsr #31\";
4016 output_asm_insn (\"cmp\\t%2, %3\", operands);
4017 if (GET_CODE (operands[5]) == AND)
4018 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4019 else if (which_alternative != 0)
4020 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4021 return \"%i5%d4\\t%0, %1, #1\";
4023 [(set_attr "conds" "clob")
4024 (set_attr "length" "12")])
4027 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4028 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4029 (match_operator:SI 4 "comparison_operator"
4030 [(match_operand:SI 2 "s_register_operand" "r,r")
4031 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4035 output_asm_insn (\"cmp\\t%2, %3\", operands);
4036 if (which_alternative != 0)
4037 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4038 return \"sub%d4\\t%0, %1, #1\";
4040 [(set_attr "conds" "clob")
4041 (set_attr "length" "8,12")])
4044 [(set (match_operand:SI 0 "s_register_operand" "=&r")
4045 (and:SI (match_operator 1 "comparison_operator"
4046 [(match_operand:SI 2 "s_register_operand" "r")
4047 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4048 (match_operator 4 "comparison_operator"
4049 [(match_operand:SI 5 "s_register_operand" "r")
4050 (match_operand:SI 6 "arm_rhs_operand" "rI")])))
4056 comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4057 reverse_condition (GET_CODE (operands[4])))
4059 : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4060 reverse_condition (GET_CODE (operands[1])))
4062 output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
4064 output_asm_insn (\"mov\\t%0, #1\", operands);
4065 if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
4067 output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
4068 : \"cmp%d1\\t%5, %6\", operands);
4072 output_asm_insn (\"mov%D1\\t%0, #0\", operands);
4073 output_asm_insn (\"cmp\\t%5, %6\", operands);
4075 return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
4078 [(set_attr "conds" "clob")
4079 (set_attr "length" "20")])
4083 (if_then_else (match_operator 1 "equality_operator"
4084 [(and:SI (match_operator 2 "comparison_operator"
4085 [(match_operand:SI 3 "s_register_operand" "r")
4086 (match_operand:SI 4 "arm_add_operand" "rL")])
4087 (match_operator 0 "comparison_operator"
4088 [(match_operand:SI 5 "s_register_operand" "r")
4089 (match_operand:SI 6 "arm_add_operand" "rL")]))
4091 (label_ref (match_operand 7 "" ""))
4094 "(GET_CODE (operands[2]) == GET_CODE (operands[0])
4095 || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4096 reverse_condition (GET_CODE (operands[0])))
4097 || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
4098 reverse_condition (GET_CODE (operands[2]))))"
4100 (compare:CC (ior:CC (match_op_dup 2
4101 [(match_dup 3) (match_dup 4)])
4103 [(match_dup 5) (match_dup 6)]))
4106 (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
4107 (label_ref (match_dup 7))
4111 /* Use DeMorgans law to convert this into an IOR of the inverse conditions
4112 This is safe since we only do it for integer comparisons. */
4113 enum rtx_code code =
4114 comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
4115 reverse_condition (GET_CODE (operands[0])))
4116 ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
4118 operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
4119 GET_MODE (operands[2]), operands[3], operands[4]);
4120 operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
4121 GET_MODE (operands[0]), operands[5], operands[6]);
4122 if (GET_CODE (operands[1]) == NE)
4123 operands[1] = gen_rtx (code, CCmode,
4124 XEXP (operands[1], 0), XEXP (operands[1], 1));
4126 operands[1] = gen_rtx (reverse_condition (code), CCmode,
4127 XEXP (operands[1], 0), XEXP (operands[1], 1));
4131 ;; Don't match these patterns if we can use a conditional compare, since they
4132 ;; tell the final prescan branch elimator code that full branch inlining
4138 (and:SI (match_operator 1 "comparison_operator"
4139 [(match_operand:SI 2 "s_register_operand" "r")
4140 (match_operand:SI 3 "arm_add_operand" "rL")])
4141 (match_operator 4 "comparison_operator"
4142 [(match_operand:SI 5 "s_register_operand" "r")
4143 (match_operand:SI 6 "arm_rhs_operand" "rL")]))
4145 (label_ref (match_operand 0 "" ""))
4148 "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
4149 || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
4150 reverse_condition (GET_CODE (operands[4])))
4151 || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
4152 reverse_condition (GET_CODE (operands[1]))))"
4155 extern int arm_ccfsm_state;
4157 if (GET_CODE (operands[3]) == CONST_INT
4158 && !const_ok_for_arm (INTVAL (operands[3])))
4159 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4161 output_asm_insn (\"cmp\\t%2, %3\", operands);
4162 output_asm_insn (\"b%D1\\t%l0\", operands);
4163 if (GET_CODE (operands[6]) == CONST_INT
4164 && !const_ok_for_arm (INTVAL (operands[6])))
4165 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4167 output_asm_insn (\"cmp\\t%5, %6\", operands);
4168 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4170 arm_ccfsm_state += 2;
4173 return \"b%D4\\t%l0\";
4175 [(set_attr "conds" "jump_clob")
4176 (set_attr "length" "16")])
4179 [(set (match_operand:SI 0 "s_register_operand" "=r")
4180 (neg:SI (match_operator 3 "comparison_operator"
4181 [(match_operand:SI 1 "s_register_operand" "r")
4182 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4186 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4187 return \"mov\\t%0, %1, asr #31\";
4189 if (GET_CODE (operands[3]) == NE)
4190 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4192 if (GET_CODE (operands[3]) == GT)
4193 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4195 output_asm_insn (\"cmp\\t%1, %2\", operands);
4196 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4197 return \"mvn%d3\\t%0, #0\";
4199 [(set_attr "conds" "clob")
4200 (set_attr "length" "12")])
4202 (define_insn "movcond"
4203 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4204 (if_then_else:SI (match_operator 5 "comparison_operator"
4205 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4206 (match_operand:SI 4 "arm_add_operand" "rL,rL,rL")])
4207 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4208 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4212 if (GET_CODE (operands[5]) == LT
4213 && (operands[4] == const0_rtx))
4215 if (which_alternative != 1 && GET_CODE (operands[4]) == REG)
4217 if (operands[2] == const0_rtx)
4218 return \"and\\t%0, %1, %3, asr #31\";
4219 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4221 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4223 if (operands[1] == const0_rtx)
4224 return \"bic\\t%0, %2, %3, asr #31\";
4225 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4227 /* The only case that falls through to here is when both ops 1 & 2
4231 if (GET_CODE (operands[5]) == GE
4232 && (operands[4] == const0_rtx))
4234 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4236 if (operands[2] == const0_rtx)
4237 return \"bic\\t%0, %1, %3, asr #31\";
4238 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4240 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4242 if (operands[1] == const0_rtx)
4243 return \"and\\t%0, %2, %3, asr #31\";
4244 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4246 /* The only case that falls through to here is when both ops 1 & 2
4249 if (GET_CODE (operands[4]) == CONST_INT
4250 && !const_ok_for_arm (INTVAL (operands[4])))
4251 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4253 output_asm_insn (\"cmp\\t%3, %4\", operands);
4254 if (which_alternative != 0)
4255 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4256 if (which_alternative != 1)
4257 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4260 [(set_attr "conds" "clob")
4261 (set_attr "length" "8,8,12")])
4264 [(set (match_operand:SI 0 "s_register_operand" "=r")
4265 (if_then_else:SI (match_operator 9 "comparison_operator"
4266 [(match_operand:SI 5 "s_register_operand" "r")
4267 (match_operand:SI 6 "arm_add_operand" "rL")])
4268 (match_operator:SI 8 "shiftable_operator"
4269 [(match_operand:SI 1 "s_register_operand" "r")
4270 (match_operand:SI 2 "arm_rhs_operand" "rI")])
4271 (match_operator:SI 7 "shiftable_operator"
4272 [(match_operand:SI 3 "s_register_operand" "r")
4273 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4277 if (GET_CODE (operands[6]) == CONST_INT
4278 && !const_ok_for_arm (INTVAL (operands[6])))
4279 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4281 output_asm_insn (\"cmp\\t%5, %6\", operands);
4282 return \"%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4\";
4284 [(set_attr "conds" "clob")
4285 (set_attr "length" "12")])
4288 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4289 (if_then_else:SI (match_operator 6 "comparison_operator"
4290 [(match_operand:SI 2 "s_register_operand" "r,r")
4291 (match_operand:SI 3 "arm_add_operand" "rL,rL")])
4292 (match_operator:SI 7 "shiftable_operator"
4293 [(match_operand:SI 4 "s_register_operand" "r,r")
4294 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4295 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4299 /* If we have an operation where (op x 0) is the identity operation and
4300 the condtional operator is LT or GE and we are comparing against zero and
4301 everything is in registers then we can do this in two instructions */
4302 if (operands[3] == const0_rtx
4303 && GET_CODE (operands[7]) != AND
4304 && GET_CODE (operands[5]) == REG
4305 && GET_CODE (operands[1]) == REG
4306 && REGNO (operands[1]) == REGNO (operands[4])
4307 && REGNO (operands[4]) != REGNO (operands[0]))
4309 if (GET_CODE (operands[6]) == LT)
4310 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4311 else if (GET_CODE (operands[6]) == GE)
4312 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4314 if (GET_CODE (operands[3]) == CONST_INT
4315 && !const_ok_for_arm (INTVAL (operands[3])))
4316 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4318 output_asm_insn (\"cmp\\t%2, %3\", operands);
4319 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4320 if (which_alternative != 0)
4322 if (GET_CODE (operands[1]) == MEM)
4323 return \"ldr%D6\\t%0, %1\";
4325 return \"mov%D6\\t%0, %1\";
4329 [(set_attr "conds" "clob")
4330 (set_attr "length" "8,12")])
4333 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4334 (if_then_else:SI (match_operator 6 "comparison_operator"
4335 [(match_operand:SI 4 "s_register_operand" "r,r")
4336 (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4337 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4338 (match_operator:SI 7 "shiftable_operator"
4339 [(match_operand:SI 2 "s_register_operand" "r,r")
4340 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4344 /* If we have an operation where (op x 0) is the identity operation and
4345 the condtional operator is LT or GE and we are comparing against zero and
4346 everything is in registers then we can do this in two instructions */
4347 if (operands[5] == const0_rtx
4348 && GET_CODE (operands[7]) != AND
4349 && GET_CODE (operands[3]) == REG
4350 && GET_CODE (operands[1]) == REG
4351 && REGNO (operands[1]) == REGNO (operands[2])
4352 && REGNO (operands[2]) != REGNO (operands[0]))
4354 if (GET_CODE (operands[6]) == GE)
4355 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4356 else if (GET_CODE (operands[6]) == LT)
4357 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4360 if (GET_CODE (operands[5]) == CONST_INT
4361 && !const_ok_for_arm (INTVAL (operands[5])))
4362 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4364 output_asm_insn (\"cmp\\t%4, %5\", operands);
4366 if (which_alternative != 0)
4368 if (GET_CODE (operands[1]) == MEM)
4369 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4371 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4373 return \"%I7%D6\\t%0, %2, %3\";
4375 [(set_attr "conds" "clob")
4376 (set_attr "length" "8,12")])
4379 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4380 (if_then_else:SI (match_operator 6 "comparison_operator"
4381 [(match_operand:SI 4 "s_register_operand" "r,r")
4382 (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4384 (match_operand:SI 2 "s_register_operand" "r,r")
4385 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4386 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4391 if (GET_CODE (operands[5]) == CONST_INT
4392 && !const_ok_for_arm (INTVAL (operands[5])))
4393 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4395 output_asm_insn (\"cmp\\t%4, %5\", operands);
4396 if (GET_CODE (operands[3]) == CONST_INT
4397 && !const_ok_for_arm (INTVAL (operands[3])))
4398 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4400 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4401 if (which_alternative != 0)
4403 if (GET_CODE (operands[1]) == MEM)
4404 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4406 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4411 [(set_attr "conds" "clob")
4412 (set_attr "length" "8,12")])
4415 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4416 (if_then_else:SI (match_operator 6 "comparison_operator"
4417 [(match_operand:SI 4 "s_register_operand" "r,r")
4418 (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4419 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4421 (match_operand:SI 2 "s_register_operand" "r,r")
4422 (match_operand:SI 3 "arm_add_operand" "rL,rL"))))
4427 if (GET_CODE (operands[5]) == CONST_INT
4428 && !const_ok_for_arm (INTVAL (operands[5])))
4429 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4431 output_asm_insn (\"cmp\\t%4, %5\", operands);
4432 if (GET_CODE (operands[3]) == CONST_INT
4433 && !const_ok_for_arm (INTVAL (operands[3])))
4434 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4436 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4437 if (which_alternative != 0)
4439 if (GET_CODE (operands[6]) == MEM)
4440 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4442 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4447 [(set_attr "conds" "clob")
4448 (set_attr "length" "8,12")])
4451 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4452 (if_then_else:SI (match_operator 5 "comparison_operator"
4453 [(match_operand:SI 3 "s_register_operand" "r,r")
4454 (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4455 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4457 (match_operand:SI 2 "s_register_operand" "r,r"))))
4461 [(set_attr "conds" "clob")
4462 (set_attr "length" "8,12")])
4465 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4466 (if_then_else:SI (match_operator 5 "comparison_operator"
4467 [(match_operand:SI 3 "s_register_operand" "r,r")
4468 (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4470 (match_operand:SI 2 "s_register_operand" "r,r"))
4471 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4478 if (GET_CODE (operands[30]) == CONST_INT
4479 && !const_ok_for_arm (INTVAL (operands[4])))
4480 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4482 output_asm_insn (\"cmp\\t%3, %4\", operands);
4483 if (which_alternative != 0)
4484 output_asm_insn (\"mov%D5\\t%0, %1\", operands);
4485 return \"mvn%d5\\t%0, %2\";
4489 [(set_attr "conds" "clob")
4490 (set_attr "length" "8,12")])
4493 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4494 (if_then_else:SI (match_operator 6 "comparison_operator"
4495 [(match_operand:SI 4 "s_register_operand" "r,r")
4496 (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4497 (match_operator:SI 7 "shift_operator"
4498 [(match_operand:SI 2 "s_register_operand" "r,r")
4499 (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])
4500 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4504 if (GET_CODE (operands[5]) == CONST_INT
4505 && !const_ok_for_arm (INTVAL (operands[5])))
4506 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4508 output_asm_insn (\"cmp\\t%4, %5\", operands);
4509 if (which_alternative != 0)
4510 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4511 return \"mov%d6\\t%0, %2, %S7\";
4513 [(set_attr "conds" "clob")
4514 (set_attr "length" "8,12")])
4517 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4518 (if_then_else:SI (match_operator 6 "comparison_operator"
4519 [(match_operand:SI 4 "s_register_operand" "r,r")
4520 (match_operand:SI 5 "arm_add_operand" "rL,rL")])
4521 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4522 (match_operator:SI 7 "shift_operator"
4523 [(match_operand:SI 2 "s_register_operand" "r,r")
4524 (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])))
4528 if (GET_CODE (operands[5]) == CONST_INT
4529 && !const_ok_for_arm (INTVAL (operands[5])))
4530 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4532 output_asm_insn (\"cmp\\t%4, %5\", operands);
4533 if (which_alternative != 0)
4534 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4535 return \"mov%D6\\t%0, %2, %S7\";
4537 [(set_attr "conds" "clob")
4538 (set_attr "length" "8,12")])
4541 [(set (match_operand:SI 0 "s_register_operand" "=r")
4542 (if_then_else:SI (match_operator 7 "comparison_operator"
4543 [(match_operand:SI 5 "s_register_operand" "r")
4544 (match_operand:SI 6 "arm_add_operand" "rL")])
4545 (match_operator:SI 8 "shift_operator"
4546 [(match_operand:SI 1 "s_register_operand" "r")
4547 (match_operand:SI 2 "arm_rhs_operand" "rn")])
4548 (match_operator:SI 9 "shift_operator"
4549 [(match_operand:SI 3 "s_register_operand" "r")
4550 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4554 if (GET_CODE (operands[6]) == CONST_INT
4555 && !const_ok_for_arm (INTVAL (operands[6])))
4556 output_asm_insn (\"cmn\\t%5, #%n6\", operands);
4558 output_asm_insn (\"cmp\\t%5, %6\", operands);
4559 return \"mov%d7\\t%0, %1, %S8\;mov%D7\\t%0, %3, %S9\";
4561 [(set_attr "conds" "clob")
4562 (set_attr "length" "12")])
4565 [(set (match_operand:SI 0 "s_register_operand" "=r")
4566 (if_then_else:SI (match_operator 6 "comparison_operator"
4567 [(match_operand:SI 4 "s_register_operand" "r")
4568 (match_operand:SI 5 "arm_add_operand" "rL")])
4569 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4570 (match_operator:SI 7 "shiftable_operator"
4571 [(match_operand:SI 2 "s_register_operand" "r")
4572 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
4576 if (GET_CODE (operands[5]) == CONST_INT
4577 && !const_ok_for_arm (INTVAL (operands[5])))
4578 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4580 output_asm_insn (\"cmp\\t%4, %5\", operands);
4581 return \"mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3\";
4583 [(set_attr "conds" "clob")
4584 (set_attr "length" "12")])
4587 [(set (match_operand:SI 0 "s_register_operand" "=r")
4588 (if_then_else:SI (match_operator 6 "comparison_operator"
4589 [(match_operand:SI 4 "s_register_operand" "r")
4590 (match_operand:SI 5 "arm_add_operand" "rL")])
4591 (match_operator:SI 7 "shiftable_operator"
4592 [(match_operand:SI 2 "s_register_operand" "r")
4593 (match_operand:SI 3 "arm_rhs_operand" "rI")])
4594 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
4598 if (GET_CODE (operands[5]) == CONST_INT
4599 && !const_ok_for_arm (INTVAL (operands[5])))
4600 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4602 output_asm_insn (\"cmp\\t%4, %5\", operands);
4603 return \"mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3\";
4605 [(set_attr "conds" "clob")
4606 (set_attr "length" "12")])
4609 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4610 (if_then_else:SI (match_operator 5 "comparison_operator"
4611 [(match_operand:SI 3 "s_register_operand" "r,r")
4612 (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4614 (match_operand:SI 2 "s_register_operand" "r,r"))
4615 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4616 (clobber (reg:CC 24))]
4619 if (GET_CODE (operands[4]) == CONST_INT
4620 && !const_ok_for_arm (INTVAL (operands[4])))
4621 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4623 output_asm_insn (\"cmp\\t%3, %4\", operands);
4624 if (which_alternative != 0)
4625 output_asm_insn (\"mov%D5\\t%0, %1\", operands);
4626 return \"rsb%d5\\t%0, %2, #0\";
4628 [(set_attr "conds" "clob")
4629 (set_attr "length" "8,12")])
4632 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4633 (if_then_else:SI (match_operator 5 "comparison_operator"
4634 [(match_operand:SI 3 "s_register_operand" "r,r")
4635 (match_operand:SI 4 "arm_add_operand" "rL,rL")])
4636 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4638 (match_operand:SI 2 "s_register_operand" "r,r"))))
4639 (clobber (reg:CC 24))]
4642 if (GET_CODE (operands[4]) == CONST_INT
4643 && !const_ok_for_arm (INTVAL (operands[4])))
4644 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4646 output_asm_insn (\"cmp\\t%3, %4\", operands);
4647 if (which_alternative != 0)
4648 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4649 return \"rsb%D5\\t%0, %2, #0\";
4651 [(set_attr "conds" "clob")
4652 (set_attr "length" "8,12")])
4655 [(set (match_operand:SI 0 "s_register_operand" "=r")
4656 (match_operator:SI 1 "shiftable_operator"
4657 [(match_operand:SI 2 "memory_operand" "m")
4658 (match_operand:SI 3 "memory_operand" "m")]))
4659 (clobber (match_scratch:SI 4 "=r"))]
4660 "adjacent_mem_locations (operands[2], operands[3])"
4665 int val1 = 0, val2 = 0;
4667 if (REGNO (operands[0]) > REGNO (operands[4]))
4669 ldm[1] = operands[4];
4670 ldm[2] = operands[0];
4674 ldm[1] = operands[0];
4675 ldm[2] = operands[4];
4677 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4678 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4679 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4680 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4681 arith[0] = operands[0];
4695 ldm[0] = ops[0] = operands[4];
4696 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4697 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4698 output_add_immediate (ops);
4700 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4702 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4706 ldm[0] = XEXP (operands[3], 0);
4708 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4710 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4714 ldm[0] = XEXP (operands[2], 0);
4716 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4718 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4720 output_asm_insn (\"%I1%?\\t%0, %1, %2\", arith);
4724 [(set_attr "length" "12")
4725 (set_attr "type" "load")])
4727 ;; the arm can support extended pre-inc instructions
4729 ;; In all these cases, we use operands 0 and 1 for the register being
4730 ;; incremented because those are the operands that local-alloc will
4731 ;; tie and these are the pair most likely to be tieable (and the ones
4732 ;; that will benefit the most).
4734 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4735 ;; elimination will cause too many headaches.
4738 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4739 (match_operand:SI 2 "index_operand" "rJ")))
4740 (match_operand:QI 3 "s_register_operand" "r"))
4741 (set (match_operand:SI 0 "s_register_operand" "=r")
4742 (plus:SI (match_dup 1) (match_dup 2)))]
4743 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4744 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4745 && (GET_CODE (operands[2]) != REG
4746 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4747 "str%?b\\t%3, [%0, %2]!"
4748 [(set_attr "type" "store1")])
4751 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4752 (match_operand:SI 2 "s_register_operand" "r")))
4753 (match_operand:QI 3 "s_register_operand" "r"))
4754 (set (match_operand:SI 0 "s_register_operand" "=r")
4755 (minus:SI (match_dup 1) (match_dup 2)))]
4756 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4757 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4758 && (GET_CODE (operands[2]) != REG
4759 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4760 "str%?b\\t%3, [%0, -%2]!"
4761 [(set_attr "type" "store1")])
4764 [(set (match_operand:QI 3 "s_register_operand" "=r")
4765 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4766 (match_operand:SI 2 "index_operand" "rJ"))))
4767 (set (match_operand:SI 0 "s_register_operand" "=r")
4768 (plus:SI (match_dup 1) (match_dup 2)))]
4769 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4770 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4771 && (GET_CODE (operands[2]) != REG
4772 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4773 "ldr%?b\\t%3, [%0, %2]!"
4774 [(set_attr "type" "load")])
4777 [(set (match_operand:QI 3 "s_register_operand" "=r")
4778 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4779 (match_operand:SI 2 "s_register_operand" "r"))))
4780 (set (match_operand:SI 0 "s_register_operand" "=r")
4781 (minus:SI (match_dup 1) (match_dup 2)))]
4782 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4783 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4784 && (GET_CODE (operands[2]) != REG
4785 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4786 "ldr%?b\\t%3, [%0, -%2]!"
4787 [(set_attr "type" "load")])
4790 [(set (match_operand:SI 3 "s_register_operand" "=r")
4792 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4793 (match_operand:SI 2 "index_operand" "rJ")))))
4794 (set (match_operand:SI 0 "s_register_operand" "=r")
4795 (plus:SI (match_dup 1) (match_dup 2)))]
4796 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4797 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4798 && (GET_CODE (operands[2]) != REG
4799 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4800 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4801 [(set_attr "type" "load")])
4804 [(set (match_operand:SI 3 "s_register_operand" "=r")
4806 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4807 (match_operand:SI 2 "s_register_operand" "r")))))
4808 (set (match_operand:SI 0 "s_register_operand" "=r")
4809 (minus:SI (match_dup 1) (match_dup 2)))]
4810 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4811 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4812 && (GET_CODE (operands[2]) != REG
4813 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4814 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4815 [(set_attr "type" "load")])
4818 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4819 (match_operand:SI 2 "index_operand" "rJ")))
4820 (match_operand:SI 3 "s_register_operand" "r"))
4821 (set (match_operand:SI 0 "s_register_operand" "=r")
4822 (plus:SI (match_dup 1) (match_dup 2)))]
4823 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4824 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4825 && (GET_CODE (operands[2]) != REG
4826 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4827 "str%?\\t%3, [%0, %2]!"
4828 [(set_attr "type" "store1")])
4831 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4832 (match_operand:SI 2 "s_register_operand" "r")))
4833 (match_operand:SI 3 "s_register_operand" "r"))
4834 (set (match_operand:SI 0 "s_register_operand" "=r")
4835 (minus:SI (match_dup 1) (match_dup 2)))]
4836 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4837 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4838 && (GET_CODE (operands[2]) != REG
4839 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4840 "str%?\\t%3, [%0, -%2]!"
4841 [(set_attr "type" "store1")])
4844 [(set (match_operand:SI 3 "s_register_operand" "=r")
4845 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4846 (match_operand:SI 2 "index_operand" "rJ"))))
4847 (set (match_operand:SI 0 "s_register_operand" "=r")
4848 (plus:SI (match_dup 1) (match_dup 2)))]
4849 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4850 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4851 && (GET_CODE (operands[2]) != REG
4852 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4853 "ldr%?\\t%3, [%0, %2]!"
4854 [(set_attr "type" "load")])
4857 [(set (match_operand:SI 3 "s_register_operand" "=r")
4858 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4859 (match_operand:SI 2 "s_register_operand" "r"))))
4860 (set (match_operand:SI 0 "s_register_operand" "=r")
4861 (minus:SI (match_dup 1) (match_dup 2)))]
4862 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4863 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4864 && (GET_CODE (operands[2]) != REG
4865 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4866 "ldr%?\\t%3, [%0, -%2]!"
4867 [(set_attr "type" "load")])
4870 [(set (match_operand:HI 3 "s_register_operand" "=r")
4871 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4872 (match_operand:SI 2 "index_operand" "rJ"))))
4873 (set (match_operand:SI 0 "s_register_operand" "=r")
4874 (plus:SI (match_dup 1) (match_dup 2)))]
4875 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4876 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4877 && (GET_CODE (operands[2]) != REG
4878 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4879 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
4880 [(set_attr "type" "load")])
4883 [(set (match_operand:HI 3 "s_register_operand" "=r")
4884 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4885 (match_operand:SI 2 "s_register_operand" "r"))))
4886 (set (match_operand:SI 0 "s_register_operand" "=r")
4887 (minus:SI (match_dup 1) (match_dup 2)))]
4888 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4889 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4890 && (GET_CODE (operands[2]) != REG
4891 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4892 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
4893 [(set_attr "type" "load")])
4896 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4897 [(match_operand:SI 3 "s_register_operand" "r")
4898 (match_operand:SI 4 "const_shift_operand" "n")])
4899 (match_operand:SI 1 "s_register_operand" "0")))
4900 (match_operand:QI 5 "s_register_operand" "r"))
4901 (set (match_operand:SI 0 "s_register_operand" "=r")
4902 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4904 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4905 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4906 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4907 "str%?b\\t%5, [%0, %3, %S2]!"
4908 [(set_attr "type" "store1")])
4911 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4912 (match_operator:SI 2 "shift_operator"
4913 [(match_operand:SI 3 "s_register_operand" "r")
4914 (match_operand:SI 4 "const_shift_operand" "n")])))
4915 (match_operand:QI 5 "s_register_operand" "r"))
4916 (set (match_operand:SI 0 "s_register_operand" "=r")
4917 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4919 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4920 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4921 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4922 "str%?b\\t%5, [%0, -%3, %S2]!"
4923 [(set_attr "type" "store1")])
4926 [(set (match_operand:QI 5 "s_register_operand" "=r")
4927 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
4928 [(match_operand:SI 3 "s_register_operand" "r")
4929 (match_operand:SI 4 "const_shift_operand" "n")])
4930 (match_operand:SI 1 "s_register_operand" "0"))))
4931 (set (match_operand:SI 0 "s_register_operand" "=r")
4932 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4934 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4935 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4936 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4937 "ldr%?b\\t%5, [%0, %3, %S2]!"
4938 [(set_attr "type" "load")])
4941 [(set (match_operand:QI 5 "s_register_operand" "=r")
4942 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4943 (match_operator:SI 2 "shift_operator"
4944 [(match_operand:SI 3 "s_register_operand" "r")
4945 (match_operand:SI 4 "const_shift_operand" "n")]))))
4946 (set (match_operand:SI 0 "s_register_operand" "=r")
4947 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4949 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4950 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4951 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4952 "ldr%?b\\t%5, [%0, -%3, %S2]!"
4953 [(set_attr "type" "load")])
4956 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4957 [(match_operand:SI 3 "s_register_operand" "r")
4958 (match_operand:SI 4 "const_shift_operand" "n")])
4959 (match_operand:SI 1 "s_register_operand" "0")))
4960 (match_operand:SI 5 "s_register_operand" "r"))
4961 (set (match_operand:SI 0 "s_register_operand" "=r")
4962 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4964 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4965 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4966 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4967 "str%?\\t%5, [%0, %3, %S2]!"
4968 [(set_attr "type" "store1")])
4971 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4972 (match_operator:SI 2 "shift_operator"
4973 [(match_operand:SI 3 "s_register_operand" "r")
4974 (match_operand:SI 4 "const_shift_operand" "n")])))
4975 (match_operand:SI 5 "s_register_operand" "r"))
4976 (set (match_operand:SI 0 "s_register_operand" "=r")
4977 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4979 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4980 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4981 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4982 "str%?\\t%5, [%0, -%3, %S2]!"
4983 [(set_attr "type" "store1")])
4986 [(set (match_operand:SI 5 "s_register_operand" "=r")
4987 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
4988 [(match_operand:SI 3 "s_register_operand" "r")
4989 (match_operand:SI 4 "const_shift_operand" "n")])
4990 (match_operand:SI 1 "s_register_operand" "0"))))
4991 (set (match_operand:SI 0 "s_register_operand" "=r")
4992 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
4994 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4995 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4996 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
4997 "ldr%?\\t%5, [%0, %3, %S2]!"
4998 [(set_attr "type" "load")])
5001 [(set (match_operand:SI 5 "s_register_operand" "=r")
5002 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5003 (match_operator:SI 2 "shift_operator"
5004 [(match_operand:SI 3 "s_register_operand" "r")
5005 (match_operand:SI 4 "const_shift_operand" "n")]))))
5006 (set (match_operand:SI 0 "s_register_operand" "=r")
5007 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5009 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5010 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5011 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5012 "ldr%?\\t%5, [%0, -%3, %S2]!"
5013 [(set_attr "type" "load")])
5016 [(set (match_operand:HI 5 "s_register_operand" "=r")
5017 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5018 [(match_operand:SI 3 "s_register_operand" "r")
5019 (match_operand:SI 4 "const_shift_operand" "n")])
5020 (match_operand:SI 1 "s_register_operand" "0"))))
5021 (set (match_operand:SI 0 "s_register_operand" "=r")
5022 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5024 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5025 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5026 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5027 "ldr%?\\t%5, [%0, %3, %S2]!\\t%@ loadhi"
5028 [(set_attr "type" "load")])
5031 [(set (match_operand:HI 5 "s_register_operand" "=r")
5032 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5033 (match_operator:SI 2 "shift_operator"
5034 [(match_operand:SI 3 "s_register_operand" "r")
5035 (match_operand:SI 4 "const_shift_operand" "n")]))))
5036 (set (match_operand:SI 0 "s_register_operand" "=r")
5037 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5039 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5040 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5041 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5042 "ldr%?\\t%5, [%0, -%3, %S2]!\\t%@ loadhi"
5043 [(set_attr "type" "load")])
5045 ; It can also support extended post-inc expressions, but combine doesn't
5047 ; It doesn't seem worth adding peepholes for anything but the most common
5048 ; cases since, unlike combine, the increment must immediately follow the load
5049 ; for this pattern to match.
5050 ; When loading we must watch to see that the base register isn't trampled by
5051 ; the load. In such cases this isn't a post-inc expression.
5054 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5055 (match_operand:QI 2 "s_register_operand" "r"))
5057 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5059 "strb\\t%2, [%0], %1")
5062 [(set (match_operand:QI 0 "s_register_operand" "=r")
5063 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5065 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5066 "REGNO(operands[0]) != REGNO(operands[1])
5067 && (GET_CODE (operands[2]) != REG
5068 || REGNO(operands[0]) != REGNO (operands[2]))"
5069 "ldr%?b\\t%0, [%1], %2")
5072 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5073 (match_operand:SI 2 "s_register_operand" "r"))
5075 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5077 "str%?\\t%2, [%0], %1")
5080 [(set (match_operand:HI 0 "s_register_operand" "=r")
5081 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5083 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5084 "REGNO(operands[0]) != REGNO(operands[1])
5085 && (GET_CODE (operands[2]) != REG
5086 || REGNO(operands[0]) != REGNO (operands[2]))"
5087 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5090 [(set (match_operand:SI 0 "s_register_operand" "=r")
5091 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5093 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5094 "REGNO(operands[0]) != REGNO(operands[1])
5095 && (GET_CODE (operands[2]) != REG
5096 || REGNO(operands[0]) != REGNO (operands[2]))"
5097 "ldr%?\\t%0, [%1], %2")
5099 ; This pattern is never tried by combine, so do it as a peephole
5102 [(set (match_operand:SI 0 "s_register_operand" "=r")
5103 (match_operand:SI 1 "s_register_operand" "r"))
5104 (set (match_operand 2 "cc_register" "")
5105 (compare (match_dup 1) (const_int 0)))]
5107 "sub%?s\\t%0, %1, #0"
5108 [(set_attr "conds" "set")])
5110 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5111 ; reversed, check that the memory references aren't volatile.
5114 [(set (match_operand:SI 0 "s_register_operand" "=r")
5115 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5117 (set (match_operand:SI 2 "s_register_operand" "=r")
5118 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5119 (set (match_operand:SI 3 "s_register_operand" "=r")
5120 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5121 (set (match_operand:SI 4 "s_register_operand" "=r")
5122 (mem:SI (match_dup 1)))]
5123 "REGNO (operands[0]) > REGNO (operands[2])
5124 && REGNO (operands[2]) > REGNO (operands[3])
5125 && REGNO (operands[3]) > REGNO (operands[4])
5126 && !(REGNO (operands[1]) == REGNO (operands[0])
5127 || REGNO (operands[1]) == REGNO (operands[2])
5128 || REGNO (operands[1]) == REGNO (operands[3])
5129 || REGNO (operands[1]) == REGNO (operands[4]))
5130 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5131 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5132 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5133 (prev_nonnote_insn (insn)))))
5134 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5136 (prev_nonnote_insn (insn))))))"
5137 "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
5140 [(set (match_operand:SI 0 "s_register_operand" "=r")
5141 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5143 (set (match_operand:SI 2 "s_register_operand" "=r")
5144 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5145 (set (match_operand:SI 3 "s_register_operand" "=r")
5146 (mem:SI (match_dup 1)))]
5147 "REGNO (operands[0]) > REGNO (operands[2])
5148 && REGNO (operands[2]) > REGNO (operands[3])
5149 && !(REGNO (operands[1]) == REGNO (operands[0])
5150 || REGNO (operands[1]) == REGNO (operands[2])
5151 || REGNO (operands[1]) == REGNO (operands[3]))
5152 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5153 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
5154 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
5155 (prev_nonnote_insn (insn)))))"
5156 "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
5159 [(set (match_operand:SI 0 "s_register_operand" "=r")
5160 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5162 (set (match_operand:SI 2 "s_register_operand" "=r")
5163 (mem:SI (match_dup 1)))]
5164 "REGNO (operands[0]) > REGNO (operands[2])
5165 && !(REGNO (operands[1]) == REGNO (operands[0])
5166 || REGNO (operands[1]) == REGNO (operands[2]))
5167 && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
5168 && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
5169 "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
5172 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5174 (match_operand:SI 0 "s_register_operand" "r"))
5175 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5176 (match_operand:SI 2 "s_register_operand" "r"))
5177 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5178 (match_operand:SI 3 "s_register_operand" "r"))
5179 (set (mem:SI (match_dup 1))
5180 (match_operand:SI 4 "s_register_operand" "r"))]
5181 "REGNO (operands[0]) > REGNO (operands[2])
5182 && REGNO (operands[2]) > REGNO (operands[3])
5183 && REGNO (operands[3]) > REGNO (operands[4])
5184 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5185 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5186 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5187 (prev_nonnote_insn (insn)))))
5188 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5190 (prev_nonnote_insn (insn))))))"
5191 "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
5194 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5196 (match_operand:SI 0 "s_register_operand" "r"))
5197 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5198 (match_operand:SI 2 "s_register_operand" "r"))
5199 (set (mem:SI (match_dup 1))
5200 (match_operand:SI 3 "s_register_operand" "r"))]
5201 "REGNO (operands[0]) > REGNO (operands[2])
5202 && REGNO (operands[2]) > REGNO (operands[3])
5203 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5204 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
5205 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
5206 (prev_nonnote_insn (insn)))))"
5207 "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
5210 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
5212 (match_operand:SI 0 "s_register_operand" "r"))
5213 (set (mem:SI (match_dup 1))
5214 (match_operand:SI 2 "s_register_operand" "r"))]
5215 "REGNO (operands[0]) > REGNO (operands[2])
5216 && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
5217 && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
5218 "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
5220 ;; A call followed by return can be replaced by restoring the regs and
5221 ;; jumping to the subroutine, provided we aren't passing the address of
5222 ;; any of our local variables. If we call alloca then this is unsafe
5223 ;; since restoring the frame frees the memory, which is not what we want.
5224 ;; Sometimes the return might have been targeted by the final prescan:
5225 ;; if so then emit a propper return insn as well.
5226 ;; Unfortunately, if the frame pointer is required, we don't know if the
5227 ;; current function has any implicit stack pointer adjustments that will
5228 ;; be restored by the return: we can't therefore do a tail call.
5229 ;; Another unfortunate that we can't handle is if current_function_args_size
5230 ;; is non-zero: in this case elimination of the argument pointer assumed
5231 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5235 [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
5236 (match_operand:SI 1 "general_operand" "g"))
5237 (clobber (reg:SI 14))])
5239 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5240 && !get_frame_size () && !current_function_calls_alloca
5241 && !frame_pointer_needed && !current_function_args_size)"
5244 extern rtx arm_target_insn;
5245 extern int arm_ccfsm_state, arm_current_cc;
5247 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5249 arm_current_cc ^= 1;
5250 output_return_instruction (NULL, TRUE);
5251 arm_ccfsm_state = 0;
5252 arm_target_insn = NULL;
5255 output_return_instruction (NULL, FALSE);
5256 return \"b%?\\t%a0\";
5258 [(set (attr "conds")
5259 (if_then_else (eq_attr "cpu" "arm6")
5260 (const_string "clob")
5261 (const_string "nocond")))
5262 (set_attr "length" "8")])
5265 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5266 (call (mem:SI (match_operand:SI 1 "" "i"))
5267 (match_operand:SI 2 "general_operand" "g")))
5268 (clobber (reg:SI 14))])
5270 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5271 && !get_frame_size () && !current_function_calls_alloca
5272 && !frame_pointer_needed && !current_function_args_size)"
5275 extern rtx arm_target_insn;
5276 extern int arm_ccfsm_state, arm_current_cc;
5278 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5280 arm_current_cc ^= 1;
5281 output_return_instruction (NULL, TRUE);
5282 arm_ccfsm_state = 0;
5283 arm_target_insn = NULL;
5286 output_return_instruction (NULL, FALSE);
5287 return \"b%?\\t%a1\";
5289 [(set (attr "conds")
5290 (if_then_else (eq_attr "cpu" "arm6")
5291 (const_string "clob")
5292 (const_string "nocond")))
5293 (set_attr "length" "8")])
5295 ;; As above but when this function is not void, we must be returning the
5296 ;; result of the called subroutine.
5299 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5300 (call (mem:SI (match_operand:SI 1 "" "i"))
5301 (match_operand:SI 2 "general_operand" "g")))
5302 (clobber (reg:SI 14))])
5305 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5306 && !get_frame_size () && !current_function_calls_alloca
5307 && !frame_pointer_needed && !current_function_args_size)"
5310 extern rtx arm_target_insn;
5311 extern int arm_ccfsm_state, arm_current_cc;
5313 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5315 arm_current_cc ^= 1;
5316 output_return_instruction (NULL, TRUE);
5317 arm_ccfsm_state = 0;
5318 arm_target_insn = NULL;
5321 output_return_instruction (NULL, FALSE);
5322 return \"b%?\\t%a1\";
5324 [(set (attr "conds")
5325 (if_then_else (eq_attr "cpu" "arm6")
5326 (const_string "clob")
5327 (const_string "nocond")))
5328 (set_attr "length" "8")])
5330 ;; If calling a subroutine and then jumping back to somewhere else, but not
5331 ;; too far away, then we can set the link register with the branch address
5332 ;; and jump direct to the subroutine. On return from the subroutine
5333 ;; execution continues at the branch; this avoids a prefetch stall.
5334 ;; We use the length attribute (via short_branch ()) to establish whether or
5335 ;; not this is possible, this is the same asthe sparc does.
5338 [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
5339 (match_operand:SI 1 "general_operand" "g"))
5340 (clobber (reg:SI 14))])
5342 (label_ref (match_operand 2 "" "")))]
5343 "GET_CODE (operands[0]) == SYMBOL_REF
5344 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5345 && arm_insn_not_targeted (insn)"
5348 int backward = arm_backwards_branch (INSN_UID (insn),
5349 INSN_UID (operands[2]));
5352 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5353 * above, leaving it out means that the code will still run on an arm 2 or 3
5358 output_asm_insn (\"sub%?\\tlr, pc, #(8 + . -%l2)\", operands);
5360 output_asm_insn (\"add%?\\tlr, pc, #(%l2 - . -8)\", operands);
5365 output_asm_insn (\"mov%?\\tlr, pc\\t%@ protect cc\", operands);
5367 output_asm_insn (\"sub%?\\tlr, lr, #(4 + . -%l2)\", operands);
5369 output_asm_insn (\"add%?\\tlr, lr, #(%l2 - . -4)\", operands);
5371 return \"b%?\\t%a0\";
5373 [(set (attr "conds")
5374 (if_then_else (eq_attr "cpu" "arm6")
5375 (const_string "clob")
5376 (const_string "nocond")))
5377 (set (attr "length")
5378 (if_then_else (eq_attr "cpu" "arm6")
5383 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5384 (call (mem:SI (match_operand:SI 1 "" "i"))
5385 (match_operand:SI 2 "general_operand" "g")))
5386 (clobber (reg:SI 14))])
5388 (label_ref (match_operand 3 "" "")))]
5389 "GET_CODE (operands[0]) == SYMBOL_REF
5390 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5391 && arm_insn_not_targeted (insn)"
5394 int backward = arm_backwards_branch (INSN_UID (insn),
5395 INSN_UID (operands[3]));
5398 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5399 * above, leaving it out means that the code will still run on an arm 2 or 3
5404 output_asm_insn (\"sub%?\\tlr, pc, #(8 + . -%l3)\", operands);
5406 output_asm_insn (\"add%?\\tlr, pc, #(%l3 - . -8)\", operands);
5411 output_asm_insn (\"mov%?\\tlr, pc\\t%@ protect cc\", operands);
5413 output_asm_insn (\"sub%?\\tlr, lr, #(4 + . -%l3)\", operands);
5415 output_asm_insn (\"add%?\\tlr, lr, #(%l3 - . -4)\", operands);
5417 return \"b%?\\t%a1\";
5419 [(set (attr "conds")
5420 (if_then_else (eq_attr "cpu" "arm6")
5421 (const_string "clob")
5422 (const_string "nocond")))
5423 (set (attr "length")
5424 (if_then_else (eq_attr "cpu" "arm6")
5430 (if_then_else (match_operator 0 "comparison_operator"
5431 [(match_operator:SI 1 "shift_operator"
5432 [(match_operand:SI 2 "s_register_operand" "r")
5433 (match_operand:SI 3 "nonmemory_operand" "rn")])
5434 (match_operand:SI 4 "s_register_operand" "r")])
5435 (label_ref (match_operand 5 "" ""))
5440 (compare:CC (match_dup 4)
5441 (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
5443 (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
5444 (label_ref (match_dup 5))
5447 operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
5448 operands[1], operands[2]);
5452 [(set (match_operand:SI 0 "s_register_operand" "")
5453 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5455 (neg:SI (match_operator:SI 2 "comparison_operator"
5456 [(match_operand:SI 3 "s_register_operand" "")
5457 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5458 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5460 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5461 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5465 ;; This pattern can be used because cc_noov mode implies that the following
5466 ;; branch will be an equality (EQ or NE), so the sign extension is not
5467 ;; needed. Combine doesn't eliminate these because by the time it sees the
5468 ;; branch it no-longer knows that the data came from memory.
5471 [(set (reg:CC_NOOV 24)
5473 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
5475 (match_operand 1 "immediate_operand" "I")))
5476 (clobber (match_scratch:SI 2 "=r"))]
5477 "((unsigned long) INTVAL (operands[1]))
5478 == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
5480 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5481 output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
5482 output_asm_insn (\"cmp%?\\t%2, %1\", operands);
5485 [(set_attr "conds" "set")
5486 (set_attr "length" "8")
5487 (set_attr "type" "load")])
5489 (define_expand "save_stack_nonlocal"
5490 [(match_operand:DI 0 "memory_operand" "")
5491 (match_operand:SI 1 "s_register_operand" "")]
5495 /* We also need to save the frame pointer for non-local gotos */
5496 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
5497 hard_frame_pointer_rtx);
5498 emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
5502 (define_expand "restore_stack_nonlocal"
5503 [(match_operand:SI 0 "s_register_operand" "")
5504 (match_operand:DI 1 "memory_operand" "")]
5508 /* Restore the frame pointer first, the stack pointer second. */
5509 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
5510 emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0,
5515 ;; This split is only used during output to reduce the number of patterns
5516 ;; that need assembler instructions adding to them. We allowed the setting
5517 ;; of the conditions to be implicit during rtl generation so that
5518 ;; the conditional compare patterns would work. However this conflicts to
5519 ;; some extend with the conditional data operations, so we have to split them
5523 [(set (match_operand:SI 0 "s_register_operand" "")
5524 (if_then_else:SI (match_operator 1 "comparison_operator"
5525 [(match_operand 2 "" "") (match_operand 3 "" "")])
5526 (match_operand 4 "" "")
5527 (match_operand 5 "" "")))
5530 [(set (match_dup 6) (match_dup 7))
5532 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5537 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5540 operands[6] = gen_rtx (REG, mode, 24);
5541 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5547 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5548 (if_then_else:SI (match_operator 4 "comparison_operator"
5549 [(match_operand 3 "cc_register" "") (const_int 0)])
5550 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5552 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5556 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5557 [(set_attr "conds" "use")
5558 (set_attr "length" "4,8")])
5560 ;; The next two patterns occur when an AND operation is followed by a
5561 ;; scc insn sequence
5564 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5567 (match_operand:SI 2 "immediate_operand" "n")))]
5570 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5571 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5572 return \"mvnne\\t%0, #0\";
5574 [(set_attr "conds" "clob")
5575 (set_attr "length" "8")])
5578 [(set (match_operand:SI 0 "s_register_operand" "=r")
5580 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5582 (match_operand:SI 2 "immediate_operand" "n"))))]
5585 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5586 output_asm_insn (\"tst\\t%1, %2\", operands);
5587 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5588 return \"movne\\t%0, #0\";
5590 [(set_attr "conds" "clob")
5591 (set_attr "length" "12")])