1 ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
2 ;; Copyright (C) 1991, 1993, 1994, 1995, 1996 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, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; There are patterns in this file to support XFmode arithmetic.
27 ;; Unfortunately RISC iX doesn't work well with these so they are disabled.
31 ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
32 ;; the mode is MODE_FLOAT
33 ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
34 ;; the mode is MODE_FLOAT
35 ;; 2 `push multiple' operation: operand 0 is the first register. Subsequent
36 ;; registers are in parallel (use...) expressions.
37 ;; 3 A symbol that has been treated properly for pic usage, that is, we
38 ;; will add the pic_register value to it before trying to dereference it.
42 ; PROG_MODE attribute is used to determine whether condition codes are
43 ; clobbered by a call insn: they are if in prog32 mode. This is controlled
44 ; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
45 (define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
47 ; CPU attribute is used to determine whether condition codes are clobbered
48 ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
49 ; arm2 and arm3 the condition codes are restored by the return.
51 (define_attr "cpu" "arm2,arm3,arm6,arm7"
52 (const (symbol_ref "arm_cpu_attr")))
54 ; Floating Point Unit. If we only have floating point emulation, then there
55 ; is no point in scheduling the floating point insns. (Well, for best
56 ; performance we should try and group them together).
58 (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
60 ; LENGTH of an instruction (in bytes)
61 (define_attr "length" "" (const_int 4))
63 ; An assembler sequence may clobber the condition codes without us knowing
64 (define_asm_attributes
65 [(set_attr "conds" "clob")
66 (set_attr "length" "4")])
68 ; TYPE attribute is used to detect floating point instructions which, if
69 ; running on a co-processor can run in parallel with other, basic instructions
70 ; If write-buffer scheduling is enabled then it can also be used in the
71 ; scheduling of writes.
73 ; Classification of each insn
74 ; normal any data instruction that doesn't hit memory or fp regs
75 ; mult a multiply instruction
76 ; block blockage insn, this blocks all functional units
77 ; float a floating point arithmetic operation (subject to expansion)
78 ; fdivx XFmode floating point division
79 ; fdivd DFmode floating point division
80 ; fdivs SFmode floating point division
81 ; fmul Floating point multiply
82 ; ffmul Fast floating point multiply
83 ; farith Floating point arithmetic (4 cycle)
84 ; ffarith Fast floating point arithmetic (2 cycle)
85 ; float_em a floating point arithmetic operation that is normally emulated
86 ; even on a machine with an fpa.
87 ; f_load a floating point load from memory
88 ; f_store a floating point store to memory
89 ; f_mem_r a transfer of a floating point register to a real reg via mem
90 ; r_mem_f the reverse of f_mem_r
91 ; f_2_r fast transfer float to arm (no memory needed)
92 ; r_2_f fast transfer arm to float
93 ; call a subroutine call
94 ; load any load from memory
95 ; store1 store 1 word to memory from arm registers
96 ; store2 store 2 words
97 ; store3 store 3 words
98 ; store4 store 4 words
101 "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
102 (const_string "normal"))
104 ; condition codes: this one is used by final_prescan_insn to speed up
105 ; conditionalizing instructions. It saves having to scan the rtl to see if
106 ; it uses or alters the condition codes.
108 ; USE means that the condition codes are used by the insn in the process of
109 ; outputting code, this means (at present) that we can't use the insn in
112 ; SET means that the purpose of the insn is to set the condition codes in a
113 ; well defined manner.
115 ; CLOB means that the condition codes are altered in an undefined manner, if
116 ; they are altered at all
118 ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
119 ; but are if the branch wasn't taken; the effect is to limit the branch
120 ; elimination scanning.
122 ; NOCOND means that the condition codes are neither altered nor affect the
123 ; output of this insn
125 (define_attr "conds" "use,set,clob,jump_clob,nocond"
126 (if_then_else (eq_attr "type" "call")
127 (if_then_else (eq_attr "prog_mode" "prog32")
128 (const_string "clob") (const_string "nocond"))
129 (const_string "nocond")))
131 (define_attr "write_conflict" "no,yes"
132 (if_then_else (eq_attr "type"
133 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
135 (const_string "no")))
137 (define_attr "core_cycles" "single,multi"
138 (if_then_else (eq_attr "type"
139 "normal,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
140 (const_string "single")
141 (const_string "multi")))
143 ; The write buffer on some of the arm6 processors is hard to model exactly.
144 ; There is room in the buffer for up to two addresses and up to eight words
145 ; of memory, but the two needn't be split evenly. When writing the two
146 ; addresses are fully pipelined. However, a read from memory that is not
147 ; currently in the cache will block until the writes have completed.
148 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
149 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
150 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
151 ; cycle to add as well.
153 ;; (define_function_unit {name} {num-units} {n-users} {test}
154 ;; {ready-delay} {issue-delay} [{conflict-list}])
155 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
156 (eq_attr "type" "fdivx")) 71 69)
158 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
159 (eq_attr "type" "fdivd")) 59 57)
161 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
162 (eq_attr "type" "fdivs")) 31 29)
164 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
165 (eq_attr "type" "fmul")) 9 7)
167 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
168 (eq_attr "type" "ffmul")) 6 4)
170 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
171 (eq_attr "type" "farith")) 4 2)
173 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
174 (eq_attr "type" "ffarith")) 2 2)
176 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
177 (eq_attr "type" "r_2_f")) 5 3)
179 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
180 (eq_attr "type" "f_2_r")) 1 2)
182 ;; The fpa10 doesn't really have a memory read unit, but it can start to
183 ;; speculatively execute the instruction in the pipeline, provided the data
184 ;; is already loaded, so pretend reads have a delay of 2 (and that the
185 ;; pipeline is infinite.
187 (define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
188 (eq_attr "type" "f_load")) 3 1)
190 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 5 3)
191 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 7 4)
192 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 9 5)
193 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 11 6)
194 (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 5 3)
196 ;; The write_blockage unit models (partially), the fact that writes will stall
197 ;; until the write buffer empties.
199 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store1") 5 5
200 [(eq_attr "write_conflict" "yes")])
201 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store2") 7 7
202 [(eq_attr "write_conflict" "yes")])
203 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store3") 9 9
204 [(eq_attr "write_conflict" "yes")])
205 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store4") 11 11
206 [(eq_attr "write_conflict" "yes")])
207 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "r_mem_f") 5 5
208 [(eq_attr "write_conflict" "yes")])
209 (define_function_unit "write_blockage" 1 0
210 (eq_attr "write_conflict" "yes") 1 1)
212 (define_function_unit "core" 1 1 (eq_attr "core_cycles" "single") 1 1)
214 (define_function_unit "core" 1 1 (eq_attr "type" "load") 2 2)
216 (define_function_unit "core" 1 1 (eq_attr "type" "mult") 16 16)
218 (define_function_unit "core" 1 1 (eq_attr "type" "store1") 2 2)
220 (define_function_unit "core" 1 1 (eq_attr "type" "store2") 3 3)
222 (define_function_unit "core" 1 1 (eq_attr "type" "store3") 4 4)
224 (define_function_unit "core" 1 1 (eq_attr "type" "store4") 5 5)
226 (define_function_unit "core" 1 1
227 (and (eq_attr "core_cycles" "multi")
228 (eq_attr "type" "!mult,load,store2,store3,store4")) 32 32)
231 ;; Note: For DImode insns, there is normally no reason why operands should
232 ;; not be in the same register, what we don't want is for something being
233 ;; written to partially overlap something that is an input.
237 (define_insn "adddi3"
238 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
239 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
240 (match_operand:DI 2 "s_register_operand" "r,0")))
241 (clobber (reg:CC 24))]
243 "adds\\t%Q0, %Q1, %Q2\;adc\\t%R0, %R1, %R2"
244 [(set_attr "conds" "clob")
245 (set_attr "length" "8")])
247 (define_insn "*adddi_sesidi_di"
248 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
249 (plus:DI (sign_extend:DI
250 (match_operand:SI 2 "s_register_operand" "r,r"))
251 (match_operand:DI 1 "s_register_operand" "r,0")))
252 (clobber (reg:CC 24))]
254 "adds\\t%Q0, %Q1, %2\;adc\\t%R0, %R1, %2, asr #31"
255 [(set_attr "conds" "clob")
256 (set_attr "length" "8")])
258 (define_insn "*adddi_zesidi_di"
259 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
260 (plus:DI (zero_extend:DI
261 (match_operand:SI 2 "s_register_operand" "r,r"))
262 (match_operand:DI 1 "s_register_operand" "r,0")))
263 (clobber (reg:CC 24))]
265 "adds\\t%Q0, %Q1, %2\;adc\\t%R0, %R1, #0"
266 [(set_attr "conds" "clob")
267 (set_attr "length" "8")])
269 (define_expand "addsi3"
270 [(set (match_operand:SI 0 "s_register_operand" "")
271 (plus:SI (match_operand:SI 1 "s_register_operand" "")
272 (match_operand:SI 2 "reg_or_int_operand" "")))]
275 if (GET_CODE (operands[2]) == CONST_INT)
277 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
279 (reload_in_progress || reload_completed ? 0
280 : preserve_subexpressions_p ()));
286 [(set (match_operand:SI 0 "s_register_operand" "")
287 (plus:SI (match_operand:SI 1 "s_register_operand" "")
288 (match_operand:SI 2 "const_int_operand" "")))]
289 "! (const_ok_for_arm (INTVAL (operands[2]))
290 || const_ok_for_arm (-INTVAL (operands[2])))"
291 [(clobber (const_int 0))]
293 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
298 (define_insn "*addsi3_insn"
299 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
300 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
301 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
307 [(set_attr "length" "4,4,16")])
309 (define_insn "*addsi3_compare0"
310 [(set (reg:CC_NOOV 24)
312 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
313 (match_operand:SI 2 "arm_add_operand" "rI,L"))
315 (set (match_operand:SI 0 "s_register_operand" "=r,r")
316 (plus:SI (match_dup 1) (match_dup 2)))]
320 sub%?s\\t%0, %1, #%n2"
321 [(set_attr "conds" "set")])
323 (define_insn "*addsi3_compare0_scratch"
324 [(set (reg:CC_NOOV 24)
326 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
327 (match_operand:SI 1 "arm_add_operand" "rI,L"))
333 [(set_attr "conds" "set")])
335 ;; The next four insns work because they compare the result with one of
336 ;; the operands, and we know that the use of the condition code is
337 ;; either GEU or LTU, so we can use the carry flag from the addition
338 ;; instead of doing the compare a second time.
339 (define_insn "*addsi3_compare_op1"
342 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
343 (match_operand:SI 2 "arm_add_operand" "rI,L"))
345 (set (match_operand:SI 0 "s_register_operand" "=r,r")
346 (plus:SI (match_dup 1) (match_dup 2)))]
350 sub%?s\\t%0, %1, #%n2"
351 [(set_attr "conds" "set")])
353 (define_insn "*addsi3_compare_op2"
356 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
357 (match_operand:SI 2 "arm_add_operand" "rI,L"))
359 (set (match_operand:SI 0 "s_register_operand" "=r,r")
360 (plus:SI (match_dup 1) (match_dup 2)))]
364 sub%?s\\t%0, %1, #%n2"
365 [(set_attr "conds" "set")])
367 (define_insn "*compare_addsi2_op0"
370 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
371 (match_operand:SI 1 "arm_add_operand" "rI,L"))
377 [(set_attr "conds" "set")])
379 (define_insn "*compare_addsi2_op1"
382 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
383 (match_operand:SI 1 "arm_add_operand" "rI,L"))
389 [(set_attr "conds" "set")])
391 (define_insn "*addsi3_carryin"
392 [(set (match_operand:SI 0 "s_register_operand" "=r")
393 (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
394 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
395 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
398 [(set_attr "conds" "use")])
400 (define_insn "*addsi3_carryin_alt1"
401 [(set (match_operand:SI 0 "s_register_operand" "=r")
402 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
403 (match_operand:SI 2 "arm_rhs_operand" "rI"))
404 (ltu:SI (reg:CC_C 24) (const_int 0))))]
407 [(set_attr "conds" "use")])
409 (define_insn "*addsi3_carryin_alt2"
410 [(set (match_operand:SI 0 "s_register_operand" "=r")
411 (plus:SI (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
412 (match_operand:SI 1 "s_register_operand" "r"))
413 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
416 [(set_attr "conds" "use")])
418 (define_insn "*addsi3_carryin_alt3"
419 [(set (match_operand:SI 0 "s_register_operand" "=r")
420 (plus:SI (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
421 (match_operand:SI 2 "arm_rhs_operand" "rI"))
422 (match_operand:SI 1 "s_register_operand" "r")))]
425 [(set_attr "conds" "use")])
427 (define_insn "incscc"
428 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
429 (plus:SI (match_operator:SI 2 "comparison_operator"
430 [(reg 24) (const_int 0)])
431 (match_operand:SI 1 "s_register_operand" "0,?r")))]
435 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
436 [(set_attr "conds" "use")
437 (set_attr "length" "4,8")])
439 ; If a constant is too big to fit in a single instruction then the constant
440 ; will be pre-loaded into a register taking at least two insns, we might be
441 ; able to merge it with an add, but it depends on the exact value.
444 [(set (match_operand:SI 0 "s_register_operand" "=r")
445 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
446 (match_operand:SI 2 "const_int_operand" "n")))]
447 "!(const_ok_for_arm (INTVAL (operands[2]))
448 || const_ok_for_arm (-INTVAL (operands[2])))"
449 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
450 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
453 unsigned int val = (unsigned) INTVAL (operands[2]);
457 /* this code is similar to the approach followed in movsi, but it must
458 generate exactly two insns */
460 for (i = 30; i >= 0; i -= 2)
466 if (const_ok_for_arm (temp = (val & ~(255 << i))))
471 /* we might be able to do this as (larger number - small number) */
472 temp = ((val >> i) & 255) + 1;
473 if (temp > 255 && i < 24)
476 temp = ((val >> i) & 255) + 1;
478 if (const_ok_for_arm ((temp << i) - val))
481 temp = (unsigned) - (int) (i - val);
488 /* if we got here, we have found a way of doing it in two instructions.
489 the two constants are in val and temp */
490 operands[2] = GEN_INT ((int)val);
491 operands[3] = GEN_INT ((int)temp);
495 (define_insn "addsf3"
496 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
497 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
498 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
502 suf%?s\\t%0, %1, #%N2"
503 [(set_attr "type" "farith")])
505 (define_insn "adddf3"
506 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
507 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
508 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
512 suf%?d\\t%0, %1, #%N2"
513 [(set_attr "type" "farith")])
515 (define_insn "*adddf_df_esfdf"
516 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
517 (plus:DF (float_extend:DF
518 (match_operand:SF 1 "s_register_operand" "f,f"))
519 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
523 suf%?d\\t%0, %1, #%N2"
524 [(set_attr "type" "farith")])
526 (define_insn "*adddf_df_esfdf"
527 [(set (match_operand:DF 0 "s_register_operand" "=f")
528 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
530 (match_operand:SF 2 "s_register_operand" "f"))))]
532 "adf%?d\\t%0, %1, %2"
533 [(set_attr "type" "farith")])
535 (define_insn "*adddf_esfdf_esfdf"
536 [(set (match_operand:DF 0 "s_register_operand" "=f")
537 (plus:DF (float_extend:DF
538 (match_operand:SF 1 "s_register_operand" "f"))
540 (match_operand:SF 2 "s_register_operand" "f"))))]
542 "adf%?d\\t%0, %1, %2"
543 [(set_attr "type" "farith")])
545 (define_insn "addxf3"
546 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
547 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
548 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
549 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
552 suf%?e\\t%0, %1, #%N2"
553 [(set_attr "type" "farith")])
555 (define_insn "subdi3"
556 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
557 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
558 (match_operand:DI 2 "s_register_operand" "r,0,0")))
559 (clobber (reg:CC 24))]
561 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
562 [(set_attr "conds" "clob")
563 (set_attr "length" "8")])
565 (define_insn "*subdi_di_zesidi"
566 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
567 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
569 (match_operand:SI 2 "s_register_operand" "r,r"))))
570 (clobber (reg:CC 24))]
572 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
573 [(set_attr "conds" "clob")
574 (set_attr "length" "8")])
576 (define_insn "*subdi_di_sesidi"
577 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
578 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
580 (match_operand:SI 2 "s_register_operand" "r,r"))))
581 (clobber (reg:CC 24))]
583 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
584 [(set_attr "conds" "clob")
585 (set_attr "length" "8")])
587 (define_insn "*subdi_zesidi_di"
588 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
589 (minus:DI (zero_extend:DI
590 (match_operand:SI 2 "s_register_operand" "r,r"))
591 (match_operand:DI 1 "s_register_operand" "?r,0")))
592 (clobber (reg:CC 24))]
594 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
595 [(set_attr "conds" "clob")
596 (set_attr "length" "8")])
598 (define_insn "*subdi_sesidi_di"
599 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
600 (minus:DI (sign_extend:DI
601 (match_operand:SI 2 "s_register_operand" "r,r"))
602 (match_operand:DI 1 "s_register_operand" "?r,0")))
603 (clobber (reg:CC 24))]
605 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
606 [(set_attr "conds" "clob")
607 (set_attr "length" "8")])
609 (define_insn "*subdi_zesidi_zesidi"
610 [(set (match_operand:DI 0 "s_register_operand" "=r")
611 (minus:DI (zero_extend:DI
612 (match_operand:SI 1 "s_register_operand" "r"))
614 (match_operand:SI 2 "s_register_operand" "r"))))
615 (clobber (reg:CC 24))]
617 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
618 [(set_attr "conds" "clob")
619 (set_attr "length" "8")])
621 (define_expand "subsi3"
622 [(set (match_operand:SI 0 "s_register_operand" "")
623 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
624 (match_operand:SI 2 "s_register_operand" "")))]
627 if (GET_CODE (operands[1]) == CONST_INT)
629 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
631 (reload_in_progress || reload_completed ? 0
632 : preserve_subexpressions_p ()));
637 (define_insn "*subsi3_insn"
638 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
639 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
640 (match_operand:SI 2 "s_register_operand" "r,r")))]
645 [(set_attr "length" "4,16")])
648 [(set (match_operand:SI 0 "s_register_operand" "")
649 (minus:SI (match_operand:SI 1 "const_int_operand" "")
650 (match_operand:SI 2 "s_register_operand" "")))]
651 "! const_ok_for_arm (INTVAL (operands[1]))"
652 [(clobber (const_int 0))]
654 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
659 (define_insn "*subsi3_compare0"
660 [(set (reg:CC_NOOV 24)
661 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
662 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
664 (set (match_operand:SI 0 "s_register_operand" "=r,r")
665 (minus:SI (match_dup 1) (match_dup 2)))]
670 [(set_attr "conds" "set")])
672 (define_insn "decscc"
673 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
674 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
675 (match_operator:SI 2 "comparison_operator"
676 [(reg 24) (const_int 0)])))]
680 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
681 [(set_attr "conds" "use")
682 (set_attr "length" "*,8")])
684 (define_insn "subsf3"
685 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
686 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
687 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
692 [(set_attr "type" "farith")])
694 (define_insn "subdf3"
695 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
696 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
697 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
702 [(set_attr "type" "farith")])
704 (define_insn "*subdf_esfdf_df"
705 [(set (match_operand:DF 0 "s_register_operand" "=f")
706 (minus:DF (float_extend:DF
707 (match_operand:SF 1 "s_register_operand" "f"))
708 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
710 "suf%?d\\t%0, %1, %2"
711 [(set_attr "type" "farith")])
713 (define_insn "*subdf_df_esfdf"
714 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
715 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
717 (match_operand:SF 2 "s_register_operand" "f,f"))))]
722 [(set_attr "type" "farith")])
724 (define_insn "*subdf_esfdf_esfdf"
725 [(set (match_operand:DF 0 "s_register_operand" "=f")
726 (minus:DF (float_extend:DF
727 (match_operand:SF 1 "s_register_operand" "f"))
729 (match_operand:SF 2 "s_register_operand" "f"))))]
731 "suf%?d\\t%0, %1, %2"
732 [(set_attr "type" "farith")])
734 (define_insn "subxf3"
735 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
736 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
737 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
738 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
742 [(set_attr "type" "farith")])
744 ;; Multiplication insns
746 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
747 (define_insn "mulsi3"
748 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
749 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
750 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
753 [(set_attr "type" "mult")])
755 (define_insn "*mulsi3_compare0"
756 [(set (reg:CC_NOOV 24)
757 (compare:CC_NOOV (mult:SI
758 (match_operand:SI 2 "s_register_operand" "r,r")
759 (match_operand:SI 1 "s_register_operand" "%?r,0"))
761 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
762 (mult:SI (match_dup 2) (match_dup 1)))]
764 "mul%?s\\t%0, %2, %1"
765 [(set_attr "conds" "set")
766 (set_attr "type" "mult")])
768 (define_insn "*mulsi_compare0_scratch"
769 [(set (reg:CC_NOOV 24)
770 (compare:CC_NOOV (mult:SI
771 (match_operand:SI 2 "s_register_operand" "r,r")
772 (match_operand:SI 1 "s_register_operand" "%?r,0"))
774 (clobber (match_scratch:SI 0 "=&r,&r"))]
776 "mul%?s\\t%0, %2, %1"
777 [(set_attr "conds" "set")
778 (set_attr "type" "mult")])
780 ;; Unnamed templates to match MLA instruction.
782 (define_insn "*mulsi3addsi"
783 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
785 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
786 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
787 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
789 "mla%?\\t%0, %2, %1, %3"
790 [(set_attr "type" "mult")])
792 (define_insn "*mulsi3addsi_compare0"
793 [(set (reg:CC_NOOV 24)
794 (compare:CC_NOOV (plus:SI
796 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
797 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
798 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
800 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
801 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
804 "mla%?s\\t%0, %2, %1, %3"
805 [(set_attr "conds" "set")
806 (set_attr "type" "mult")])
808 (define_insn "*mulsi3addsi_compare0_scratch"
809 [(set (reg:CC_NOOV 24)
810 (compare:CC_NOOV (plus:SI
812 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
813 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
814 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
816 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
818 "mla%?s\\t%0, %2, %1, %3"
819 [(set_attr "conds" "set")
820 (set_attr "type" "mult")])
822 (define_insn "mulsidi3"
823 [(set (match_operand:DI 0 "s_register_operand" "=&r")
824 (mult:DI (sign_extend:DI
825 (match_operand:SI 1 "s_register_operand" "%r"))
827 (match_operand:SI 2 "s_register_operand" "r"))))]
829 "smull%?\\t%Q0, %R0, %1, %2"
830 [(set_attr "type" "mult")])
832 (define_insn "umulsidi3"
833 [(set (match_operand:DI 0 "s_register_operand" "=&r")
834 (mult:DI (zero_extend:DI
835 (match_operand:SI 1 "s_register_operand" "%r"))
837 (match_operand:SI 2 "s_register_operand" "r"))))]
839 "umull%?\\t%Q0, %R0, %1, %2"
840 [(set_attr "type" "mult")])
842 (define_insn "mulsf3"
843 [(set (match_operand:SF 0 "s_register_operand" "=f")
844 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
845 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
847 "fml%?s\\t%0, %1, %2"
848 [(set_attr "type" "ffmul")])
850 (define_insn "muldf3"
851 [(set (match_operand:DF 0 "s_register_operand" "=f")
852 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
853 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
855 "muf%?d\\t%0, %1, %2"
856 [(set_attr "type" "fmul")])
858 (define_insn "*muldf_esfdf_df"
859 [(set (match_operand:DF 0 "s_register_operand" "=f")
860 (mult:DF (float_extend:DF
861 (match_operand:SF 1 "s_register_operand" "f"))
862 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
864 "muf%?d\\t%0, %1, %2"
865 [(set_attr "type" "fmul")])
867 (define_insn "*muldf_df_esfdf"
868 [(set (match_operand:DF 0 "s_register_operand" "=f")
869 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
871 (match_operand:SF 2 "s_register_operand" "f"))))]
873 "muf%?d\\t%0, %1, %2"
874 [(set_attr "type" "fmul")])
876 (define_insn "*muldf_esfdf_esfdf"
877 [(set (match_operand:DF 0 "s_register_operand" "=f")
878 (mult:DF (float_extend:DF
879 (match_operand:SF 1 "s_register_operand" "f"))
881 (match_operand:SF 2 "s_register_operand" "f"))))]
883 "muf%?d\\t%0, %1, %2"
884 [(set_attr "type" "fmul")])
886 (define_insn "mulxf3"
887 [(set (match_operand:XF 0 "s_register_operand" "=f")
888 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
889 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
890 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
891 "muf%?e\\t%0, %1, %2"
892 [(set_attr "type" "fmul")])
896 (define_insn "divsf3"
897 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
898 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
899 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
904 [(set_attr "type" "fdivs")])
906 (define_insn "divdf3"
907 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
908 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
909 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
914 [(set_attr "type" "fdivd")])
916 (define_insn "*divdf_esfdf_df"
917 [(set (match_operand:DF 0 "s_register_operand" "=f")
918 (div:DF (float_extend:DF
919 (match_operand:SF 1 "s_register_operand" "f"))
920 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
922 "dvf%?d\\t%0, %1, %2"
923 [(set_attr "type" "fdivd")])
925 (define_insn "*divdf_df_esfdf"
926 [(set (match_operand:DF 0 "s_register_operand" "=f")
927 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
929 (match_operand:SF 2 "s_register_operand" "f"))))]
931 "rdf%?d\\t%0, %2, %1"
932 [(set_attr "type" "fdivd")])
934 (define_insn "*divdf_esfdf_esfdf"
935 [(set (match_operand:DF 0 "s_register_operand" "=f")
936 (div:DF (float_extend:DF
937 (match_operand:SF 1 "s_register_operand" "f"))
939 (match_operand:SF 2 "s_register_operand" "f"))))]
941 "dvf%?d\\t%0, %1, %2"
942 [(set_attr "type" "fdivd")])
944 (define_insn "divxf3"
945 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
946 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
947 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
948 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
952 [(set_attr "type" "fdivx")])
956 (define_insn "modsf3"
957 [(set (match_operand:SF 0 "s_register_operand" "=f")
958 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
959 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
961 "rmf%?s\\t%0, %1, %2"
962 [(set_attr "type" "fdivs")])
964 (define_insn "moddf3"
965 [(set (match_operand:DF 0 "s_register_operand" "=f")
966 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
967 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
969 "rmf%?d\\t%0, %1, %2"
970 [(set_attr "type" "fdivd")])
972 (define_insn "*moddf_esfdf_df"
973 [(set (match_operand:DF 0 "s_register_operand" "=f")
974 (mod:DF (float_extend:DF
975 (match_operand:SF 1 "s_register_operand" "f"))
976 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
978 "rmf%?d\\t%0, %1, %2"
979 [(set_attr "type" "fdivd")])
981 (define_insn "*moddf_df_esfdf"
982 [(set (match_operand:DF 0 "s_register_operand" "=f")
983 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
985 (match_operand:SF 2 "s_register_operand" "f"))))]
987 "rmf%?d\\t%0, %1, %2"
988 [(set_attr "type" "fdivd")])
990 (define_insn "*moddf_esfdf_esfdf"
991 [(set (match_operand:DF 0 "s_register_operand" "=f")
992 (mod:DF (float_extend:DF
993 (match_operand:SF 1 "s_register_operand" "f"))
995 (match_operand:SF 2 "s_register_operand" "f"))))]
997 "rmf%?d\\t%0, %1, %2"
998 [(set_attr "type" "fdivd")])
1000 (define_insn "modxf3"
1001 [(set (match_operand:XF 0 "s_register_operand" "=f")
1002 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
1003 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
1004 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1005 "rmf%?e\\t%0, %1, %2"
1006 [(set_attr "type" "fdivx")])
1008 ;; Boolean and,ior,xor insns
1010 (define_insn "anddi3"
1011 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1012 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1013 (match_operand:DI 2 "s_register_operand" "r,0")))]
1015 "and%?\\t%Q0, %Q1, %Q2\;and%?\\t%R0, %R1, %R2"
1016 [(set_attr "length" "8")])
1018 (define_insn "*anddi_zesidi_di"
1019 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1020 (and:DI (zero_extend:DI
1021 (match_operand:SI 2 "s_register_operand" "r,r"))
1022 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1024 "and%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, #0"
1025 [(set_attr "length" "8")])
1027 (define_insn "*anddi_sesdi_di"
1028 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1029 (and:DI (sign_extend:DI
1030 (match_operand:SI 2 "s_register_operand" "r,r"))
1031 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1033 "and%?\\t%Q0, %Q1, %2\;and%?\\t%R0, %R1, %2, asr #31"
1034 [(set_attr "length" "8")])
1036 (define_expand "andsi3"
1037 [(set (match_operand:SI 0 "s_register_operand" "")
1038 (and:SI (match_operand:SI 1 "s_register_operand" "")
1039 (match_operand:SI 2 "reg_or_int_operand" "")))]
1042 if (GET_CODE (operands[2]) == CONST_INT)
1044 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1046 (reload_in_progress || reload_completed
1047 ? 0 : preserve_subexpressions_p ()));
1052 (define_insn "*andsi3_insn"
1053 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1054 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1055 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1059 bic%?\\t%0, %1, #%B2
1061 [(set_attr "length" "4,4,16")])
1064 [(set (match_operand:SI 0 "s_register_operand" "")
1065 (and:SI (match_operand:SI 1 "s_register_operand" "")
1066 (match_operand:SI 2 "const_int_operand" "")))]
1067 "! (const_ok_for_arm (INTVAL (operands[2]))
1068 || const_ok_for_arm (~ INTVAL (operands[2])))"
1069 [(clobber (const_int 0))]
1071 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1076 (define_insn "*andsi3_compare0"
1077 [(set (reg:CC_NOOV 24)
1079 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1080 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1082 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1083 (and:SI (match_dup 1) (match_dup 2)))]
1087 bic%?s\\t%0, %1, #%B2"
1088 [(set_attr "conds" "set")])
1090 (define_insn "*andsi3_compare0_scratch"
1091 [(set (reg:CC_NOOV 24)
1093 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1094 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1096 (clobber (match_scratch:SI 3 "=X,r"))]
1100 bic%?s\\t%3, %0, #%B1"
1101 [(set_attr "conds" "set")])
1103 (define_insn "*zeroextractsi_compare0_scratch"
1104 [(set (reg:CC_NOOV 24)
1105 (compare:CC_NOOV (zero_extract:SI
1106 (match_operand:SI 0 "s_register_operand" "r")
1107 (match_operand 1 "const_int_operand" "n")
1108 (match_operand 2 "const_int_operand" "n"))
1110 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1111 && INTVAL (operands[1]) > 0
1112 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1113 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
1116 unsigned int mask = 0;
1117 int cnt = INTVAL (operands[1]);
1120 mask = (mask << 1) | 1;
1121 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1122 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1126 [(set_attr "conds" "set")])
1128 (define_insn "*zeroextractqi_compare0_scratch"
1129 [(set (reg:CC_NOOV 24)
1130 (compare:CC_NOOV (zero_extract:SI
1131 (match_operand:QI 0 "memory_operand" "m")
1132 (match_operand 1 "const_int_operand" "n")
1133 (match_operand 2 "const_int_operand" "n"))
1135 (clobber (match_scratch:QI 3 "=r"))]
1136 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
1137 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
1140 unsigned int mask = 0;
1141 int cnt = INTVAL (operands[1]);
1144 mask = (mask << 1) | 1;
1145 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1146 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
1147 output_asm_insn (\"tst%?\\t%3, %1\", operands);
1151 [(set_attr "conds" "set")
1152 (set_attr "length" "8")])
1154 ;; constants for op 2 will never be given to these patterns.
1155 (define_insn "*anddi_notdi_di"
1156 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1157 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
1158 (match_operand:DI 1 "s_register_operand" "0,r")))]
1160 "bic%?\\t%Q0, %Q1, %Q2\;bic%?\\t%R0, %R1, %R2"
1161 [(set_attr "length" "8")])
1163 (define_insn "*anddi_notzesidi_di"
1164 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1165 (and:DI (not:DI (zero_extend:DI
1166 (match_operand:SI 2 "s_register_operand" "r,r")))
1167 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1170 bic%?\\t%Q0, %Q1, %2
1171 bic%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1172 [(set_attr "length" "4,8")])
1174 (define_insn "*anddi_notsesidi_di"
1175 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1176 (and:DI (not:DI (sign_extend:DI
1177 (match_operand:SI 2 "s_register_operand" "r,r")))
1178 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1180 "bic%?\\t%Q0, %Q1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
1181 [(set_attr "length" "8")])
1183 (define_insn "*andsi_notsi_si"
1184 [(set (match_operand:SI 0 "s_register_operand" "=r")
1185 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1186 (match_operand:SI 1 "s_register_operand" "r")))]
1188 "bic%?\\t%0, %1, %2")
1190 (define_insn "*andsi_notsi_si_compare0"
1191 [(set (reg:CC_NOOV 24)
1193 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1194 (match_operand:SI 1 "s_register_operand" "r"))
1196 (set (match_operand:SI 0 "s_register_operand" "=r")
1197 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1199 "bic%?s\\t%0, %1, %2"
1200 [(set_attr "conds" "set")])
1202 (define_insn "*andsi_notsi_si_compare0_scratch"
1203 [(set (reg:CC_NOOV 24)
1205 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1206 (match_operand:SI 1 "s_register_operand" "r"))
1208 (clobber (match_scratch:SI 0 "=r"))]
1210 "bic%?s\\t%0, %1, %2"
1211 [(set_attr "conds" "set")])
1213 (define_insn "iordi3"
1214 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1215 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1216 (match_operand:DI 2 "s_register_operand" "r")))]
1218 "orr%?\\t%Q0, %Q1, %Q2\;orr%?\\t%R0, %R1, %R2"
1219 [(set_attr "length" "8")])
1221 (define_insn "*iordi_zesidi_di"
1222 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1223 (ior:DI (zero_extend:DI
1224 (match_operand:SI 2 "s_register_operand" "r,r"))
1225 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1228 orr%?\\t%Q0, %Q1, %2
1229 orr%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1230 [(set_attr "length" "4,8")])
1232 (define_insn "*iordi_sesidi_di"
1233 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1234 (ior:DI (sign_extend:DI
1235 (match_operand:SI 2 "s_register_operand" "r,r"))
1236 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1238 "orr%?\\t%Q0, %Q1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1239 [(set_attr "length" "8")])
1241 (define_expand "iorsi3"
1242 [(set (match_operand:SI 0 "s_register_operand" "")
1243 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1244 (match_operand:SI 2 "reg_or_int_operand" "")))]
1247 if (GET_CODE (operands[2]) == CONST_INT)
1249 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1251 (reload_in_progress || reload_completed
1252 ? 0 : preserve_subexpressions_p ()));
1257 (define_insn "*iorsi3_insn"
1258 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1259 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1260 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
1265 [(set_attr "length" "4,16")])
1268 [(set (match_operand:SI 0 "s_register_operand" "")
1269 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1270 (match_operand:SI 2 "const_int_operand" "")))]
1271 "! const_ok_for_arm (INTVAL (operands[2]))"
1272 [(clobber (const_int 0))]
1274 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1279 (define_insn "*iorsi3_compare0"
1280 [(set (reg:CC_NOOV 24)
1281 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1282 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1284 (set (match_operand:SI 0 "s_register_operand" "=r")
1285 (ior:SI (match_dup 1) (match_dup 2)))]
1287 "orr%?s\\t%0, %1, %2"
1288 [(set_attr "conds" "set")])
1290 (define_insn "*iorsi3_compare0_scratch"
1291 [(set (reg:CC_NOOV 24)
1292 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1293 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1295 (clobber (match_scratch:SI 0 "=r"))]
1297 "orr%?s\\t%0, %1, %2"
1298 [(set_attr "conds" "set")])
1300 (define_insn "xordi3"
1301 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1302 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1303 (match_operand:DI 2 "s_register_operand" "r,0")))]
1305 "eor%?\\t%Q0, %Q1, %Q2\;eor%?\\t%R0, %R1, %R2"
1306 [(set_attr "length" "8")])
1308 (define_insn "*xordi_zesidi_di"
1309 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1310 (xor:DI (zero_extend:DI
1311 (match_operand:SI 2 "s_register_operand" "r,r"))
1312 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1315 eor%?\\t%Q0, %Q1, %2
1316 eor%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1317 [(set_attr "length" "4,8")])
1319 (define_insn "*xordi_sesidi_di"
1320 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1321 (xor:DI (sign_extend:DI
1322 (match_operand:SI 2 "s_register_operand" "r,r"))
1323 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1325 "eor%?\\t%Q0, %Q1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1326 [(set_attr "length" "8")])
1328 (define_insn "xorsi3"
1329 [(set (match_operand:SI 0 "s_register_operand" "=r")
1330 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1331 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1333 "eor%?\\t%0, %1, %2")
1335 (define_insn "*xorsi3_compare0"
1336 [(set (reg:CC_NOOV 24)
1337 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1338 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1340 (set (match_operand:SI 0 "s_register_operand" "=r")
1341 (xor:SI (match_dup 1) (match_dup 2)))]
1343 "eor%?s\\t%0, %1, %2"
1344 [(set_attr "conds" "set")])
1346 (define_insn "*xorsi3_compare0_scratch"
1347 [(set (reg:CC_NOOV 24)
1348 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1349 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1353 [(set_attr "conds" "set")])
1355 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1356 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1360 [(set (match_operand:SI 0 "s_register_operand" "=r")
1361 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1362 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1363 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1364 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1366 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1367 (not:SI (match_dup 3))))
1368 (set (match_dup 0) (not:SI (match_dup 4)))]
1372 (define_insn "*andsi_iorsi3_notsi"
1373 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1374 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1375 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1376 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1378 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1379 [(set_attr "length" "8")])
1383 ;; Minimum and maximum insns
1385 (define_insn "smaxsi3"
1386 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1387 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1388 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1389 (clobber (reg:CC 24))]
1392 cmp\\t%1, %2\;movlt\\t%0, %2
1393 cmp\\t%1, %2\;movge\\t%0, %1
1394 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1395 [(set_attr "conds" "clob")
1396 (set_attr "length" "8,8,12")])
1398 (define_insn "sminsi3"
1399 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1400 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1401 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1402 (clobber (reg:CC 24))]
1405 cmp\\t%1, %2\;movge\\t%0, %2
1406 cmp\\t%1, %2\;movlt\\t%0, %1
1407 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1408 [(set_attr "conds" "clob")
1409 (set_attr "length" "8,8,12")])
1411 (define_insn "umaxsi3"
1412 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1413 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1414 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1415 (clobber (reg:CC 24))]
1418 cmp\\t%1, %2\;movcc\\t%0, %2
1419 cmp\\t%1, %2\;movcs\\t%0, %1
1420 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1421 [(set_attr "conds" "clob")
1422 (set_attr "length" "8,8,12")])
1424 (define_insn "uminsi3"
1425 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1426 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1427 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1428 (clobber (reg:CC 24))]
1431 cmp\\t%1, %2\;movcs\\t%0, %2
1432 cmp\\t%1, %2\;movcc\\t%0, %1
1433 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1434 [(set_attr "conds" "clob")
1435 (set_attr "length" "8,8,12")])
1437 (define_insn "*store_minmansi"
1438 [(set (match_operand:SI 0 "memory_operand" "=m")
1439 (match_operator:SI 3 "minmax_operator"
1440 [(match_operand:SI 1 "s_register_operand" "r")
1441 (match_operand:SI 2 "s_register_operand" "r")]))
1442 (clobber (reg:CC 24))]
1445 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1447 output_asm_insn (\"cmp\\t%1, %2\", operands);
1448 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1449 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1452 [(set_attr "conds" "clob")
1453 (set_attr "length" "12")
1454 (set_attr "type" "store1")])
1456 (define_insn "*minmax_arithsi"
1457 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1458 (match_operator:SI 4 "shiftable_operator"
1459 [(match_operator:SI 5 "minmax_operator"
1460 [(match_operand:SI 2 "s_register_operand" "r,r")
1461 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1462 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1463 (clobber (reg:CC 24))]
1467 enum rtx_code code = GET_CODE (operands[4]);
1469 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1471 output_asm_insn (\"cmp\\t%2, %3\", operands);
1472 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1473 if (which_alternative != 0 || operands[3] != const0_rtx
1474 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1475 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1479 [(set_attr "conds" "clob")
1480 (set_attr "length" "12")])
1483 ;; Shift and rotation insns
1485 (define_expand "ashlsi3"
1486 [(set (match_operand:SI 0 "s_register_operand" "")
1487 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1488 (match_operand:SI 2 "arm_rhs_operand" "")))]
1491 if (GET_CODE (operands[2]) == CONST_INT
1492 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1494 emit_insn (gen_movsi (operands[0], const0_rtx));
1499 (define_expand "ashrsi3"
1500 [(set (match_operand:SI 0 "s_register_operand" "")
1501 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1502 (match_operand:SI 2 "arm_rhs_operand" "")))]
1505 if (GET_CODE (operands[2]) == CONST_INT
1506 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1507 operands[2] = GEN_INT (31);
1510 (define_expand "lshrsi3"
1511 [(set (match_operand:SI 0 "s_register_operand" "")
1512 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1513 (match_operand:SI 2 "arm_rhs_operand" "")))]
1516 if (GET_CODE (operands[2]) == CONST_INT
1517 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1519 emit_insn (gen_movsi (operands[0], const0_rtx));
1524 (define_expand "rotlsi3"
1525 [(set (match_operand:SI 0 "s_register_operand" "")
1526 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1527 (match_operand:SI 2 "reg_or_int_operand" "")))]
1530 if (GET_CODE (operands[2]) == CONST_INT)
1531 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1534 rtx reg = gen_reg_rtx (SImode);
1535 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1540 (define_expand "rotrsi3"
1541 [(set (match_operand:SI 0 "s_register_operand" "")
1542 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1543 (match_operand:SI 2 "arm_rhs_operand" "")))]
1546 if (GET_CODE (operands[2]) == CONST_INT
1547 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1548 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1551 (define_insn "*shiftsi3"
1552 [(set (match_operand:SI 0 "s_register_operand" "=r")
1553 (match_operator:SI 3 "shift_operator"
1554 [(match_operand:SI 1 "s_register_operand" "r")
1555 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1557 "mov%?\\t%0, %1%S3")
1559 (define_insn "*shiftsi3_compare0"
1560 [(set (reg:CC_NOOV 24)
1561 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1562 [(match_operand:SI 1 "s_register_operand" "r")
1563 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1565 (set (match_operand:SI 0 "s_register_operand" "=r")
1566 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1568 "mov%?s\\t%0, %1%S3"
1569 [(set_attr "conds" "set")])
1571 (define_insn "*shiftsi3_compare0_scratch"
1572 [(set (reg:CC_NOOV 24)
1573 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1574 [(match_operand:SI 1 "s_register_operand" "r")
1575 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1577 (clobber (match_scratch:SI 0 "=r"))]
1579 "mov%?s\\t%0, %1%S3"
1580 [(set_attr "conds" "set")])
1582 (define_insn "*notsi_shiftsi"
1583 [(set (match_operand:SI 0 "s_register_operand" "=r")
1584 (not:SI (match_operator:SI 3 "shift_operator"
1585 [(match_operand:SI 1 "s_register_operand" "r")
1586 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
1588 "mvn%?\\t%0, %1%S3")
1590 (define_insn "*notsi_shiftsi_compare0"
1591 [(set (reg:CC_NOOV 24)
1592 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1593 [(match_operand:SI 1 "s_register_operand" "r")
1594 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1596 (set (match_operand:SI 0 "s_register_operand" "=r")
1597 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1599 "mvn%?s\\t%0, %1%S3"
1600 [(set_attr "conds" "set")])
1602 (define_insn "*not_shiftsi_compare0_scratch"
1603 [(set (reg:CC_NOOV 24)
1604 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1605 [(match_operand:SI 1 "s_register_operand" "r")
1606 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1608 (clobber (match_scratch:SI 0 "=r"))]
1610 "mvn%?s\\t%0, %1%S3"
1611 [(set_attr "conds" "set")])
1614 ;; Unary arithmetic insns
1616 (define_insn "negdi2"
1617 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1618 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1620 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
1621 [(set_attr "conds" "clob")
1622 (set_attr "length" "8")])
1624 (define_insn "negsi2"
1625 [(set (match_operand:SI 0 "s_register_operand" "=r")
1626 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1628 "rsb%?\\t%0, %1, #0")
1630 (define_insn "negsf2"
1631 [(set (match_operand:SF 0 "s_register_operand" "=f")
1632 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1635 [(set_attr "type" "ffarith")])
1637 (define_insn "negdf2"
1638 [(set (match_operand:DF 0 "s_register_operand" "=f")
1639 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1642 [(set_attr "type" "ffarith")])
1644 (define_insn "*negdf_esfdf"
1645 [(set (match_operand:DF 0 "s_register_operand" "=f")
1646 (neg:DF (float_extend:DF
1647 (match_operand:SF 1 "s_register_operand" "f"))))]
1650 [(set_attr "type" "ffarith")])
1652 (define_insn "negxf2"
1653 [(set (match_operand:XF 0 "s_register_operand" "=f")
1654 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1655 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1657 [(set_attr "type" "ffarith")])
1659 ;; abssi2 doesn't really clobber the condition codes if a different register
1660 ;; is being set. To keep things simple, assume during rtl manipulations that
1661 ;; it does, but tell the final scan operator the truth. Similarly for
1664 (define_insn "abssi2"
1665 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1666 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1670 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1671 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1672 [(set_attr "conds" "clob,*")
1673 (set_attr "length" "8")])
1675 (define_insn "*neg_abssi2"
1676 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1677 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1681 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1682 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1683 [(set_attr "conds" "clob,*")
1684 (set_attr "length" "8")])
1686 (define_insn "abssf2"
1687 [(set (match_operand:SF 0 "s_register_operand" "=f")
1688 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1691 [(set_attr "type" "ffarith")])
1693 (define_insn "absdf2"
1694 [(set (match_operand:DF 0 "s_register_operand" "=f")
1695 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1698 [(set_attr "type" "ffarith")])
1700 (define_insn "*absdf_esfdf"
1701 [(set (match_operand:DF 0 "s_register_operand" "=f")
1702 (abs:DF (float_extend:DF
1703 (match_operand:SF 1 "s_register_operand" "f"))))]
1706 [(set_attr "type" "ffarith")])
1708 (define_insn "absxf2"
1709 [(set (match_operand:XF 0 "s_register_operand" "=f")
1710 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1711 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1713 [(set_attr "type" "ffarith")])
1715 (define_insn "sqrtsf2"
1716 [(set (match_operand:SF 0 "s_register_operand" "=f")
1717 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1720 [(set_attr "type" "float_em")])
1722 (define_insn "sqrtdf2"
1723 [(set (match_operand:DF 0 "s_register_operand" "=f")
1724 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1727 [(set_attr "type" "float_em")])
1729 (define_insn "*sqrtdf_esfdf"
1730 [(set (match_operand:DF 0 "s_register_operand" "=f")
1731 (sqrt:DF (float_extend:DF
1732 (match_operand:SF 1 "s_register_operand" "f"))))]
1735 [(set_attr "type" "float_em")])
1737 (define_insn "sqrtxf2"
1738 [(set (match_operand:XF 0 "s_register_operand" "=f")
1739 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1740 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1742 [(set_attr "type" "float_em")])
1744 (define_insn "sinsf2"
1745 [(set (match_operand:SF 0 "s_register_operand" "=f")
1746 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1749 [(set_attr "type" "float_em")])
1751 (define_insn "sindf2"
1752 [(set (match_operand:DF 0 "s_register_operand" "=f")
1753 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1756 [(set_attr "type" "float_em")])
1758 (define_insn "*sindf_esfdf"
1759 [(set (match_operand:DF 0 "s_register_operand" "=f")
1760 (unspec:DF [(float_extend:DF
1761 (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1764 [(set_attr "type" "float_em")])
1766 (define_insn "sinxf2"
1767 [(set (match_operand:XF 0 "s_register_operand" "=f")
1768 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1769 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1771 [(set_attr "type" "float_em")])
1773 (define_insn "cossf2"
1774 [(set (match_operand:SF 0 "s_register_operand" "=f")
1775 (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1778 [(set_attr "type" "float_em")])
1780 (define_insn "cosdf2"
1781 [(set (match_operand:DF 0 "s_register_operand" "=f")
1782 (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1785 [(set_attr "type" "float_em")])
1787 (define_insn "*cosdf_esfdf"
1788 [(set (match_operand:DF 0 "s_register_operand" "=f")
1789 (unspec:DF [(float_extend:DF
1790 (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1793 [(set_attr "type" "float_em")])
1795 (define_insn "cosxf2"
1796 [(set (match_operand:XF 0 "s_register_operand" "=f")
1797 (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1798 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1800 [(set_attr "type" "float_em")])
1802 (define_insn "one_cmpldi2"
1803 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1804 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1806 "mvn%?\\t%Q0, %Q1\;mvn%?\\t%R0, %R1"
1807 [(set_attr "length" "8")])
1809 (define_insn "one_cmplsi2"
1810 [(set (match_operand:SI 0 "s_register_operand" "=r")
1811 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1815 (define_insn "*notsi_compare0"
1816 [(set (reg:CC_NOOV 24)
1817 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1819 (set (match_operand:SI 0 "s_register_operand" "=r")
1820 (not:SI (match_dup 1)))]
1823 [(set_attr "conds" "set")])
1825 (define_insn "*notsi_compare0_scratch"
1826 [(set (reg:CC_NOOV 24)
1827 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1829 (clobber (match_scratch:SI 0 "=r"))]
1832 [(set_attr "conds" "set")])
1834 ;; Fixed <--> Floating conversion insns
1836 (define_insn "floatsisf2"
1837 [(set (match_operand:SF 0 "s_register_operand" "=f")
1838 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1841 [(set_attr "type" "r_2_f")])
1843 (define_insn "floatsidf2"
1844 [(set (match_operand:DF 0 "s_register_operand" "=f")
1845 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1848 [(set_attr "type" "r_2_f")])
1850 (define_insn "floatsixf2"
1851 [(set (match_operand:XF 0 "s_register_operand" "=f")
1852 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1853 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1855 [(set_attr "type" "r_2_f")])
1857 (define_insn "fix_truncsfsi2"
1858 [(set (match_operand:SI 0 "s_register_operand" "=r")
1859 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
1862 [(set_attr "type" "f_2_r")])
1864 (define_insn "fix_truncdfsi2"
1865 [(set (match_operand:SI 0 "s_register_operand" "=r")
1866 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
1869 [(set_attr "type" "f_2_r")])
1871 (define_insn "fix_truncxfsi2"
1872 [(set (match_operand:SI 0 "s_register_operand" "=r")
1873 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
1874 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1876 [(set_attr "type" "f_2_r")])
1880 (define_insn "truncdfsf2"
1881 [(set (match_operand:SF 0 "s_register_operand" "=f")
1883 (match_operand:DF 1 "s_register_operand" "f")))]
1886 [(set_attr "type" "ffarith")])
1888 (define_insn "truncxfsf2"
1889 [(set (match_operand:SF 0 "s_register_operand" "=f")
1891 (match_operand:XF 1 "s_register_operand" "f")))]
1892 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1894 [(set_attr "type" "ffarith")])
1896 (define_insn "truncxfdf2"
1897 [(set (match_operand:DF 0 "s_register_operand" "=f")
1899 (match_operand:XF 1 "s_register_operand" "f")))]
1900 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1902 [(set_attr "type" "ffarith")])
1904 ;; Zero and sign extension instructions.
1906 (define_insn "zero_extendsidi2"
1907 [(set (match_operand:DI 0 "s_register_operand" "=r")
1908 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1911 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
1912 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
1913 return \"mov%?\\t%R0, #0\";
1915 [(set_attr "length" "8")])
1917 (define_insn "zero_extendqidi2"
1918 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
1919 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1922 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
1923 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
1924 [(set_attr "length" "8")
1925 (set_attr "type" "*,load")])
1927 (define_insn "extendsidi2"
1928 [(set (match_operand:DI 0 "s_register_operand" "=r")
1929 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
1932 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
1933 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
1934 return \"mov%?\\t%R0, %Q0, asr #31\";
1936 [(set_attr "length" "8")])
1938 (define_expand "zero_extendhisi2"
1939 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
1941 (set (match_operand:SI 0 "s_register_operand" "")
1942 (lshiftrt:SI (match_dup 2) (const_int 16)))]
1946 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
1948 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1949 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
1952 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
1954 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
1957 if (! s_register_operand (operands[1], HImode))
1958 operands[1] = copy_to_mode_reg (HImode, operands[1]);
1959 operands[1] = gen_lowpart (SImode, operands[1]);
1960 operands[2] = gen_reg_rtx (SImode);
1963 (define_insn "*zero_extendhisi_insn"
1964 [(set (match_operand:SI 0 "s_register_operand" "=r")
1965 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1968 [(set_attr "type" "load")])
1971 [(set (match_operand:SI 0 "s_register_operand" "")
1972 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
1973 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1975 [(set (match_dup 2) (match_dup 1))
1976 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
1979 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
1984 [(set (match_operand:SI 0 "s_register_operand" "")
1985 (match_operator:SI 3 "shiftable_operator"
1986 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
1987 (match_operand:SI 4 "s_register_operand" "")]))
1988 (clobber (match_operand:SI 2 "s_register_operand" ""))]
1990 [(set (match_dup 2) (match_dup 1))
1993 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
1996 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2000 (define_expand "zero_extendqisi2"
2001 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2003 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2006 if (GET_CODE (operands[1]) != MEM)
2008 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
2014 (define_insn "*load_extendqisi"
2015 [(set (match_operand:SI 0 "s_register_operand" "=r")
2016 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2018 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
2019 [(set_attr "type" "load")])
2022 [(set (match_operand:SI 0 "s_register_operand" "")
2023 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
2024 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2025 "GET_CODE (operands[1]) != MEM"
2026 [(set (match_dup 2) (match_dup 1))
2027 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
2030 (define_insn "*compareqi_eq0"
2032 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
2036 [(set_attr "conds" "set")])
2038 (define_expand "extendhisi2"
2040 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2042 (set (match_operand:SI 0 "s_register_operand" "")
2043 (ashiftrt:SI (match_dup 2)
2048 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2050 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2051 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2055 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2057 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
2060 if (! s_register_operand (operands[1], HImode))
2061 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2062 operands[1] = gen_lowpart (SImode, operands[1]);
2063 operands[2] = gen_reg_rtx (SImode);
2066 (define_expand "extendhisi2_mem"
2067 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2069 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2070 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
2071 (set (match_operand:SI 0 "" "")
2072 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
2075 operands[0] = gen_lowpart (SImode, operands[0]);
2076 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2077 operands[2] = gen_reg_rtx (SImode);
2078 operands[3] = gen_reg_rtx (SImode);
2079 operands[6] = gen_reg_rtx (SImode);
2081 if (BYTES_BIG_ENDIAN)
2083 operands[4] = operands[2];
2084 operands[5] = operands[3];
2088 operands[4] = operands[3];
2089 operands[5] = operands[2];
2093 (define_insn "*extendhisi_insn"
2094 [(set (match_operand:SI 0 "s_register_operand" "=r")
2095 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2098 [(set_attr "type" "load")])
2101 [(set (match_operand:SI 0 "s_register_operand" "")
2102 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2103 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2105 [(set (match_dup 2) (match_dup 1))
2106 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
2109 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2114 [(set (match_operand:SI 0 "s_register_operand" "")
2115 (match_operator:SI 3 "shiftable_operator"
2116 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2117 (match_operand:SI 4 "s_register_operand" "")]))
2118 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2120 [(set (match_dup 2) (match_dup 1))
2123 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2126 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2130 (define_expand "extendqihi2"
2132 (ashift:SI (match_operand:QI 1 "general_operand" "")
2134 (set (match_operand:HI 0 "s_register_operand" "")
2135 (ashiftrt:SI (match_dup 2)
2140 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2142 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2143 gen_rtx (SIGN_EXTEND, HImode, operands[1])));
2146 if (! s_register_operand (operands[1], QImode))
2147 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2148 operands[0] = gen_lowpart (SImode, operands[0]);
2149 operands[1] = gen_lowpart (SImode, operands[1]);
2150 operands[2] = gen_reg_rtx (SImode);
2153 (define_insn "*extendqihi_insn"
2154 [(set (match_operand:HI 0 "s_register_operand" "=r")
2155 (sign_extend:HI (match_operand:QI 1 "memory_operand" "o<>")))]
2158 [(set_attr "type" "load")])
2160 (define_expand "extendqisi2"
2162 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
2164 (set (match_operand:SI 0 "s_register_operand" "")
2165 (ashiftrt:SI (match_dup 2)
2170 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2172 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2173 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2176 if (! s_register_operand (operands[1], QImode))
2177 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2178 operands[1] = gen_lowpart (SImode, operands[1]);
2179 operands[2] = gen_reg_rtx (SImode);
2182 (define_insn "*extendqisi_insn"
2183 [(set (match_operand:SI 0 "s_register_operand" "=r")
2184 (sign_extend:SI (match_operand:QI 1 "memory_operand" "o<>")))]
2187 [(set_attr "type" "load")])
2189 (define_insn "extendsfdf2"
2190 [(set (match_operand:DF 0 "s_register_operand" "=f")
2191 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
2194 [(set_attr "type" "ffarith")])
2196 (define_insn "extendsfxf2"
2197 [(set (match_operand:XF 0 "s_register_operand" "=f")
2198 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
2199 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2201 [(set_attr "type" "ffarith")])
2203 (define_insn "extenddfxf2"
2204 [(set (match_operand:XF 0 "s_register_operand" "=f")
2205 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
2206 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2208 [(set_attr "type" "ffarith")])
2211 ;; Move insns (including loads and stores)
2213 ;; XXX Just some ideas about movti.
2214 ;; I don't think these are a good idea on the arm, there just aren't enough
2216 ;;(define_expand "loadti"
2217 ;; [(set (match_operand:TI 0 "s_register_operand" "")
2218 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
2221 ;;(define_expand "storeti"
2222 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
2223 ;; (match_operand:TI 1 "s_register_operand" ""))]
2226 ;;(define_expand "movti"
2227 ;; [(set (match_operand:TI 0 "general_operand" "")
2228 ;; (match_operand:TI 1 "general_operand" ""))]
2234 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2235 ;; operands[1] = copy_to_reg (operands[1]);
2236 ;; if (GET_CODE (operands[0]) == MEM)
2237 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
2238 ;; else if (GET_CODE (operands[1]) == MEM)
2239 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
2243 ;; emit_insn (insn);
2247 ;; Recognise garbage generated above.
2250 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
2251 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
2255 ;; register mem = (which_alternative < 3);
2256 ;; register char *template;
2258 ;; operands[mem] = XEXP (operands[mem], 0);
2259 ;; switch (which_alternative)
2261 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
2262 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
2263 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
2264 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
2265 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
2266 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
2268 ;; output_asm_insn (template, operands);
2273 (define_insn "movdi"
2274 [(set (match_operand:DI 0 "di_operand" "=r,r,o<>")
2275 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
2278 return (output_move_double (operands));
2280 [(set_attr "length" "8,8,8")
2281 (set_attr "type" "*,load,store2")])
2283 (define_expand "movsi"
2284 [(set (match_operand:SI 0 "general_operand" "")
2285 (match_operand:SI 1 "general_operand" ""))]
2288 /* Everything except mem = const or mem = mem can be done easily */
2289 if (GET_CODE (operands[0]) == MEM)
2290 operands[1] = force_reg (SImode, operands[1]);
2291 if (GET_CODE (operands[1]) == CONST_INT
2292 && !(const_ok_for_arm (INTVAL (operands[1]))
2293 || const_ok_for_arm (~INTVAL (operands[1]))))
2295 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2297 (reload_in_progress || reload_completed ? 0
2298 : preserve_subexpressions_p ()));
2303 (define_insn "*movsi_insn"
2304 [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
2305 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
2306 "register_operand (operands[0], SImode)
2307 || register_operand (operands[1], SImode)"
2313 [(set_attr "type" "*,*,load,store1")])
2316 [(set (match_operand:SI 0 "s_register_operand" "")
2317 (match_operand:SI 1 "const_int_operand" ""))]
2318 "! (const_ok_for_arm (INTVAL (operands[1]))
2319 || const_ok_for_arm (~INTVAL (operands[1])))"
2320 [(clobber (const_int 0))]
2322 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2327 (define_expand "movaddr"
2328 [(set (match_operand:SI 0 "s_register_operand" "")
2329 (match_operand:DI 1 "address_operand" ""))]
2333 (define_insn "*movaddr_insn"
2334 [(set (match_operand:SI 0 "s_register_operand" "=r")
2335 (match_operand:DI 1 "address_operand" "p"))]
2337 && (GET_CODE (operands[1]) == LABEL_REF
2338 || (GET_CODE (operands[1]) == CONST
2339 && GET_CODE (XEXP (operands[1], 0)) == PLUS
2340 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2341 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
2344 ;; If copying one reg to another we can set the condition codes according to
2345 ;; its value. Such a move is common after a return from subroutine and the
2346 ;; result is being tested against zero.
2348 (define_insn "*movsi_compare0"
2349 [(set (reg:CC 24) (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
2351 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2355 sub%?s\\t%0, %1, #0"
2356 [(set_attr "conds" "set")])
2358 ;; Subroutine to store a half word from a register into memory.
2359 ;; Operand 0 is the source register (HImode)
2360 ;; Operand 1 is the destination address in a register (SImode)
2362 ;; In both this routine and the next, we must be careful not to spill
2363 ;; a memory address of reg+large_const into a separate PLUS insn, since this
2364 ;; can generate unrecognizable rtl.
2366 (define_expand "storehi"
2367 [;; store the low byte
2368 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2369 ;; extract the high byte
2371 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2372 ;; store the high byte
2373 (set (mem:QI (match_dup 4))
2374 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2378 enum rtx_code code = GET_CODE (operands[1]);
2380 if ((code == PLUS || code == MINUS)
2381 && (GET_CODE (XEXP (operands[1], 1)) == REG
2382 || GET_CODE (XEXP (operands[1], 0)) != REG))
2383 operands[1] = force_reg (SImode, operands[1]);
2384 operands[4] = plus_constant (operands[1], 1);
2385 operands[3] = gen_lowpart (QImode, operands[0]);
2386 operands[0] = gen_lowpart (SImode, operands[0]);
2387 operands[2] = gen_reg_rtx (SImode);
2391 (define_expand "storehi_bigend"
2392 [(set (mem:QI (match_dup 4)) (match_dup 3))
2394 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2395 (set (mem:QI (match_operand 1 "" ""))
2396 (subreg:QI (match_dup 2) 0))]
2400 enum rtx_code code = GET_CODE (operands[1]);
2401 if ((code == PLUS || code == MINUS)
2402 && (GET_CODE (XEXP (operands[1], 1)) == REG
2403 || GET_CODE (XEXP (operands[1], 0)) != REG))
2404 operands[1] = force_reg (SImode, operands[1]);
2406 operands[4] = plus_constant (operands[1], 1);
2407 operands[3] = gen_lowpart (QImode, operands[0]);
2408 operands[0] = gen_lowpart (SImode, operands[0]);
2409 operands[2] = gen_reg_rtx (SImode);
2413 ;; Subroutine to store a half word integer constant into memory.
2414 (define_expand "storeinthi"
2415 [(set (mem:QI (match_operand:SI 0 "" ""))
2416 (subreg:QI (match_operand 1 "" "") 0))
2417 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2421 HOST_WIDE_INT value = INTVAL (operands[1]);
2422 enum rtx_code code = GET_CODE (operands[0]);
2424 if ((code == PLUS || code == MINUS)
2425 && (GET_CODE (XEXP (operands[0], 1)) == REG
2426 || GET_CODE (XEXP (operands[0], 0)) != REG))
2427 operands[0] = force_reg (SImode, operands[0]);
2429 operands[1] = gen_reg_rtx (SImode);
2430 if (BYTES_BIG_ENDIAN)
2432 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2433 if ((value & 255) == ((value >> 8) & 255))
2434 operands[2] = operands[1];
2437 operands[2] = gen_reg_rtx (SImode);
2438 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2443 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2444 if ((value & 255) == ((value >> 8) & 255))
2445 operands[2] = operands[1];
2448 operands[2] = gen_reg_rtx (SImode);
2449 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2453 operands[3] = plus_constant (operands[0], 1);
2457 (define_expand "storehi_single_op"
2458 [(set (match_operand:HI 0 "memory_operand" "")
2459 (match_operand:HI 1 "general_operand" ""))]
2462 if (! s_register_operand (operands[1], HImode))
2463 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2466 (define_expand "movhi"
2467 [(set (match_operand:HI 0 "general_operand" "")
2468 (match_operand:HI 1 "general_operand" ""))]
2474 if (! (reload_in_progress || reload_completed))
2476 if (GET_CODE (operands[0]) == MEM)
2480 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
2483 if (GET_CODE (operands[1]) == CONST_INT)
2484 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
2487 if (GET_CODE (operands[1]) == MEM)
2488 operands[1] = force_reg (HImode, operands[1]);
2489 if (BYTES_BIG_ENDIAN)
2490 emit_insn (gen_storehi_bigend (operands[1],
2491 XEXP (operands[0], 0)));
2493 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
2497 /* Sign extend a constant, and keep it in an SImode reg. */
2498 else if (GET_CODE (operands[1]) == CONST_INT)
2500 rtx reg = gen_reg_rtx (SImode);
2501 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2503 /* If the constant is already valid, leave it alone. */
2504 if (! const_ok_for_arm (val))
2506 /* If setting all the top bits will make the constant
2507 loadable in a single instruction, then set them.
2508 Otherwise, sign extend the number. */
2510 if (const_ok_for_arm (~ (val | ~0xffff)))
2512 else if (val & 0x8000)
2516 emit_insn (gen_movsi (reg, GEN_INT (val)));
2517 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2519 else if (! arm_arch4)
2521 if (GET_CODE (operands[1]) == MEM)
2523 if (TARGET_SHORT_BY_BYTES)
2526 rtx offset = const0_rtx;
2527 rtx reg = gen_reg_rtx (SImode);
2529 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2530 || (GET_CODE (base) == PLUS
2531 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2532 && GET_CODE (base = XEXP (base, 0)) == REG))
2533 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2535 HOST_WIDE_INT new_offset = INTVAL (offset) & ~2;
2537 emit_insn (gen_movsi (reg, gen_rtx (MEM, SImode,
2538 plus_constant (base, new_offset))));
2539 if (((INTVAL (offset) & 2) != 0)
2540 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
2542 rtx reg2 = gen_reg_rtx (SImode);
2544 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
2549 emit_insn (gen_movhi_bytes (reg, operands[1]));
2551 operands[1] = gen_lowpart (HImode, reg);
2553 else if (BYTES_BIG_ENDIAN)
2556 rtx offset = const0_rtx;
2558 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2559 || (GET_CODE (base) == PLUS
2560 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2561 && GET_CODE (base = XEXP (base, 0)) == REG))
2562 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2564 rtx reg = gen_reg_rtx (SImode);
2567 if ((INTVAL (offset) & 2) == 2)
2569 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
2570 new_mem = gen_rtx (MEM, SImode,
2571 plus_constant (base, new_offset));
2573 emit_insn (gen_movsi (reg, new_mem));
2577 new_mem = gen_rtx (MEM, SImode,
2578 XEXP (operands[1], 0));
2579 emit_insn (gen_rotated_loadsi (reg, new_mem));
2582 operands[1] = gen_lowpart (HImode, reg);
2586 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2593 /* Handle loading a large integer during reload */
2594 else if (GET_CODE (operands[1]) == CONST_INT
2595 && ! const_ok_for_arm (INTVAL (operands[1]))
2596 && ! const_ok_for_arm (~INTVAL (operands[1])))
2598 /* Writing a constant to memory needs a scratch, which should
2599 be handled with SECONDARY_RELOADs. */
2600 if (GET_CODE (operands[0]) != REG)
2603 operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0);
2604 emit_insn (gen_movsi (operands[0], operands[1]));
2610 (define_insn "rotated_loadsi"
2611 [(set (match_operand:SI 0 "s_register_operand" "=r")
2612 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
2614 "! TARGET_SHORT_BY_BYTES"
2619 ops[0] = operands[0];
2620 ops[1] = gen_rtx (MEM, SImode, plus_constant (XEXP (operands[1], 0), 2));
2621 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
2624 [(set_attr "type" "load")])
2626 (define_expand "movhi_bytes"
2627 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2629 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2630 (set (match_operand:SI 0 "" "")
2631 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
2634 operands[0] = gen_lowpart (SImode, operands[0]);
2635 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2636 operands[2] = gen_reg_rtx (SImode);
2637 operands[3] = gen_reg_rtx (SImode);
2639 if (BYTES_BIG_ENDIAN)
2641 operands[4] = operands[2];
2642 operands[5] = operands[3];
2646 operands[4] = operands[3];
2647 operands[5] = operands[2];
2651 (define_expand "movhi_bigend"
2653 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2656 (ashiftrt:SI (match_dup 2) (const_int 16)))
2657 (set (match_operand:HI 0 "s_register_operand" "")
2658 (subreg:HI (match_dup 3) 0))]
2661 operands[2] = gen_reg_rtx (SImode);
2662 operands[3] = gen_reg_rtx (SImode);
2665 ;; Pattern to recognise insn generated default case above
2667 (define_insn "*movhi_insn_arch4"
2668 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2669 (match_operand:HI 1 "general_operand" "rI,K,m,r"))]
2671 && (GET_CODE (operands[1]) != CONST_INT
2672 || const_ok_for_arm (INTVAL (operands[1]))
2673 || const_ok_for_arm (~INTVAL (operands[1])))"
2675 mov%?\\t%0, %1\\t%@ movhi
2676 mvn%?\\t%0, #%B1\\t%@ movhi
2677 ldr%?h\\t%0, %1\\t%@ movhi
2678 str%?h\\t%1, %0\\t%@ movhi"
2679 [(set_attr "type" "*,*,load,store1")])
2681 (define_insn "*movhi_insn_littleend"
2682 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2683 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2685 && ! BYTES_BIG_ENDIAN
2686 && ! TARGET_SHORT_BY_BYTES
2687 && (GET_CODE (operands[1]) != CONST_INT
2688 || const_ok_for_arm (INTVAL (operands[1]))
2689 || const_ok_for_arm (~INTVAL (operands[1])))"
2691 mov%?\\t%0, %1\\t%@ movhi
2692 mvn%?\\t%0, #%B1\\t%@ movhi
2693 ldr%?\\t%0, %1\\t%@ movhi"
2694 [(set_attr "type" "*,*,load")])
2696 (define_insn "*movhi_insn_bigend"
2697 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2698 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2701 && ! TARGET_SHORT_BY_BYTES
2702 && (GET_CODE (operands[1]) != CONST_INT
2703 || const_ok_for_arm (INTVAL (operands[1]))
2704 || const_ok_for_arm (~INTVAL (operands[1])))"
2706 mov%?\\t%0, %1\\t%@ movhi
2707 mvn%?\\t%0, #%B1\\t%@ movhi
2708 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2709 [(set_attr "type" "*,*,load")
2710 (set_attr "length" "4,4,8")])
2712 (define_insn "*loadhi_si_bigend"
2713 [(set (match_operand:SI 0 "s_register_operand" "=r")
2714 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2717 && ! TARGET_SHORT_BY_BYTES"
2718 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2719 [(set_attr "type" "load")])
2721 (define_insn "*movhi_bytes"
2722 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
2723 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
2724 "TARGET_SHORT_BY_BYTES"
2726 mov%?\\t%0, %1\\t%@ movhi
2727 mvn%?\\t%0, #%B1\\t%@ movhi")
2730 (define_expand "reload_outhi"
2731 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2732 (match_operand:HI 1 "s_register_operand" "r")
2733 (match_operand:SI 2 "s_register_operand" "=&r")])]
2736 arm_reload_out_hi (operands);
2740 (define_expand "reload_inhi"
2741 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
2742 (match_operand:HI 1 "reload_memory_operand" "o")
2743 (match_operand:SI 2 "s_register_operand" "=&r")])]
2744 "TARGET_SHORT_BY_BYTES"
2746 arm_reload_in_hi (operands);
2750 (define_expand "movqi"
2751 [(set (match_operand:QI 0 "general_operand" "")
2752 (match_operand:QI 1 "general_operand" ""))]
2755 /* Everything except mem = const or mem = mem can be done easily */
2757 if (!(reload_in_progress || reload_completed))
2759 if (GET_CODE (operands[1]) == CONST_INT)
2761 rtx reg = gen_reg_rtx (SImode);
2763 emit_insn (gen_movsi (reg, operands[1]));
2764 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2766 if (GET_CODE (operands[0]) == MEM)
2767 operands[1] = force_reg (QImode, operands[1]);
2772 (define_insn "*movqi_insn"
2773 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2774 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
2775 "register_operand (operands[0], QImode)
2776 || register_operand (operands[1], QImode)"
2782 [(set_attr "type" "*,*,load,store1")])
2784 (define_expand "movsf"
2785 [(set (match_operand:SF 0 "general_operand" "")
2786 (match_operand:SF 1 "general_operand" ""))]
2789 if (GET_CODE (operands[0]) == MEM)
2790 operands[1] = force_reg (SFmode, operands[1]);
2793 (define_insn "*movsf_hard_insn"
2794 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2795 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
2797 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
2803 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2804 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
2806 ldr%?\\t%0, %1\\t%@ float
2807 str%?\\t%1, %0\\t%@ float"
2808 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2810 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2812 ;; Exactly the same as above, except that all `f' cases are deleted.
2813 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2814 ;; when -msoft-float.
2816 (define_insn "*movsf_soft_insn"
2817 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
2818 (match_operand:SF 1 "general_operand" "r,mE,r"))]
2820 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
2823 ldr%?\\t%0, %1\\t%@ float
2824 str%?\\t%1, %0\\t%@ float"
2825 [(set_attr "length" "4,4,4")
2826 (set_attr "type" "*,load,store1")])
2828 (define_expand "movdf"
2829 [(set (match_operand:DF 0 "general_operand" "")
2830 (match_operand:DF 1 "general_operand" ""))]
2833 if (GET_CODE (operands[0]) == MEM)
2834 operands[1] = force_reg (DFmode, operands[1]);
2837 ;; Reloading a df mode value stored in integer regs to memory can require a
2839 (define_expand "reload_outdf"
2840 [(match_operand:DF 0 "reload_memory_operand" "=o")
2841 (match_operand:DF 1 "s_register_operand" "r")
2842 (match_operand:SI 2 "s_register_operand" "=&r")]
2846 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
2849 operands[2] = XEXP (operands[0], 0);
2850 else if (code == POST_INC || code == PRE_DEC)
2852 operands[0] = gen_rtx (SUBREG, DImode, operands[0], 0);
2853 operands[1] = gen_rtx (SUBREG, DImode, operands[1], 0);
2854 emit_insn (gen_movdi (operands[0], operands[1]));
2857 else if (code == PRE_INC)
2859 rtx reg = XEXP (XEXP (operands[0], 0), 0);
2860 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
2863 else if (code == POST_DEC)
2864 operands[2] = XEXP (XEXP (operands[0], 0), 0);
2866 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
2867 XEXP (XEXP (operands[0], 0), 1)));
2869 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
2872 if (code == POST_DEC)
2873 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
2879 (define_insn "*movdf_hard_insn"
2880 [(set (match_operand:DF 0 "general_operand" "=r,Q,r,m,r,f,f,f,m,!f,!r")
2881 (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,fG,H,mF,f,r,f"))]
2883 && (GET_CODE (operands[0]) != MEM
2884 || register_operand (operands[1], DFmode))"
2889 switch (which_alternative)
2891 case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
2892 case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
2893 case 2: case 3: case 4: return output_move_double (operands);
2894 case 5: return \"mvf%?d\\t%0, %1\";
2895 case 6: return \"mnf%?d\\t%0, #%N1\";
2896 case 7: return \"ldf%?d\\t%0, %1\";
2897 case 8: return \"stf%?d\\t%1, %0\";
2898 case 9: return output_mov_double_fpu_from_arm (operands);
2899 case 10: return output_mov_double_arm_from_fpu (operands);
2903 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
2905 "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")])
2907 ;; Software floating point version. This is essentially the same as movdi.
2908 ;; Do not use `f' as a constraint to prevent reload from ever trying to use
2911 (define_insn "*movdf_soft_insn"
2912 [(set (match_operand:DF 0 "soft_df_operand" "=r,r,m")
2913 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
2915 "* return output_move_double (operands);"
2916 [(set_attr "length" "8,8,8")
2917 (set_attr "type" "*,load,store2")])
2919 (define_expand "movxf"
2920 [(set (match_operand:XF 0 "general_operand" "")
2921 (match_operand:XF 1 "general_operand" ""))]
2922 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2925 ;; Even when the XFmode patterns aren't enabled, we enable this after
2926 ;; reloading so that we can push floating point registers in the prologue.
2928 (define_insn "*movxf_hard_insn"
2929 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
2930 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
2931 "TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
2933 switch (which_alternative)
2935 case 0: return \"mvf%?e\\t%0, %1\";
2936 case 1: return \"mnf%?e\\t%0, #%N1\";
2937 case 2: return \"ldf%?e\\t%0, %1\";
2938 case 3: return \"stf%?e\\t%1, %0\";
2939 case 4: return output_mov_long_double_fpu_from_arm (operands);
2940 case 5: return output_mov_long_double_arm_from_fpu (operands);
2941 case 6: return output_mov_long_double_arm_from_arm (operands);
2944 [(set_attr "length" "4,4,4,4,8,8,12")
2945 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
2948 ;; load- and store-multiple insns
2949 ;; The arm can load/store any set of registers, provided that they are in
2950 ;; ascending order; but that is beyond GCC so stick with what it knows.
2952 (define_expand "load_multiple"
2953 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
2954 (match_operand:SI 1 "" ""))
2955 (use (match_operand:SI 2 "" ""))])]
2958 /* Support only fixed point registers */
2959 if (GET_CODE (operands[2]) != CONST_INT
2960 || INTVAL (operands[2]) > 14
2961 || INTVAL (operands[2]) < 2
2962 || GET_CODE (operands[1]) != MEM
2963 || GET_CODE (operands[0]) != REG
2964 || REGNO (operands[0]) > 14
2965 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
2969 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
2970 force_reg (SImode, XEXP (operands[1], 0)),
2974 ;; Load multiple with write-back
2976 (define_insn "*ldmsi_postinc"
2977 [(match_parallel 0 "load_multiple_operation"
2978 [(set (match_operand:SI 1 "s_register_operand" "+r")
2979 (plus:SI (match_dup 1)
2980 (match_operand:SI 2 "const_int_operand" "n")))
2981 (set (match_operand:SI 3 "s_register_operand" "=r")
2982 (mem:SI (match_dup 1)))])]
2983 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
2987 int count = XVECLEN (operands[0], 0);
2989 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
2990 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
2991 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
2993 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
2997 [(set_attr "type" "load")])
2999 ;; Ordinary load multiple
3001 (define_insn "*ldmsi"
3002 [(match_parallel 0 "load_multiple_operation"
3003 [(set (match_operand:SI 1 "s_register_operand" "=r")
3004 (mem:SI (match_operand:SI 2 "s_register_operand" "r")))])]
3009 int count = XVECLEN (operands[0], 0);
3011 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3012 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
3013 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
3015 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
3019 [(set_attr "type" "load")])
3021 (define_expand "store_multiple"
3022 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3023 (match_operand:SI 1 "" ""))
3024 (use (match_operand:SI 2 "" ""))])]
3027 /* Support only fixed point registers */
3028 if (GET_CODE (operands[2]) != CONST_INT
3029 || INTVAL (operands[2]) > 14
3030 || INTVAL (operands[2]) < 2
3031 || GET_CODE (operands[1]) != REG
3032 || GET_CODE (operands[0]) != MEM
3033 || REGNO (operands[1]) > 14
3034 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
3038 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
3039 force_reg (SImode, XEXP (operands[0], 0)),
3043 ;; Store multiple with write-back
3045 (define_insn "*stmsi_postinc"
3046 [(match_parallel 0 "store_multiple_operation"
3047 [(set (match_operand:SI 1 "s_register_operand" "+r")
3048 (plus:SI (match_dup 1)
3049 (match_operand:SI 2 "const_int_operand" "n")))
3050 (set (mem:SI (match_dup 1))
3051 (match_operand:SI 3 "s_register_operand" "r"))])]
3052 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3056 int count = XVECLEN (operands[0], 0);
3058 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3059 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
3060 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
3062 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
3067 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3068 (const_string "store2")
3069 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
3070 (const_string "store3")]
3071 (const_string "store4")))])
3073 ;; Ordinary store multiple
3075 (define_insn "*stmsi"
3076 [(match_parallel 0 "store_multiple_operation"
3077 [(set (mem:SI (match_operand:SI 2 "s_register_operand" "r"))
3078 (match_operand:SI 1 "s_register_operand" "r"))])]
3083 int count = XVECLEN (operands[0], 0);
3085 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
3086 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
3087 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
3089 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
3094 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
3095 (const_string "store2")
3096 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3097 (const_string "store3")]
3098 (const_string "store4")))])
3100 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
3101 ;; We could let this apply for blocks of less than this, but it clobbers so
3102 ;; many registers that there is then probably a better way.
3104 (define_expand "movstrqi"
3105 [(match_operand:BLK 0 "general_operand" "")
3106 (match_operand:BLK 1 "general_operand" "")
3107 (match_operand:SI 2 "const_int_operand" "")
3108 (match_operand:SI 3 "const_int_operand" "")]
3111 if (arm_gen_movstrqi (operands))
3117 ;; Comparison and test insns
3119 (define_expand "cmpsi"
3120 [(match_operand:SI 0 "s_register_operand" "")
3121 (match_operand:SI 1 "arm_add_operand" "")]
3125 arm_compare_op0 = operands[0];
3126 arm_compare_op1 = operands[1];
3132 (define_expand "cmpsf"
3133 [(match_operand:SF 0 "s_register_operand" "")
3134 (match_operand:SF 1 "fpu_rhs_operand" "")]
3138 arm_compare_op0 = operands[0];
3139 arm_compare_op1 = operands[1];
3145 (define_expand "cmpdf"
3146 [(match_operand:DF 0 "s_register_operand" "")
3147 (match_operand:DF 1 "fpu_rhs_operand" "")]
3151 arm_compare_op0 = operands[0];
3152 arm_compare_op1 = operands[1];
3158 (define_expand "cmpxf"
3159 [(match_operand:XF 0 "s_register_operand" "")
3160 (match_operand:XF 1 "fpu_rhs_operand" "")]
3161 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3164 arm_compare_op0 = operands[0];
3165 arm_compare_op1 = operands[1];
3171 (define_insn "*cmpsi_insn"
3173 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
3174 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
3179 [(set_attr "conds" "set")])
3181 (define_insn "*cmpsi_shiftsi"
3183 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3184 (match_operator:SI 3 "shift_operator"
3185 [(match_operand:SI 1 "s_register_operand" "r")
3186 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
3189 [(set_attr "conds" "set")])
3191 (define_insn "*cmpsi_shiftsi_swp"
3192 [(set (reg:CC_SWP 24)
3193 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
3194 [(match_operand:SI 1 "s_register_operand" "r")
3195 (match_operand:SI 2 "reg_or_int_operand" "rM")])
3196 (match_operand:SI 0 "s_register_operand" "r")))]
3199 [(set_attr "conds" "set")])
3201 (define_insn "*cmpsi_neg_shiftsi"
3203 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3204 (neg:SI (match_operator:SI 3 "shift_operator"
3205 [(match_operand:SI 1 "s_register_operand" "r")
3206 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
3209 [(set_attr "conds" "set")])
3211 (define_insn "*cmpsf_insn"
3213 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
3214 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3219 [(set_attr "conds" "set")
3220 (set_attr "type" "f_2_r")])
3222 (define_insn "*cmpdf_insn"
3224 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
3225 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3230 [(set_attr "conds" "set")
3231 (set_attr "type" "f_2_r")])
3233 (define_insn "*cmpesfdf_df"
3235 (compare:CCFP (float_extend:DF
3236 (match_operand:SF 0 "s_register_operand" "f,f"))
3237 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3242 [(set_attr "conds" "set")
3243 (set_attr "type" "f_2_r")])
3245 (define_insn "*cmpdf_esfdf"
3247 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
3249 (match_operand:SF 1 "s_register_operand" "f"))))]
3252 [(set_attr "conds" "set")
3253 (set_attr "type" "f_2_r")])
3255 (define_insn "*cmpxf_insn"
3257 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
3258 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3259 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3263 [(set_attr "conds" "set")
3264 (set_attr "type" "f_2_r")])
3266 (define_insn "*cmpsf_trap"
3267 [(set (reg:CCFPE 24)
3268 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
3269 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3274 [(set_attr "conds" "set")
3275 (set_attr "type" "f_2_r")])
3277 (define_insn "*cmpdf_trap"
3278 [(set (reg:CCFPE 24)
3279 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
3280 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3285 [(set_attr "conds" "set")
3286 (set_attr "type" "f_2_r")])
3288 (define_insn "*cmp_esfdf_df_trap"
3289 [(set (reg:CCFPE 24)
3290 (compare:CCFPE (float_extend:DF
3291 (match_operand:SF 0 "s_register_operand" "f,f"))
3292 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3297 [(set_attr "conds" "set")
3298 (set_attr "type" "f_2_r")])
3300 (define_insn "*cmp_df_esfdf_trap"
3301 [(set (reg:CCFPE 24)
3302 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
3304 (match_operand:SF 1 "s_register_operand" "f"))))]
3307 [(set_attr "conds" "set")
3308 (set_attr "type" "f_2_r")])
3310 (define_insn "*cmpxf_trap"
3311 [(set (reg:CCFPE 24)
3312 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
3313 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3314 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3318 [(set_attr "conds" "set")
3319 (set_attr "type" "f_2_r")])
3321 ; This insn allows redundant compares to be removed by cse, nothing should
3322 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
3323 ; is deleted later on. The match_dup will match the mode here, so that
3324 ; mode changes of the condition codes aren't lost by this even though we don't
3325 ; specify what they are.
3327 (define_insn "*delted_compare"
3328 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
3330 "\\t%@ deleted compare"
3331 [(set_attr "conds" "set")
3332 (set_attr "length" "0")])
3335 ;; Conditional branch insns
3337 (define_expand "beq"
3339 (if_then_else (eq (match_dup 1) (const_int 0))
3340 (label_ref (match_operand 0 "" ""))
3345 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3350 (define_expand "bne"
3352 (if_then_else (ne (match_dup 1) (const_int 0))
3353 (label_ref (match_operand 0 "" ""))
3358 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3363 (define_expand "bgt"
3365 (if_then_else (gt (match_dup 1) (const_int 0))
3366 (label_ref (match_operand 0 "" ""))
3371 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3376 (define_expand "ble"
3378 (if_then_else (le (match_dup 1) (const_int 0))
3379 (label_ref (match_operand 0 "" ""))
3384 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3389 (define_expand "bge"
3391 (if_then_else (ge (match_dup 1) (const_int 0))
3392 (label_ref (match_operand 0 "" ""))
3397 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3402 (define_expand "blt"
3404 (if_then_else (lt (match_dup 1) (const_int 0))
3405 (label_ref (match_operand 0 "" ""))
3410 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3415 (define_expand "bgtu"
3417 (if_then_else (gtu (match_dup 1) (const_int 0))
3418 (label_ref (match_operand 0 "" ""))
3423 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3428 (define_expand "bleu"
3430 (if_then_else (leu (match_dup 1) (const_int 0))
3431 (label_ref (match_operand 0 "" ""))
3436 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3441 (define_expand "bgeu"
3443 (if_then_else (geu (match_dup 1) (const_int 0))
3444 (label_ref (match_operand 0 "" ""))
3449 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3454 (define_expand "bltu"
3456 (if_then_else (ltu (match_dup 1) (const_int 0))
3457 (label_ref (match_operand 0 "" ""))
3462 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3467 ;; patterns to match conditional branch insns
3469 (define_insn "*condbranch"
3471 (if_then_else (match_operator 1 "comparison_operator"
3472 [(reg 24) (const_int 0)])
3473 (label_ref (match_operand 0 "" ""))
3478 extern int arm_ccfsm_state;
3480 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3482 arm_ccfsm_state += 2;
3485 return \"b%d1\\t%l0\";
3487 [(set_attr "conds" "use")])
3489 (define_insn "*condbranch_reversed"
3491 (if_then_else (match_operator 1 "comparison_operator"
3492 [(reg 24) (const_int 0)])
3494 (label_ref (match_operand 0 "" ""))))]
3498 extern int arm_ccfsm_state;
3500 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3502 arm_ccfsm_state += 2;
3505 return \"b%D1\\t%l0\";
3507 [(set_attr "conds" "use")])
3512 (define_expand "seq"
3513 [(set (match_operand:SI 0 "s_register_operand" "=r")
3514 (eq:SI (match_dup 1) (const_int 0)))]
3518 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3523 (define_expand "sne"
3524 [(set (match_operand:SI 0 "s_register_operand" "=r")
3525 (ne:SI (match_dup 1) (const_int 0)))]
3529 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3534 (define_expand "sgt"
3535 [(set (match_operand:SI 0 "s_register_operand" "=r")
3536 (gt:SI (match_dup 1) (const_int 0)))]
3540 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3545 (define_expand "sle"
3546 [(set (match_operand:SI 0 "s_register_operand" "=r")
3547 (le:SI (match_dup 1) (const_int 0)))]
3551 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3556 (define_expand "sge"
3557 [(set (match_operand:SI 0 "s_register_operand" "=r")
3558 (ge:SI (match_dup 1) (const_int 0)))]
3562 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3567 (define_expand "slt"
3568 [(set (match_operand:SI 0 "s_register_operand" "=r")
3569 (lt:SI (match_dup 1) (const_int 0)))]
3573 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3578 (define_expand "sgtu"
3579 [(set (match_operand:SI 0 "s_register_operand" "=r")
3580 (gtu:SI (match_dup 1) (const_int 0)))]
3584 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3589 (define_expand "sleu"
3590 [(set (match_operand:SI 0 "s_register_operand" "=r")
3591 (leu:SI (match_dup 1) (const_int 0)))]
3595 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3600 (define_expand "sgeu"
3601 [(set (match_operand:SI 0 "s_register_operand" "=r")
3602 (geu:SI (match_dup 1) (const_int 0)))]
3606 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3611 (define_expand "sltu"
3612 [(set (match_operand:SI 0 "s_register_operand" "=r")
3613 (ltu:SI (match_dup 1) (const_int 0)))]
3617 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3622 (define_insn "*mov_scc"
3623 [(set (match_operand:SI 0 "s_register_operand" "=r")
3624 (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
3626 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3627 [(set_attr "conds" "use")
3628 (set_attr "length" "8")])
3630 (define_insn "*mov_negscc"
3631 [(set (match_operand:SI 0 "s_register_operand" "=r")
3632 (neg:SI (match_operator:SI 1 "comparison_operator"
3633 [(reg 24) (const_int 0)])))]
3635 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3636 [(set_attr "conds" "use")
3637 (set_attr "length" "8")])
3639 (define_insn "*mov_notscc"
3640 [(set (match_operand:SI 0 "s_register_operand" "=r")
3641 (not:SI (match_operator:SI 1 "comparison_operator"
3642 [(reg 24) (const_int 0)])))]
3644 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3645 [(set_attr "conds" "use")
3646 (set_attr "length" "8")])
3649 ;; Conditional move insns
3651 (define_expand "movsicc"
3652 [(set (match_operand:SI 0 "register_operand" "")
3653 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3654 (match_operand:SI 2 "arm_not_operand" "")
3655 (match_operand:SI 3 "register_operand" "")))]
3659 enum rtx_code code = GET_CODE (operands[1]);
3660 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3663 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3666 (define_expand "movsfcc"
3667 [(set (match_operand:SF 0 "register_operand" "")
3668 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3669 (match_operand:SF 2 "nonmemory_operand" "")
3670 (match_operand:SF 3 "register_operand" "")))]
3674 enum rtx_code code = GET_CODE (operands[1]);
3675 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3678 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3681 (define_expand "movdfcc"
3682 [(set (match_operand:DF 0 "register_operand" "")
3683 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3684 (match_operand:DF 2 "nonmemory_operand" "")
3685 (match_operand:DF 3 "register_operand" "")))]
3689 enum rtx_code code = GET_CODE (operands[1]);
3690 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3693 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3696 (define_insn "*movsicc_insn"
3697 [(set (match_operand:SI 0 "register_operand" "=r,r")
3698 (if_then_else:SI (match_operator 1 "comparison_operator"
3699 [(reg 24) (const_int 0)])
3700 (match_operand:SI 2 "arm_not_operand" "rI,K")
3701 (match_operand:SI 3 "register_operand" "0,0")))]
3706 [(set_attr "type" "*,*")
3707 (set_attr "conds" "use,use")])
3709 (define_insn "*movsfcc_hard_insn"
3710 [(set (match_operand:SF 0 "register_operand" "=f")
3711 (if_then_else:SF (match_operator 1 "comparison_operator"
3712 [(reg 24) (const_int 0)])
3713 (match_operand:SF 2 "register_operand" "f")
3714 (match_operand:SF 3 "register_operand" "0")))]
3717 [(set_attr "type" "ffarith")
3718 (set_attr "conds" "use")])
3720 (define_insn "*movsfcc_soft_insn"
3721 [(set (match_operand:SF 0 "register_operand" "=r")
3722 (if_then_else:SF (match_operator 1 "comparison_operator"
3723 [(reg 24) (const_int 0)])
3724 (match_operand:SF 2 "register_operand" "r")
3725 (match_operand:SF 3 "register_operand" "0")))]
3728 [(set_attr "type" "*")
3729 (set_attr "conds" "use")])
3731 (define_insn "*movdfcc_insn"
3732 [(set (match_operand:DF 0 "register_operand" "=f")
3733 (if_then_else:DF (match_operator 1 "comparison_operator"
3734 [(reg 24) (const_int 0)])
3735 (match_operand:DF 2 "register_operand" "f")
3736 (match_operand:DF 3 "register_operand" "0")))]
3739 [(set_attr "type" "ffarith")
3740 (set_attr "conds" "use")])
3742 ;; Jump and linkage insns
3746 (label_ref (match_operand 0 "" "")))]
3750 extern int arm_ccfsm_state;
3752 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3754 arm_ccfsm_state += 2;
3757 return \"b%?\\t%l0\";
3760 (define_expand "call"
3761 [(parallel [(call (match_operand 0 "memory_operand" "")
3762 (match_operand 1 "general_operand" ""))
3763 (clobber (reg:SI 14))])]
3767 (define_insn "*call_reg"
3768 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3769 (match_operand 1 "" "g"))
3770 (clobber (reg:SI 14))]
3773 return output_call (operands);
3775 ;; length is worst case, normally it is only two
3776 [(set_attr "length" "12")
3777 (set_attr "type" "call")])
3779 (define_insn "*call_mem"
3780 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3781 (match_operand 1 "general_operand" "g"))
3782 (clobber (reg:SI 14))]
3785 return output_call_mem (operands);
3787 [(set_attr "length" "12")
3788 (set_attr "type" "call")])
3790 (define_expand "call_value"
3791 [(parallel [(set (match_operand 0 "" "=rf")
3792 (call (match_operand 1 "memory_operand" "m")
3793 (match_operand 2 "general_operand" "g")))
3794 (clobber (reg:SI 14))])]
3798 (define_insn "*call_value_reg"
3799 [(set (match_operand 0 "" "=rf")
3800 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3801 (match_operand 2 "general_operand" "g")))
3802 (clobber (reg:SI 14))]
3805 return output_call (&operands[1]);
3807 [(set_attr "length" "12")
3808 (set_attr "type" "call")])
3810 (define_insn "*call_value_mem"
3811 [(set (match_operand 0 "" "=rf")
3812 (call (mem:SI (match_operand 1 "memory_operand" "m"))
3813 (match_operand 2 "general_operand" "g")))
3814 (clobber (reg:SI 14))]
3815 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
3817 return output_call_mem (&operands[1]);
3819 [(set_attr "length" "12")
3820 (set_attr "type" "call")])
3822 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
3823 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
3825 (define_insn "*call_symbol"
3826 [(call (mem:SI (match_operand:SI 0 "" "X"))
3827 (match_operand:SI 1 "general_operand" "g"))
3828 (clobber (reg:SI 14))]
3829 "GET_CODE (operands[0]) == SYMBOL_REF"
3831 [(set_attr "type" "call")])
3833 (define_insn "*call_value_symbol"
3834 [(set (match_operand 0 "s_register_operand" "=rf")
3835 (call (mem:SI (match_operand:SI 1 "" "X"))
3836 (match_operand:SI 2 "general_operand" "g")))
3837 (clobber (reg:SI 14))]
3838 "GET_CODE(operands[1]) == SYMBOL_REF"
3840 [(set_attr "type" "call")])
3842 ;; Often the return insn will be the same as loading from memory, so set attr
3843 (define_insn "return"
3848 extern int arm_ccfsm_state;
3850 if (arm_ccfsm_state == 2)
3852 arm_ccfsm_state += 2;
3855 return output_return_instruction (NULL, TRUE, FALSE);
3857 [(set_attr "type" "load")])
3859 (define_insn "*cond_return"
3861 (if_then_else (match_operator 0 "comparison_operator"
3862 [(reg 24) (const_int 0)])
3868 extern int arm_ccfsm_state;
3870 if (arm_ccfsm_state == 2)
3872 arm_ccfsm_state += 2;
3875 return output_return_instruction (operands[0], TRUE, FALSE);
3877 [(set_attr "conds" "use")
3878 (set_attr "type" "load")])
3880 (define_insn "*cond_return_inverted"
3882 (if_then_else (match_operator 0 "comparison_operator"
3883 [(reg 24) (const_int 0)])
3889 extern int arm_ccfsm_state;
3891 if (arm_ccfsm_state == 2)
3893 arm_ccfsm_state += 2;
3896 return output_return_instruction (operands[0], TRUE, TRUE);
3898 [(set_attr "conds" "use")
3899 (set_attr "type" "load")])
3901 ;; Call subroutine returning any type.
3903 (define_expand "untyped_call"
3904 [(parallel [(call (match_operand 0 "" "")
3906 (match_operand 1 "" "")
3907 (match_operand 2 "" "")])]
3913 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3915 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3917 rtx set = XVECEXP (operands[2], 0, i);
3918 emit_move_insn (SET_DEST (set), SET_SRC (set));
3921 /* The optimizer does not know that the call sets the function value
3922 registers we stored in the result block. We avoid problems by
3923 claiming that all hard registers are used and clobbered at this
3925 emit_insn (gen_blockage ());
3930 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3931 ;; all of memory. This blocks insns from being moved across this point.
3933 (define_insn "blockage"
3934 [(unspec_volatile [(const_int 0)] 0)]
3937 [(set_attr "length" "0")
3938 (set_attr "type" "block")])
3940 (define_expand "casesi"
3941 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
3942 (match_operand:SI 1 "const_int_operand" "") ; lower bound
3943 (match_operand:SI 2 "const_int_operand" "") ; total range
3944 (match_operand:SI 3 "" "") ; table label
3945 (match_operand:SI 4 "" "")] ; Out of range label
3950 if (operands[1] != const0_rtx)
3952 reg = gen_reg_rtx (SImode);
3953 emit_insn (gen_addsi3 (reg, operands[0],
3954 GEN_INT (-INTVAL (operands[1]))));
3958 if (! const_ok_for_arm (INTVAL (operands[2])))
3959 operands[2] = force_reg (SImode, operands[2]);
3961 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
3966 (define_insn "casesi_internal"
3969 (leu (match_operand:SI 0 "s_register_operand" "r")
3970 (match_operand:SI 1 "arm_rhs_operand" "rI"))
3971 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
3972 (label_ref (match_operand 2 "" ""))))
3973 (label_ref (match_operand 3 "" ""))))]
3977 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
3978 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
3980 [(set_attr "conds" "clob")
3981 (set_attr "length" "12")])
3983 (define_insn "indirect_jump"
3985 (match_operand:SI 0 "s_register_operand" "r"))]
3987 "mov%?\\t%|pc, %0\\t%@ indirect jump")
3989 (define_insn "*load_indirect_jump"
3991 (match_operand:SI 0 "memory_operand" "m"))]
3993 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
3994 [(set_attr "type" "load")])
4001 "mov%?\\tr0, r0\\t%@ nop")
4003 ;; Patterns to allow combination of arithmetic, cond code and shifts
4005 (define_insn "*arith_shiftsi"
4006 [(set (match_operand:SI 0 "s_register_operand" "=r")
4007 (match_operator:SI 1 "shiftable_operator"
4008 [(match_operator:SI 3 "shift_operator"
4009 [(match_operand:SI 4 "s_register_operand" "r")
4010 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4011 (match_operand:SI 2 "s_register_operand" "r")]))]
4013 "%i1%?\\t%0, %2, %4%S3")
4015 (define_insn "*arith_shiftsi_compare0"
4016 [(set (reg:CC_NOOV 24)
4017 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4018 [(match_operator:SI 3 "shift_operator"
4019 [(match_operand:SI 4 "s_register_operand" "r")
4020 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4021 (match_operand:SI 2 "s_register_operand" "r")])
4023 (set (match_operand:SI 0 "s_register_operand" "=r")
4024 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
4027 "%i1%?s\\t%0, %2, %4%S3"
4028 [(set_attr "conds" "set")])
4030 (define_insn "*arith_shiftsi_compare0_scratch"
4031 [(set (reg:CC_NOOV 24)
4032 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4033 [(match_operator:SI 3 "shift_operator"
4034 [(match_operand:SI 4 "s_register_operand" "r")
4035 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4036 (match_operand:SI 2 "s_register_operand" "r")])
4038 (clobber (match_scratch:SI 0 "=r"))]
4040 "%i1%?s\\t%0, %2, %4%S3"
4041 [(set_attr "conds" "set")])
4043 (define_insn "*sub_shiftsi"
4044 [(set (match_operand:SI 0 "s_register_operand" "=r")
4045 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4046 (match_operator:SI 2 "shift_operator"
4047 [(match_operand:SI 3 "s_register_operand" "r")
4048 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
4050 "sub%?\\t%0, %1, %3%S2")
4052 (define_insn "*sub_shiftsi_compare0"
4053 [(set (reg:CC_NOOV 24)
4055 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4056 (match_operator:SI 2 "shift_operator"
4057 [(match_operand:SI 3 "s_register_operand" "r")
4058 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4060 (set (match_operand:SI 0 "s_register_operand" "=r")
4061 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4064 "sub%?s\\t%0, %1, %3%S2"
4065 [(set_attr "conds" "set")])
4067 (define_insn "*sub_shiftsi_compare0_scratch"
4068 [(set (reg:CC_NOOV 24)
4070 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4071 (match_operator:SI 2 "shift_operator"
4072 [(match_operand:SI 3 "s_register_operand" "r")
4073 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4075 (clobber (match_scratch:SI 0 "=r"))]
4077 "sub%?s\\t%0, %1, %3%S2"
4078 [(set_attr "conds" "set")])
4080 ;; These variants of the above insns can occur if the first operand is the
4081 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
4082 ;; seem to be a way around it. Most of the predicates have to be null
4083 ;; because the format can be generated part way through reload, so
4084 ;; if we don't match it as soon as it becomes available, reload doesn't know
4085 ;; how to reload pseudos that haven't got hard registers; the constraints will
4086 ;; sort everything out.
4088 (define_insn "*reload_mulsi3"
4089 [(set (match_operand:SI 0 "" "=&r")
4090 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
4091 [(match_operand:SI 3 "" "r")
4092 (match_operand:SI 4 "" "rM")])
4093 (match_operand:SI 2 "" "r"))
4094 (match_operand:SI 1 "const_int_operand" "n")))]
4095 "reload_in_progress"
4097 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
4098 operands[2] = operands[1];
4099 operands[1] = operands[0];
4100 return output_add_immediate (operands);
4102 ; we have no idea how long the add_immediate is, it could be up to 4.
4103 [(set_attr "length" "20")])
4105 (define_insn "*relaod_mulsi_compare0"
4106 [(set (reg:CC_NOOV 24)
4107 (compare:CC_NOOV (plus:SI
4109 (match_operator:SI 5 "shift_operator"
4110 [(match_operand:SI 3 "" "r")
4111 (match_operand:SI 4 "" "rM")])
4112 (match_operand:SI 1 "" "r"))
4113 (match_operand:SI 2 "const_int_operand" "n"))
4115 (set (match_operand:SI 0 "" "=&r")
4116 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
4119 "reload_in_progress"
4121 output_add_immediate (operands);
4122 return \"add%?s\\t%0, %0, %3%S5\";
4124 [(set_attr "conds" "set")
4125 (set_attr "length" "20")])
4127 (define_insn "*reload_mulsi_compare0_scratch"
4128 [(set (reg:CC_NOOV 24)
4129 (compare:CC_NOOV (plus:SI
4131 (match_operator:SI 5 "shift_operator"
4132 [(match_operand:SI 3 "" "r")
4133 (match_operand:SI 4 "" "rM")])
4134 (match_operand:SI 1 "" "r"))
4135 (match_operand:SI 2 "const_int_operand" "n"))
4137 (clobber (match_scratch:SI 0 "=&r"))]
4138 "reload_in_progress"
4140 output_add_immediate (operands);
4141 return \"add%?s\\t%0, %0, %3%S5\";
4143 [(set_attr "conds" "set")
4144 (set_attr "length" "20")])
4146 ;; These are similar, but are needed when the mla pattern contains the
4147 ;; eliminated register as operand 3.
4149 (define_insn "*reload_muladdsi"
4150 [(set (match_operand:SI 0 "" "=&r,&r")
4151 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
4152 (match_operand:SI 2 "" "r,r"))
4153 (match_operand:SI 3 "" "r,r"))
4154 (match_operand:SI 4 "const_int_operand" "n,n")))]
4155 "reload_in_progress"
4157 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
4158 operands[2] = operands[4];
4159 operands[1] = operands[0];
4160 return output_add_immediate (operands);
4162 [(set_attr "length" "20")
4163 (set_attr "type" "mult")])
4165 (define_insn "*reload_muladdsi_compare0"
4166 [(set (reg:CC_NOOV 24)
4167 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4168 (match_operand:SI 3 "" "r")
4169 (match_operand:SI 4 "" "r"))
4170 (match_operand:SI 1 "" "r"))
4171 (match_operand:SI 2 "const_int_operand" "n"))
4173 (set (match_operand:SI 0 "" "=&r")
4174 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
4176 "reload_in_progress"
4178 output_add_immediate (operands);
4179 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
4182 [(set_attr "length" "20")
4183 (set_attr "conds" "set")
4184 (set_attr "type" "mult")])
4186 (define_insn "*reload_muladdsi_compare0_scratch"
4187 [(set (reg:CC_NOOV 24)
4188 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4189 (match_operand:SI 3 "" "r")
4190 (match_operand:SI 4 "" "r"))
4191 (match_operand:SI 1 "" "r"))
4192 (match_operand:SI 2 "const_int_operand" "n"))
4194 (clobber (match_scratch:SI 0 "=&r"))]
4195 "reload_in_progress"
4197 output_add_immediate (operands);
4198 return \"mla%?s\\t%0, %3, %4, %0\";
4200 [(set_attr "length" "20")
4201 (set_attr "conds" "set")
4202 (set_attr "type" "mult")])
4206 (define_insn "*and_scc"
4207 [(set (match_operand:SI 0 "s_register_operand" "=r")
4208 (and:SI (match_operator 1 "comparison_operator"
4209 [(match_operand 3 "cc_register" "") (const_int 0)])
4210 (match_operand:SI 2 "s_register_operand" "r")))]
4212 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
4213 [(set_attr "conds" "use")
4214 (set_attr "length" "8")])
4216 (define_insn "*ior_scc"
4217 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4218 (ior:SI (match_operator 2 "comparison_operator"
4219 [(reg 24) (const_int 0)])
4220 (match_operand:SI 1 "s_register_operand" "0,?r")))]
4224 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
4225 [(set_attr "conds" "use")
4226 (set_attr "length" "4,8")])
4228 (define_insn "*compare_scc"
4229 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4230 (match_operator 1 "comparison_operator"
4231 [(match_operand:SI 2 "s_register_operand" "r,r")
4232 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
4236 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
4237 return \"mov\\t%0, %2, lsr #31\";
4239 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
4240 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
4242 if (GET_CODE (operands[1]) == NE)
4244 if (which_alternative == 1)
4245 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
4246 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
4248 if (which_alternative == 1)
4249 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4251 output_asm_insn (\"cmp\\t%2, %3\", operands);
4252 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
4254 [(set_attr "conds" "clob")
4255 (set_attr "length" "12")])
4257 (define_insn "*cond_move"
4258 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4259 (if_then_else:SI (match_operator 3 "equality_operator"
4260 [(match_operator 4 "comparison_operator"
4261 [(reg 24) (const_int 0)])
4263 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4264 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
4267 if (GET_CODE (operands[3]) == NE)
4269 if (which_alternative != 1)
4270 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4271 if (which_alternative != 0)
4272 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
4275 if (which_alternative != 0)
4276 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4277 if (which_alternative != 1)
4278 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
4281 [(set_attr "conds" "use")
4282 (set_attr "length" "4,4,8")])
4284 (define_insn "*cond_arith"
4285 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4286 (match_operator:SI 5 "shiftable_operator"
4287 [(match_operator:SI 4 "comparison_operator"
4288 [(match_operand:SI 2 "s_register_operand" "r,r")
4289 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4290 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4294 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4295 return \"%i5\\t%0, %1, %2, lsr #31\";
4297 output_asm_insn (\"cmp\\t%2, %3\", operands);
4298 if (GET_CODE (operands[5]) == AND)
4299 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4300 else if (GET_CODE (operands[5]) == MINUS)
4301 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
4302 else if (which_alternative != 0)
4303 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4304 return \"%i5%d4\\t%0, %1, #1\";
4306 [(set_attr "conds" "clob")
4307 (set_attr "length" "12")])
4309 (define_insn "*cond_sub"
4310 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4311 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4312 (match_operator:SI 4 "comparison_operator"
4313 [(match_operand:SI 2 "s_register_operand" "r,r")
4314 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4318 output_asm_insn (\"cmp\\t%2, %3\", operands);
4319 if (which_alternative != 0)
4320 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4321 return \"sub%d4\\t%0, %1, #1\";
4323 [(set_attr "conds" "clob")
4324 (set_attr "length" "8,12")])
4326 (define_insn "*cmp_ite0"
4327 [(set (match_operand 6 "dominant_cc_register" "")
4330 (match_operator 4 "comparison_operator"
4331 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4332 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4333 (match_operator:SI 5 "comparison_operator"
4334 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4335 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4341 char* opcodes[4][2] =
4343 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
4344 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
4345 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
4346 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
4347 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
4350 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
4352 return opcodes[which_alternative][swap];
4355 [(set_attr "conds" "set")
4356 (set_attr "length" "8")])
4358 (define_insn "*cmp_ite1"
4359 [(set (match_operand 6 "dominant_cc_register" "")
4362 (match_operator 4 "comparison_operator"
4363 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4364 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4365 (match_operator:SI 5 "comparison_operator"
4366 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4367 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4373 char* opcodes[4][2] =
4375 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
4376 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
4377 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
4378 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
4379 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
4382 comparison_dominates_p (GET_CODE (operands[5]),
4383 reverse_condition (GET_CODE (operands[4])));
4385 return opcodes[which_alternative][swap];
4388 [(set_attr "conds" "set")
4389 (set_attr "length" "8")])
4391 (define_insn "*negscc"
4392 [(set (match_operand:SI 0 "s_register_operand" "=r")
4393 (neg:SI (match_operator 3 "comparison_operator"
4394 [(match_operand:SI 1 "s_register_operand" "r")
4395 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4399 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4400 return \"mov\\t%0, %1, asr #31\";
4402 if (GET_CODE (operands[3]) == NE)
4403 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4405 if (GET_CODE (operands[3]) == GT)
4406 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4408 output_asm_insn (\"cmp\\t%1, %2\", operands);
4409 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4410 return \"mvn%d3\\t%0, #0\";
4412 [(set_attr "conds" "clob")
4413 (set_attr "length" "12")])
4415 (define_insn "movcond"
4416 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4418 (match_operator 5 "comparison_operator"
4419 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4420 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4421 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4422 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4426 if (GET_CODE (operands[5]) == LT
4427 && (operands[4] == const0_rtx))
4429 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4431 if (operands[2] == const0_rtx)
4432 return \"and\\t%0, %1, %3, asr #31\";
4433 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4435 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4437 if (operands[1] == const0_rtx)
4438 return \"bic\\t%0, %2, %3, asr #31\";
4439 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4441 /* The only case that falls through to here is when both ops 1 & 2
4445 if (GET_CODE (operands[5]) == GE
4446 && (operands[4] == const0_rtx))
4448 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4450 if (operands[2] == const0_rtx)
4451 return \"bic\\t%0, %1, %3, asr #31\";
4452 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4454 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4456 if (operands[1] == const0_rtx)
4457 return \"and\\t%0, %2, %3, asr #31\";
4458 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4460 /* The only case that falls through to here is when both ops 1 & 2
4463 if (GET_CODE (operands[4]) == CONST_INT
4464 && !const_ok_for_arm (INTVAL (operands[4])))
4465 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4467 output_asm_insn (\"cmp\\t%3, %4\", operands);
4468 if (which_alternative != 0)
4469 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4470 if (which_alternative != 1)
4471 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4474 [(set_attr "conds" "clob")
4475 (set_attr "length" "8,8,12")])
4477 (define_insn "*ifcompare_arith_arith"
4478 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4479 (if_then_else:SI (match_operator 9 "comparison_operator"
4480 [(match_operand:SI 5 "s_register_operand" "r,r")
4481 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4482 (match_operator:SI 8 "shiftable_operator"
4483 [(match_operand:SI 1 "s_register_operand" "r,r")
4484 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
4485 (match_operator:SI 7 "shiftable_operator"
4486 [(match_operand:SI 3 "s_register_operand" "r,r")
4487 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4491 cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
4492 cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
4493 [(set_attr "conds" "clob")
4494 (set_attr "length" "12")])
4496 (define_insn "*ifcompare_arith_move"
4497 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4498 (if_then_else:SI (match_operator 6 "comparison_operator"
4499 [(match_operand:SI 2 "s_register_operand" "r,r")
4500 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4501 (match_operator:SI 7 "shiftable_operator"
4502 [(match_operand:SI 4 "s_register_operand" "r,r")
4503 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4504 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4508 /* If we have an operation where (op x 0) is the identity operation and
4509 the conditional operator is LT or GE and we are comparing against zero and
4510 everything is in registers then we can do this in two instructions */
4511 if (operands[3] == const0_rtx
4512 && GET_CODE (operands[7]) != AND
4513 && GET_CODE (operands[5]) == REG
4514 && GET_CODE (operands[1]) == REG
4515 && REGNO (operands[1]) == REGNO (operands[4])
4516 && REGNO (operands[4]) != REGNO (operands[0]))
4518 if (GET_CODE (operands[6]) == LT)
4519 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4520 else if (GET_CODE (operands[6]) == GE)
4521 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4523 if (GET_CODE (operands[3]) == CONST_INT
4524 && !const_ok_for_arm (INTVAL (operands[3])))
4525 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4527 output_asm_insn (\"cmp\\t%2, %3\", operands);
4528 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4529 if (which_alternative != 0)
4531 if (GET_CODE (operands[1]) == MEM)
4532 return \"ldr%D6\\t%0, %1\";
4534 return \"mov%D6\\t%0, %1\";
4538 [(set_attr "conds" "clob")
4539 (set_attr "length" "8,12")])
4541 (define_insn "*ifcompare_move_arith"
4542 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4543 (if_then_else:SI (match_operator 6 "comparison_operator"
4544 [(match_operand:SI 4 "s_register_operand" "r,r")
4545 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4546 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4547 (match_operator:SI 7 "shiftable_operator"
4548 [(match_operand:SI 2 "s_register_operand" "r,r")
4549 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4553 /* If we have an operation where (op x 0) is the identity operation and
4554 the conditional operator is LT or GE and we are comparing against zero and
4555 everything is in registers then we can do this in two instructions */
4556 if (operands[5] == const0_rtx
4557 && GET_CODE (operands[7]) != AND
4558 && GET_CODE (operands[3]) == REG
4559 && GET_CODE (operands[1]) == REG
4560 && REGNO (operands[1]) == REGNO (operands[2])
4561 && REGNO (operands[2]) != REGNO (operands[0]))
4563 if (GET_CODE (operands[6]) == GE)
4564 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4565 else if (GET_CODE (operands[6]) == LT)
4566 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4569 if (GET_CODE (operands[5]) == CONST_INT
4570 && !const_ok_for_arm (INTVAL (operands[5])))
4571 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4573 output_asm_insn (\"cmp\\t%4, %5\", operands);
4575 if (which_alternative != 0)
4577 if (GET_CODE (operands[1]) == MEM)
4578 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4580 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4582 return \"%I7%D6\\t%0, %2, %3\";
4584 [(set_attr "conds" "clob")
4585 (set_attr "length" "8,12")])
4587 (define_insn "*ifcompare_plus_move"
4588 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4589 (if_then_else:SI (match_operator 6 "comparison_operator"
4590 [(match_operand:SI 4 "s_register_operand" "r,r")
4591 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4593 (match_operand:SI 2 "s_register_operand" "r,r")
4594 (match_operand:SI 3 "arm_add_operand" "rL,rL"))
4595 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4600 if (GET_CODE (operands[5]) == CONST_INT
4601 && !const_ok_for_arm (INTVAL (operands[5])))
4602 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4604 output_asm_insn (\"cmp\\t%4, %5\", operands);
4605 if (GET_CODE (operands[3]) == CONST_INT
4606 && !const_ok_for_arm (INTVAL (operands[3])))
4607 output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
4609 output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
4610 if (which_alternative != 0)
4612 if (GET_CODE (operands[1]) == MEM)
4613 output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
4615 output_asm_insn (\"mov%D6\\t%0, %1\", operands);
4620 [(set_attr "conds" "clob")
4621 (set_attr "length" "8,12")])
4623 (define_insn "*ifcompare_move_plus"
4624 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4625 (if_then_else:SI (match_operator 6 "comparison_operator"
4626 [(match_operand:SI 4 "s_register_operand" "r,r")
4627 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4628 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4630 (match_operand:SI 2 "s_register_operand" "r,r")
4631 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4636 if (GET_CODE (operands[5]) == CONST_INT
4637 && !const_ok_for_arm (INTVAL (operands[5])))
4638 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4640 output_asm_insn (\"cmp\\t%4, %5\", operands);
4641 if (GET_CODE (operands[3]) == CONST_INT
4642 && !const_ok_for_arm (INTVAL (operands[3])))
4643 output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
4645 output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
4646 if (which_alternative != 0)
4648 if (GET_CODE (operands[6]) == MEM)
4649 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4651 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4656 [(set_attr "conds" "clob")
4657 (set_attr "length" "8,12")])
4659 (define_insn "*ifcompare_move_not"
4660 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4661 (if_then_else:SI (match_operator 5 "comparison_operator"
4662 [(match_operand:SI 3 "s_register_operand" "r,r")
4663 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4664 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4666 (match_operand:SI 2 "s_register_operand" "r,r"))))
4670 [(set_attr "conds" "clob")
4671 (set_attr "length" "8,12")])
4673 (define_insn "*ifcompare_not_move"
4674 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4676 (match_operator 5 "comparison_operator"
4677 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4678 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4680 (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4681 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4685 cmp\\t%3, %4\;mvn%d5\\t%0, %2
4686 cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
4687 cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
4688 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
4689 [(set_attr "conds" "clob")
4690 (set_attr "length" "8,8,12,12")])
4692 (define_insn "*ifcompare_shift_move"
4693 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4695 (match_operator 6 "comparison_operator"
4696 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4697 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4698 (match_operator:SI 7 "shift_operator"
4699 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4700 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
4701 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4705 cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
4706 cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
4707 cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
4708 cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
4709 [(set_attr "conds" "clob")
4710 (set_attr "length" "8,8,12,12")])
4712 (define_insn "ifcompare_move_shift"
4713 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4715 (match_operator 6 "comparison_operator"
4716 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
4717 (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
4718 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4719 (match_operator:SI 7 "shift_operator"
4720 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4721 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
4725 cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
4726 cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
4727 cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
4728 cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
4729 [(set_attr "conds" "clob")
4730 (set_attr "length" "8,8,12,12")])
4732 (define_insn "*ifcompare_shift_shift"
4733 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4735 (match_operator 7 "comparison_operator"
4736 [(match_operand:SI 5 "s_register_operand" "r,r")
4737 (match_operand:SI 6 "arm_add_operand" "rI,L")])
4738 (match_operator:SI 8 "shift_operator"
4739 [(match_operand:SI 1 "s_register_operand" "r,r")
4740 (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
4741 (match_operator:SI 9 "shift_operator"
4742 [(match_operand:SI 3 "s_register_operand" "r,r")
4743 (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
4747 cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
4748 cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
4749 [(set_attr "conds" "clob")
4750 (set_attr "length" "12")])
4752 (define_insn "*ifcompare_not_arith"
4753 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4755 (match_operator 6 "comparison_operator"
4756 [(match_operand:SI 4 "s_register_operand" "r,r")
4757 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4758 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
4759 (match_operator:SI 7 "shiftable_operator"
4760 [(match_operand:SI 2 "s_register_operand" "r,r")
4761 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4765 cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
4766 cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
4767 [(set_attr "conds" "clob")
4768 (set_attr "length" "12")])
4770 (define_insn "*if_compare_arith_not"
4771 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4773 (match_operator 6 "comparison_operator"
4774 [(match_operand:SI 4 "s_register_operand" "r,r")
4775 (match_operand:SI 5 "arm_add_operand" "rI,L")])
4776 (match_operator:SI 7 "shiftable_operator"
4777 [(match_operand:SI 2 "s_register_operand" "r,r")
4778 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4779 (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
4783 cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
4784 cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
4785 [(set_attr "conds" "clob")
4786 (set_attr "length" "12")])
4788 (define_insn "*ifcompare_neg_move"
4789 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4791 (match_operator 5 "comparison_operator"
4792 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4793 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4794 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
4795 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
4796 (clobber (reg:CC 24))]
4799 cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
4800 cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
4801 cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
4802 cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
4803 [(set_attr "conds" "clob")
4804 (set_attr "length" "8,8,12,12")])
4806 (define_insn "*ifcompare_move_neg"
4807 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4809 (match_operator 5 "comparison_operator"
4810 [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
4811 (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
4812 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4813 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
4814 (clobber (reg:CC 24))]
4817 cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
4818 cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
4819 cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
4820 cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
4821 [(set_attr "conds" "clob")
4822 (set_attr "length" "8,8,12,12")])
4824 (define_insn "*arith_adjacentmem"
4825 [(set (match_operand:SI 0 "s_register_operand" "=r")
4826 (match_operator:SI 1 "shiftable_operator"
4827 [(match_operand:SI 2 "memory_operand" "m")
4828 (match_operand:SI 3 "memory_operand" "m")]))
4829 (clobber (match_scratch:SI 4 "=r"))]
4830 "adjacent_mem_locations (operands[2], operands[3])"
4835 int val1 = 0, val2 = 0;
4837 if (REGNO (operands[0]) > REGNO (operands[4]))
4839 ldm[1] = operands[4];
4840 ldm[2] = operands[0];
4844 ldm[1] = operands[0];
4845 ldm[2] = operands[4];
4847 if (GET_CODE (XEXP (operands[2], 0)) != REG)
4848 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
4849 if (GET_CODE (XEXP (operands[3], 0)) != REG)
4850 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
4851 arith[0] = operands[0];
4852 arith[3] = operands[1];
4866 ldm[0] = ops[0] = operands[4];
4867 ops[1] = XEXP (XEXP (operands[2], 0), 0);
4868 ops[2] = XEXP (XEXP (operands[2], 0), 1);
4869 output_add_immediate (ops);
4871 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4873 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4877 ldm[0] = XEXP (operands[3], 0);
4879 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4881 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4885 ldm[0] = XEXP (operands[2], 0);
4887 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
4889 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
4891 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
4895 [(set_attr "length" "12")
4896 (set_attr "type" "load")])
4898 ;; the arm can support extended pre-inc instructions
4900 ;; In all these cases, we use operands 0 and 1 for the register being
4901 ;; incremented because those are the operands that local-alloc will
4902 ;; tie and these are the pair most likely to be tieable (and the ones
4903 ;; that will benefit the most).
4905 ;; We reject the frame pointer if it occurs anywhere in these patterns since
4906 ;; elimination will cause too many headaches.
4908 (define_insn "*strqi_preinc"
4909 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4910 (match_operand:SI 2 "index_operand" "rJ")))
4911 (match_operand:QI 3 "s_register_operand" "r"))
4912 (set (match_operand:SI 0 "s_register_operand" "=r")
4913 (plus:SI (match_dup 1) (match_dup 2)))]
4914 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4915 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4916 && (GET_CODE (operands[2]) != REG
4917 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4918 "str%?b\\t%3, [%0, %2]!"
4919 [(set_attr "type" "store1")])
4921 (define_insn "*strqi_predec"
4922 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4923 (match_operand:SI 2 "s_register_operand" "r")))
4924 (match_operand:QI 3 "s_register_operand" "r"))
4925 (set (match_operand:SI 0 "s_register_operand" "=r")
4926 (minus:SI (match_dup 1) (match_dup 2)))]
4927 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4928 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4929 && (GET_CODE (operands[2]) != REG
4930 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4931 "str%?b\\t%3, [%0, -%2]!"
4932 [(set_attr "type" "store1")])
4934 (define_insn "*loadqi_preinc"
4935 [(set (match_operand:QI 3 "s_register_operand" "=r")
4936 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4937 (match_operand:SI 2 "index_operand" "rJ"))))
4938 (set (match_operand:SI 0 "s_register_operand" "=r")
4939 (plus:SI (match_dup 1) (match_dup 2)))]
4940 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4941 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4942 && (GET_CODE (operands[2]) != REG
4943 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4944 "ldr%?b\\t%3, [%0, %2]!"
4945 [(set_attr "type" "load")])
4947 (define_insn "*loadqi_predec"
4948 [(set (match_operand:QI 3 "s_register_operand" "=r")
4949 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4950 (match_operand:SI 2 "s_register_operand" "r"))))
4951 (set (match_operand:SI 0 "s_register_operand" "=r")
4952 (minus:SI (match_dup 1) (match_dup 2)))]
4953 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4954 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4955 && (GET_CODE (operands[2]) != REG
4956 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4957 "ldr%?b\\t%3, [%0, -%2]!"
4958 [(set_attr "type" "load")])
4960 (define_insn "*loadqisi_preinc"
4961 [(set (match_operand:SI 3 "s_register_operand" "=r")
4963 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4964 (match_operand:SI 2 "index_operand" "rJ")))))
4965 (set (match_operand:SI 0 "s_register_operand" "=r")
4966 (plus:SI (match_dup 1) (match_dup 2)))]
4967 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4968 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4969 && (GET_CODE (operands[2]) != REG
4970 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4971 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
4972 [(set_attr "type" "load")])
4974 (define_insn "*loadqisi_predec"
4975 [(set (match_operand:SI 3 "s_register_operand" "=r")
4977 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
4978 (match_operand:SI 2 "s_register_operand" "r")))))
4979 (set (match_operand:SI 0 "s_register_operand" "=r")
4980 (minus:SI (match_dup 1) (match_dup 2)))]
4981 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4982 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4983 && (GET_CODE (operands[2]) != REG
4984 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4985 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
4986 [(set_attr "type" "load")])
4988 (define_insn "*strsi_preinc"
4989 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
4990 (match_operand:SI 2 "index_operand" "rJ")))
4991 (match_operand:SI 3 "s_register_operand" "r"))
4992 (set (match_operand:SI 0 "s_register_operand" "=r")
4993 (plus:SI (match_dup 1) (match_dup 2)))]
4994 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
4995 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
4996 && (GET_CODE (operands[2]) != REG
4997 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
4998 "str%?\\t%3, [%0, %2]!"
4999 [(set_attr "type" "store1")])
5001 (define_insn "*strqi_predec"
5002 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5003 (match_operand:SI 2 "s_register_operand" "r")))
5004 (match_operand:SI 3 "s_register_operand" "r"))
5005 (set (match_operand:SI 0 "s_register_operand" "=r")
5006 (minus:SI (match_dup 1) (match_dup 2)))]
5007 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5008 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5009 && (GET_CODE (operands[2]) != REG
5010 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5011 "str%?\\t%3, [%0, -%2]!"
5012 [(set_attr "type" "store1")])
5014 (define_insn "*loadsi_preinc"
5015 [(set (match_operand:SI 3 "s_register_operand" "=r")
5016 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5017 (match_operand:SI 2 "index_operand" "rJ"))))
5018 (set (match_operand:SI 0 "s_register_operand" "=r")
5019 (plus:SI (match_dup 1) (match_dup 2)))]
5020 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5021 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5022 && (GET_CODE (operands[2]) != REG
5023 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5024 "ldr%?\\t%3, [%0, %2]!"
5025 [(set_attr "type" "load")])
5027 (define_insn "*loadsi_predec"
5028 [(set (match_operand:SI 3 "s_register_operand" "=r")
5029 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5030 (match_operand:SI 2 "s_register_operand" "r"))))
5031 (set (match_operand:SI 0 "s_register_operand" "=r")
5032 (minus:SI (match_dup 1) (match_dup 2)))]
5033 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5034 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5035 && (GET_CODE (operands[2]) != REG
5036 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5037 "ldr%?\\t%3, [%0, -%2]!"
5038 [(set_attr "type" "load")])
5040 (define_insn "*loadhi_preinc"
5041 [(set (match_operand:HI 3 "s_register_operand" "=r")
5042 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5043 (match_operand:SI 2 "index_operand" "rJ"))))
5044 (set (match_operand:SI 0 "s_register_operand" "=r")
5045 (plus:SI (match_dup 1) (match_dup 2)))]
5046 "(! BYTES_BIG_ENDIAN)
5047 && ! TARGET_SHORT_BY_BYTES
5048 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5049 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5050 && (GET_CODE (operands[2]) != REG
5051 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5052 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
5053 [(set_attr "type" "load")])
5055 (define_insn "*loadhi_predec"
5056 [(set (match_operand:HI 3 "s_register_operand" "=r")
5057 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5058 (match_operand:SI 2 "s_register_operand" "r"))))
5059 (set (match_operand:SI 0 "s_register_operand" "=r")
5060 (minus:SI (match_dup 1) (match_dup 2)))]
5061 "(!BYTES_BIG_ENDIAN)
5062 && ! TARGET_SHORT_BY_BYTES
5063 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5064 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5065 && (GET_CODE (operands[2]) != REG
5066 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5067 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
5068 [(set_attr "type" "load")])
5070 (define_insn "*strqi_shiftpreinc"
5071 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5072 [(match_operand:SI 3 "s_register_operand" "r")
5073 (match_operand:SI 4 "const_shift_operand" "n")])
5074 (match_operand:SI 1 "s_register_operand" "0")))
5075 (match_operand:QI 5 "s_register_operand" "r"))
5076 (set (match_operand:SI 0 "s_register_operand" "=r")
5077 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5079 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5080 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5081 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5082 "str%?b\\t%5, [%0, %3%S2]!"
5083 [(set_attr "type" "store1")])
5085 (define_insn "*strqi_shiftpredec"
5086 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5087 (match_operator:SI 2 "shift_operator"
5088 [(match_operand:SI 3 "s_register_operand" "r")
5089 (match_operand:SI 4 "const_shift_operand" "n")])))
5090 (match_operand:QI 5 "s_register_operand" "r"))
5091 (set (match_operand:SI 0 "s_register_operand" "=r")
5092 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5094 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5095 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5096 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5097 "str%?b\\t%5, [%0, -%3%S2]!"
5098 [(set_attr "type" "store1")])
5100 (define_insn "*loadqi_shiftpreinc"
5101 [(set (match_operand:QI 5 "s_register_operand" "=r")
5102 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5103 [(match_operand:SI 3 "s_register_operand" "r")
5104 (match_operand:SI 4 "const_shift_operand" "n")])
5105 (match_operand:SI 1 "s_register_operand" "0"))))
5106 (set (match_operand:SI 0 "s_register_operand" "=r")
5107 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5109 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5110 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5111 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5112 "ldr%?b\\t%5, [%0, %3%S2]!"
5113 [(set_attr "type" "load")])
5115 (define_insn "*loadqi_shiftpredec"
5116 [(set (match_operand:QI 5 "s_register_operand" "=r")
5117 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5118 (match_operator:SI 2 "shift_operator"
5119 [(match_operand:SI 3 "s_register_operand" "r")
5120 (match_operand:SI 4 "const_shift_operand" "n")]))))
5121 (set (match_operand:SI 0 "s_register_operand" "=r")
5122 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5124 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5125 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5126 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5127 "ldr%?b\\t%5, [%0, -%3%S2]!"
5128 [(set_attr "type" "load")])
5130 (define_insn "*strsi_shiftpreinc"
5131 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5132 [(match_operand:SI 3 "s_register_operand" "r")
5133 (match_operand:SI 4 "const_shift_operand" "n")])
5134 (match_operand:SI 1 "s_register_operand" "0")))
5135 (match_operand:SI 5 "s_register_operand" "r"))
5136 (set (match_operand:SI 0 "s_register_operand" "=r")
5137 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5139 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5140 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5141 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5142 "str%?\\t%5, [%0, %3%S2]!"
5143 [(set_attr "type" "store1")])
5145 (define_insn "*strsi_shiftpredec"
5146 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5147 (match_operator:SI 2 "shift_operator"
5148 [(match_operand:SI 3 "s_register_operand" "r")
5149 (match_operand:SI 4 "const_shift_operand" "n")])))
5150 (match_operand:SI 5 "s_register_operand" "r"))
5151 (set (match_operand:SI 0 "s_register_operand" "=r")
5152 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5154 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5155 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5156 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5157 "str%?\\t%5, [%0, -%3%S2]!"
5158 [(set_attr "type" "store1")])
5160 (define_insn "*loadqi_shiftpreinc"
5161 [(set (match_operand:SI 5 "s_register_operand" "=r")
5162 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5163 [(match_operand:SI 3 "s_register_operand" "r")
5164 (match_operand:SI 4 "const_shift_operand" "n")])
5165 (match_operand:SI 1 "s_register_operand" "0"))))
5166 (set (match_operand:SI 0 "s_register_operand" "=r")
5167 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5169 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5170 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5171 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5172 "ldr%?\\t%5, [%0, %3%S2]!"
5173 [(set_attr "type" "load")])
5175 (define_insn "*loadqi_shiftpredec"
5176 [(set (match_operand:SI 5 "s_register_operand" "=r")
5177 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5178 (match_operator:SI 2 "shift_operator"
5179 [(match_operand:SI 3 "s_register_operand" "r")
5180 (match_operand:SI 4 "const_shift_operand" "n")]))))
5181 (set (match_operand:SI 0 "s_register_operand" "=r")
5182 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5184 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5185 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5186 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5187 "ldr%?\\t%5, [%0, -%3%S2]!"
5188 [(set_attr "type" "load")])
5190 (define_insn "*loadhi_shiftpreinc"
5191 [(set (match_operand:HI 5 "s_register_operand" "=r")
5192 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5193 [(match_operand:SI 3 "s_register_operand" "r")
5194 (match_operand:SI 4 "const_shift_operand" "n")])
5195 (match_operand:SI 1 "s_register_operand" "0"))))
5196 (set (match_operand:SI 0 "s_register_operand" "=r")
5197 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5199 "(! BYTES_BIG_ENDIAN)
5200 && ! TARGET_SHORT_BY_BYTES
5201 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5202 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5203 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5204 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
5205 [(set_attr "type" "load")])
5207 (define_insn "*loadhi_shiftpredec"
5208 [(set (match_operand:HI 5 "s_register_operand" "=r")
5209 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5210 (match_operator:SI 2 "shift_operator"
5211 [(match_operand:SI 3 "s_register_operand" "r")
5212 (match_operand:SI 4 "const_shift_operand" "n")]))))
5213 (set (match_operand:SI 0 "s_register_operand" "=r")
5214 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5216 "(! BYTES_BIG_ENDIAN)
5217 && ! TARGET_SHORT_BY_BYTES
5218 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5219 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5220 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5221 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
5222 [(set_attr "type" "load")])
5224 ; It can also support extended post-inc expressions, but combine doesn't
5226 ; It doesn't seem worth adding peepholes for anything but the most common
5227 ; cases since, unlike combine, the increment must immediately follow the load
5228 ; for this pattern to match.
5229 ; When loading we must watch to see that the base register isn't trampled by
5230 ; the load. In such cases this isn't a post-inc expression.
5233 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5234 (match_operand:QI 2 "s_register_operand" "r"))
5236 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5238 "str%?b\\t%2, [%0], %1")
5241 [(set (match_operand:QI 0 "s_register_operand" "=r")
5242 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5244 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5245 "REGNO(operands[0]) != REGNO(operands[1])
5246 && (GET_CODE (operands[2]) != REG
5247 || REGNO(operands[0]) != REGNO (operands[2]))"
5248 "ldr%?b\\t%0, [%1], %2")
5251 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5252 (match_operand:SI 2 "s_register_operand" "r"))
5254 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5256 "str%?\\t%2, [%0], %1")
5259 [(set (match_operand:HI 0 "s_register_operand" "=r")
5260 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5262 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5263 "(! BYTES_BIG_ENDIAN)
5264 && ! TARGET_SHORT_BY_BYTES
5265 && REGNO(operands[0]) != REGNO(operands[1])
5266 && (GET_CODE (operands[2]) != REG
5267 || REGNO(operands[0]) != REGNO (operands[2]))"
5268 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5271 [(set (match_operand:SI 0 "s_register_operand" "=r")
5272 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5274 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5275 "REGNO(operands[0]) != REGNO(operands[1])
5276 && (GET_CODE (operands[2]) != REG
5277 || REGNO(operands[0]) != REGNO (operands[2]))"
5278 "ldr%?\\t%0, [%1], %2")
5281 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5282 (match_operand:SI 1 "index_operand" "rJ")))
5283 (match_operand:QI 2 "s_register_operand" "r"))
5284 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5286 "str%?b\\t%2, [%0, %1]!")
5289 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5290 [(match_operand:SI 0 "s_register_operand" "r")
5291 (match_operand:SI 1 "const_int_operand" "n")])
5292 (match_operand:SI 2 "s_register_operand" "+r")))
5293 (match_operand:QI 3 "s_register_operand" "r"))
5294 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5297 "str%?b\\t%3, [%2, %0%S4]!")
5299 ; This pattern is never tried by combine, so do it as a peephole
5302 [(set (match_operand:SI 0 "s_register_operand" "=r")
5303 (match_operand:SI 1 "s_register_operand" "r"))
5305 (compare:CC (match_dup 1) (const_int 0)))]
5307 "sub%?s\\t%0, %1, #0"
5308 [(set_attr "conds" "set")])
5310 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5311 ; reversed, check that the memory references aren't volatile.
5314 [(set (match_operand:SI 0 "s_register_operand" "=r")
5315 (match_operand:SI 4 "memory_operand" "m"))
5316 (set (match_operand:SI 1 "s_register_operand" "=r")
5317 (match_operand:SI 5 "memory_operand" "m"))
5318 (set (match_operand:SI 2 "s_register_operand" "=r")
5319 (match_operand:SI 6 "memory_operand" "m"))
5320 (set (match_operand:SI 3 "s_register_operand" "=r")
5321 (match_operand:SI 7 "memory_operand" "m"))]
5322 "load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5324 return emit_ldm_seq (operands, 4);
5328 [(set (match_operand:SI 0 "s_register_operand" "=r")
5329 (match_operand:SI 3 "memory_operand" "m"))
5330 (set (match_operand:SI 1 "s_register_operand" "=r")
5331 (match_operand:SI 4 "memory_operand" "m"))
5332 (set (match_operand:SI 2 "s_register_operand" "=r")
5333 (match_operand:SI 5 "memory_operand" "m"))]
5334 "load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5336 return emit_ldm_seq (operands, 3);
5340 [(set (match_operand:SI 0 "s_register_operand" "=r")
5341 (match_operand:SI 2 "memory_operand" "m"))
5342 (set (match_operand:SI 1 "s_register_operand" "=r")
5343 (match_operand:SI 3 "memory_operand" "m"))]
5344 "load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5346 return emit_ldm_seq (operands, 2);
5350 [(set (match_operand:SI 4 "memory_operand" "=m")
5351 (match_operand:SI 0 "s_register_operand" "r"))
5352 (set (match_operand:SI 5 "memory_operand" "=m")
5353 (match_operand:SI 1 "s_register_operand" "r"))
5354 (set (match_operand:SI 6 "memory_operand" "=m")
5355 (match_operand:SI 2 "s_register_operand" "r"))
5356 (set (match_operand:SI 7 "memory_operand" "=m")
5357 (match_operand:SI 3 "s_register_operand" "r"))]
5358 "store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5360 return emit_stm_seq (operands, 4);
5364 [(set (match_operand:SI 3 "memory_operand" "=m")
5365 (match_operand:SI 0 "s_register_operand" "r"))
5366 (set (match_operand:SI 4 "memory_operand" "=m")
5367 (match_operand:SI 1 "s_register_operand" "r"))
5368 (set (match_operand:SI 5 "memory_operand" "=m")
5369 (match_operand:SI 2 "s_register_operand" "r"))]
5370 "store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5372 return emit_stm_seq (operands, 3);
5376 [(set (match_operand:SI 2 "memory_operand" "=m")
5377 (match_operand:SI 0 "s_register_operand" "r"))
5378 (set (match_operand:SI 3 "memory_operand" "=m")
5379 (match_operand:SI 1 "s_register_operand" "r"))]
5380 "store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5382 return emit_stm_seq (operands, 2);
5385 ;; A call followed by return can be replaced by restoring the regs and
5386 ;; jumping to the subroutine, provided we aren't passing the address of
5387 ;; any of our local variables. If we call alloca then this is unsafe
5388 ;; since restoring the frame frees the memory, which is not what we want.
5389 ;; Sometimes the return might have been targeted by the final prescan:
5390 ;; if so then emit a proper return insn as well.
5391 ;; Unfortunately, if the frame pointer is required, we don't know if the
5392 ;; current function has any implicit stack pointer adjustments that will
5393 ;; be restored by the return: we can't therefore do a tail call.
5394 ;; Another unfortunate that we can't handle is if current_function_args_size
5395 ;; is non-zero: in this case elimination of the argument pointer assumed
5396 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5400 [(parallel [(call (mem:SI (match_operand:SI 0 "" "X"))
5401 (match_operand:SI 1 "general_operand" "g"))
5402 (clobber (reg:SI 14))])
5404 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5405 && !get_frame_size () && !current_function_calls_alloca
5406 && !frame_pointer_needed && !current_function_args_size)"
5409 extern rtx arm_target_insn;
5410 extern int arm_ccfsm_state;
5412 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5414 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5415 output_return_instruction (NULL, TRUE, FALSE);
5416 arm_ccfsm_state = 0;
5417 arm_target_insn = NULL;
5420 output_return_instruction (NULL, FALSE, FALSE);
5421 return \"b%?\\t%a0\";
5423 [(set_attr "type" "call")
5424 (set_attr "length" "8")])
5427 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5428 (call (mem:SI (match_operand:SI 1 "" "X"))
5429 (match_operand:SI 2 "general_operand" "g")))
5430 (clobber (reg:SI 14))])
5432 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5433 && !get_frame_size () && !current_function_calls_alloca
5434 && !frame_pointer_needed && !current_function_args_size)"
5437 extern rtx arm_target_insn;
5438 extern int arm_ccfsm_state;
5440 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5442 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5443 output_return_instruction (NULL, TRUE, FALSE);
5444 arm_ccfsm_state = 0;
5445 arm_target_insn = NULL;
5448 output_return_instruction (NULL, FALSE, FALSE);
5449 return \"b%?\\t%a1\";
5451 [(set_attr "type" "call")
5452 (set_attr "length" "8")])
5454 ;; As above but when this function is not void, we must be returning the
5455 ;; result of the called subroutine.
5458 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5459 (call (mem:SI (match_operand:SI 1 "" "X"))
5460 (match_operand:SI 2 "general_operand" "g")))
5461 (clobber (reg:SI 14))])
5464 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5465 && !get_frame_size () && !current_function_calls_alloca
5466 && !frame_pointer_needed && !current_function_args_size)"
5469 extern rtx arm_target_insn;
5470 extern int arm_ccfsm_state;
5472 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5474 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5475 output_return_instruction (NULL, TRUE, FALSE);
5476 arm_ccfsm_state = 0;
5477 arm_target_insn = NULL;
5480 output_return_instruction (NULL, FALSE, FALSE);
5481 return \"b%?\\t%a1\";
5483 [(set_attr "type" "call")
5484 (set_attr "length" "8")])
5486 ;; If calling a subroutine and then jumping back to somewhere else, but not
5487 ;; too far away, then we can set the link register with the branch address
5488 ;; and jump direct to the subroutine. On return from the subroutine
5489 ;; execution continues at the branch; this avoids a prefetch stall.
5490 ;; We use the length attribute (via short_branch ()) to establish whether or
5491 ;; not this is possible, this is the same as the sparc does.
5494 [(parallel[(call (mem:SI (match_operand:SI 0 "" "X"))
5495 (match_operand:SI 1 "general_operand" "g"))
5496 (clobber (reg:SI 14))])
5498 (label_ref (match_operand 2 "" "")))]
5499 "0 && GET_CODE (operands[0]) == SYMBOL_REF
5500 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
5501 && arm_insn_not_targeted (insn)"
5504 int backward = arm_backwards_branch (INSN_UID (insn),
5505 INSN_UID (operands[2]));
5508 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5509 * above, leaving it out means that the code will still run on an arm 2 or 3
5514 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
5516 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
5521 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5523 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
5525 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
5527 return \"b%?\\t%a0\";
5529 [(set_attr "type" "call")
5530 (set (attr "length")
5531 (if_then_else (eq_attr "prog_mode" "prog32")
5536 [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
5537 (call (mem:SI (match_operand:SI 1 "" "X"))
5538 (match_operand:SI 2 "general_operand" "g")))
5539 (clobber (reg:SI 14))])
5541 (label_ref (match_operand 3 "" "")))]
5542 "0 && GET_CODE (operands[0]) == SYMBOL_REF
5543 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
5544 && arm_insn_not_targeted (insn)"
5547 int backward = arm_backwards_branch (INSN_UID (insn),
5548 INSN_UID (operands[3]));
5551 /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
5552 * above, leaving it out means that the code will still run on an arm 2 or 3
5557 output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
5559 output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
5564 output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
5566 output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
5568 output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
5570 return \"b%?\\t%a1\";
5572 [(set_attr "type" "call")
5573 (set (attr "length")
5574 (if_then_else (eq_attr "prog_mode" "prog32")
5579 [(set (match_operand:SI 0 "s_register_operand" "")
5580 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5582 (neg:SI (match_operator:SI 2 "comparison_operator"
5583 [(match_operand:SI 3 "s_register_operand" "")
5584 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5585 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5587 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5588 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5592 ;; This split can be used because CC_Z mode implies that the following
5593 ;; branch will be an equality, or an unsigned inequality, so the sign
5594 ;; extension is not needed.
5599 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
5601 (match_operand 1 "const_int_operand" "")))
5602 (clobber (match_scratch:SI 2 ""))]
5603 "((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
5604 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24"
5605 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
5606 (set (reg:CC 24) (compare:CC (match_dup 2) (match_dup 1)))]
5608 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5611 (define_expand "prologue"
5612 [(clobber (const_int 0))]
5615 arm_expand_prologue ();
5619 ;; This split is only used during output to reduce the number of patterns
5620 ;; that need assembler instructions adding to them. We allowed the setting
5621 ;; of the conditions to be implicit during rtl generation so that
5622 ;; the conditional compare patterns would work. However this conflicts to
5623 ;; some extend with the conditional data operations, so we have to split them
5627 [(set (match_operand:SI 0 "s_register_operand" "")
5628 (if_then_else:SI (match_operator 1 "comparison_operator"
5629 [(match_operand 2 "" "") (match_operand 3 "" "")])
5630 (match_operand 4 "" "")
5631 (match_operand 5 "" "")))
5634 [(set (match_dup 6) (match_dup 7))
5636 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5641 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5644 operands[6] = gen_rtx (REG, mode, 24);
5645 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5650 (define_insn "*cond_move_not"
5651 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5652 (if_then_else:SI (match_operator 4 "comparison_operator"
5653 [(match_operand 3 "cc_register" "") (const_int 0)])
5654 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5656 (match_operand:SI 2 "s_register_operand" "r,r"))))]
5660 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
5661 [(set_attr "conds" "use")
5662 (set_attr "length" "4,8")])
5664 ;; The next two patterns occur when an AND operation is followed by a
5665 ;; scc insn sequence
5667 (define_insn "*sign_extract_onebit"
5668 [(set (match_operand:SI 0 "s_register_operand" "=r")
5669 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5671 (match_operand:SI 2 "const_int_operand" "n")))]
5674 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5675 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5676 return \"mvnne\\t%0, #0\";
5678 [(set_attr "conds" "clob")
5679 (set_attr "length" "8")])
5681 (define_insn "*not_signextract_onebit"
5682 [(set (match_operand:SI 0 "s_register_operand" "=r")
5684 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5686 (match_operand:SI 2 "const_int_operand" "n"))))]
5689 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5690 output_asm_insn (\"tst\\t%1, %2\", operands);
5691 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5692 return \"movne\\t%0, #0\";
5694 [(set_attr "conds" "clob")
5695 (set_attr "length" "12")])
5697 ;; Push multiple registers to the stack. The first register is in the
5698 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5700 (define_insn "*push_multi"
5701 [(match_parallel 2 "multi_register_push"
5702 [(set (match_operand:BLK 0 "memory_operand" "=m")
5703 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5709 extern int lr_save_eliminated;
5711 if (lr_save_eliminated)
5713 if (XVECLEN (operands[2], 0) > 1)
5717 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
5718 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5720 strcat (pattern, \", %|\");
5721 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5724 strcat (pattern, \"}\");
5725 output_asm_insn (pattern, operands);
5728 [(set_attr "type" "store4")])
5730 ;; Special patterns for dealing with the constant pool
5732 (define_insn "consttable_4"
5733 [(unspec_volatile [(match_operand 0 "" "")] 2)]
5737 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
5741 union real_extract u;
5742 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
5743 assemble_real (u.d, GET_MODE (operands[0]));
5747 assemble_integer (operands[0], 4, 1);
5752 [(set_attr "length" "4")])
5754 (define_insn "consttable_8"
5755 [(unspec_volatile [(match_operand 0 "" "")] 3)]
5759 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
5763 union real_extract u;
5764 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
5765 assemble_real (u.d, GET_MODE (operands[0]));
5769 assemble_integer (operands[0], 8, 1);
5774 [(set_attr "length" "8")])
5776 (define_insn "consttable_end"
5777 [(unspec_volatile [(const_int 0)] 4)]
5780 /* Nothing to do (currently). */
5784 (define_insn "align_4"
5785 [(unspec_volatile [(const_int 0)] 5)]
5788 assemble_align (32);