1 ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
2 ;; Copyright (C) 1991, 93, 94, 95, 96, 1997 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.
39 ;; Note: sin and cos are no-longer used.
43 ; PROG_MODE attribute is used to determine whether condition codes are
44 ; clobbered by a call insn: they are if in prog32 mode. This is controlled
45 ; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
46 (define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
48 ; CPU attribute is used to determine whether condition codes are clobbered
49 ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
50 ; arm2 and arm3 the condition codes are restored by the return.
52 (define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,st_arm"
53 (const (symbol_ref "arm_cpu_attr")))
55 ; Floating Point Unit. If we only have floating point emulation, then there
56 ; is no point in scheduling the floating point insns. (Well, for best
57 ; performance we should try and group them together).
59 (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
61 ; LENGTH of an instruction (in bytes)
62 (define_attr "length" "" (const_int 4))
64 ; An assembler sequence may clobber the condition codes without us knowing
65 (define_asm_attributes
66 [(set_attr "conds" "clob")
67 (set_attr "length" "4")])
69 ; TYPE attribute is used to detect floating point instructions which, if
70 ; running on a co-processor can run in parallel with other, basic instructions
71 ; If write-buffer scheduling is enabled then it can also be used in the
72 ; scheduling of writes.
74 ; Classification of each insn
75 ; normal any data instruction that doesn't hit memory or fp regs
76 ; mult a multiply instruction
77 ; block blockage insn, this blocks all functional units
78 ; float a floating point arithmetic operation (subject to expansion)
79 ; fdivx XFmode floating point division
80 ; fdivd DFmode floating point division
81 ; fdivs SFmode floating point division
82 ; fmul Floating point multiply
83 ; ffmul Fast floating point multiply
84 ; farith Floating point arithmetic (4 cycle)
85 ; ffarith Fast floating point arithmetic (2 cycle)
86 ; float_em a floating point arithmetic operation that is normally emulated
87 ; even on a machine with an fpa.
88 ; f_load a floating point load from memory
89 ; f_store a floating point store to memory
90 ; f_mem_r a transfer of a floating point register to a real reg via mem
91 ; r_mem_f the reverse of f_mem_r
92 ; f_2_r fast transfer float to arm (no memory needed)
93 ; r_2_f fast transfer arm to float
94 ; call a subroutine call
95 ; load any load from memory
96 ; store1 store 1 word to memory from arm registers
97 ; store2 store 2 words
98 ; store3 store 3 words
99 ; store4 store 4 words
102 "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"
103 (const_string "normal"))
105 ; Load scheduling, set from the cpu characteristic
106 (define_attr "ldsched" "no,yes"
107 (if_then_else (eq_attr "cpu" "arm8,st_arm")
109 (const_string "no")))
111 ; condition codes: this one is used by final_prescan_insn to speed up
112 ; conditionalizing instructions. It saves having to scan the rtl to see if
113 ; it uses or alters the condition codes.
115 ; USE means that the condition codes are used by the insn in the process of
116 ; outputting code, this means (at present) that we can't use the insn in
119 ; SET means that the purpose of the insn is to set the condition codes in a
120 ; well defined manner.
122 ; CLOB means that the condition codes are altered in an undefined manner, if
123 ; they are altered at all
125 ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
126 ; but are if the branch wasn't taken; the effect is to limit the branch
127 ; elimination scanning.
129 ; NOCOND means that the condition codes are neither altered nor affect the
130 ; output of this insn
132 (define_attr "conds" "use,set,clob,jump_clob,nocond"
133 (if_then_else (eq_attr "type" "call")
134 (if_then_else (eq_attr "prog_mode" "prog32")
135 (const_string "clob") (const_string "nocond"))
136 (const_string "nocond")))
138 (define_attr "write_conflict" "no,yes"
139 (if_then_else (eq_attr "type"
140 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
142 (const_string "no")))
144 (define_attr "core_cycles" "single,multi"
145 (if_then_else (eq_attr "type"
146 "normal,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
147 (const_string "single")
148 (const_string "multi")))
150 ; The write buffer on some of the arm6 processors is hard to model exactly.
151 ; There is room in the buffer for up to two addresses and up to eight words
152 ; of memory, but the two needn't be split evenly. When writing the two
153 ; addresses are fully pipelined. However, a read from memory that is not
154 ; currently in the cache will block until the writes have completed.
155 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
156 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
157 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
158 ; cycle to add as well.
160 ;; (define_function_unit {name} {num-units} {n-users} {test}
161 ;; {ready-delay} {issue-delay} [{conflict-list}])
162 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
163 (eq_attr "type" "fdivx")) 71 69)
165 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
166 (eq_attr "type" "fdivd")) 59 57)
168 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
169 (eq_attr "type" "fdivs")) 31 29)
171 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
172 (eq_attr "type" "fmul")) 9 7)
174 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
175 (eq_attr "type" "ffmul")) 6 4)
177 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
178 (eq_attr "type" "farith")) 4 2)
180 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
181 (eq_attr "type" "ffarith")) 2 2)
183 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
184 (eq_attr "type" "r_2_f")) 5 3)
186 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
187 (eq_attr "type" "f_2_r")) 1 2)
189 ;; The fpa10 doesn't really have a memory read unit, but it can start to
190 ;; speculatively execute the instruction in the pipeline, provided the data
191 ;; is already loaded, so pretend reads have a delay of 2 (and that the
192 ;; pipeline is infinite.
194 (define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
195 (eq_attr "type" "f_load")) 3 1)
197 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 5 3)
198 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 7 4)
199 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 9 5)
200 (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 11 6)
201 (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 5 3)
203 ;; The write_blockage unit models (partially), the fact that writes will stall
204 ;; until the write buffer empties.
206 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store1") 5 5
207 [(eq_attr "write_conflict" "yes")])
208 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store2") 7 7
209 [(eq_attr "write_conflict" "yes")])
210 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store3") 9 9
211 [(eq_attr "write_conflict" "yes")])
212 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "store4") 11 11
213 [(eq_attr "write_conflict" "yes")])
214 (define_function_unit "write_blockage" 1 0 (eq_attr "type" "r_mem_f") 5 5
215 [(eq_attr "write_conflict" "yes")])
216 (define_function_unit "write_blockage" 1 0
217 (eq_attr "write_conflict" "yes") 1 1)
221 (define_function_unit "core" 1 1 (eq_attr "core_cycles" "single") 1 1)
223 (define_function_unit "core" 1 1
224 (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 1 1)
226 (define_function_unit "core" 1 1
227 (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load")) 2 2)
229 (define_function_unit "core" 1 1 (eq_attr "type" "mult") 16 16)
231 (define_function_unit "core" 1 1
232 (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
234 (define_function_unit "core" 1 1
235 (and (eq_attr "ldsched" "!yes") (eq_attr "type" "store1")) 2 2)
237 (define_function_unit "core" 1 1 (eq_attr "type" "store2") 3 3)
239 (define_function_unit "core" 1 1 (eq_attr "type" "store3") 4 4)
241 (define_function_unit "core" 1 1 (eq_attr "type" "store4") 5 5)
243 (define_function_unit "core" 1 1
244 (and (eq_attr "core_cycles" "multi")
245 (eq_attr "type" "!mult,load,store2,store3,store4")) 32 32)
247 (define_function_unit "loader" 1 0
248 (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
251 ;; Note: For DImode insns, there is normally no reason why operands should
252 ;; not be in the same register, what we don't want is for something being
253 ;; written to partially overlap something that is an input.
257 (define_insn "adddi3"
258 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
259 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
260 (match_operand:DI 2 "s_register_operand" "r,0")))
261 (clobber (reg:CC 24))]
263 "adds\\t%Q0, %Q1, %Q2\;adc\\t%R0, %R1, %R2"
264 [(set_attr "conds" "clob")
265 (set_attr "length" "8")])
267 (define_insn "*adddi_sesidi_di"
268 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
269 (plus:DI (sign_extend:DI
270 (match_operand:SI 2 "s_register_operand" "r,r"))
271 (match_operand:DI 1 "s_register_operand" "r,0")))
272 (clobber (reg:CC 24))]
274 "adds\\t%Q0, %Q1, %2\;adc\\t%R0, %R1, %2, asr #31"
275 [(set_attr "conds" "clob")
276 (set_attr "length" "8")])
278 (define_insn "*adddi_zesidi_di"
279 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
280 (plus:DI (zero_extend:DI
281 (match_operand:SI 2 "s_register_operand" "r,r"))
282 (match_operand:DI 1 "s_register_operand" "r,0")))
283 (clobber (reg:CC 24))]
285 "adds\\t%Q0, %Q1, %2\;adc\\t%R0, %R1, #0"
286 [(set_attr "conds" "clob")
287 (set_attr "length" "8")])
289 (define_expand "addsi3"
290 [(set (match_operand:SI 0 "s_register_operand" "")
291 (plus:SI (match_operand:SI 1 "s_register_operand" "")
292 (match_operand:SI 2 "reg_or_int_operand" "")))]
295 if (GET_CODE (operands[2]) == CONST_INT)
297 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
299 (reload_in_progress || reload_completed ? 0
300 : preserve_subexpressions_p ()));
306 [(set (match_operand:SI 0 "s_register_operand" "")
307 (plus:SI (match_operand:SI 1 "s_register_operand" "")
308 (match_operand:SI 2 "const_int_operand" "")))]
309 "! (const_ok_for_arm (INTVAL (operands[2]))
310 || const_ok_for_arm (-INTVAL (operands[2])))"
311 [(clobber (const_int 0))]
313 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
318 (define_insn "*addsi3_insn"
319 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
320 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
321 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
327 [(set_attr "length" "4,4,16")])
329 (define_insn "*addsi3_compare0"
330 [(set (reg:CC_NOOV 24)
332 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
333 (match_operand:SI 2 "arm_add_operand" "rI,L"))
335 (set (match_operand:SI 0 "s_register_operand" "=r,r")
336 (plus:SI (match_dup 1) (match_dup 2)))]
340 sub%?s\\t%0, %1, #%n2"
341 [(set_attr "conds" "set")])
343 (define_insn "*addsi3_compare0_scratch"
344 [(set (reg:CC_NOOV 24)
346 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
347 (match_operand:SI 1 "arm_add_operand" "rI,L"))
353 [(set_attr "conds" "set")])
355 ;; The next four insns work because they compare the result with one of
356 ;; the operands, and we know that the use of the condition code is
357 ;; either GEU or LTU, so we can use the carry flag from the addition
358 ;; instead of doing the compare a second time.
359 (define_insn "*addsi3_compare_op1"
362 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
363 (match_operand:SI 2 "arm_add_operand" "rI,L"))
365 (set (match_operand:SI 0 "s_register_operand" "=r,r")
366 (plus:SI (match_dup 1) (match_dup 2)))]
370 sub%?s\\t%0, %1, #%n2"
371 [(set_attr "conds" "set")])
373 (define_insn "*addsi3_compare_op2"
376 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
377 (match_operand:SI 2 "arm_add_operand" "rI,L"))
379 (set (match_operand:SI 0 "s_register_operand" "=r,r")
380 (plus:SI (match_dup 1) (match_dup 2)))]
384 sub%?s\\t%0, %1, #%n2"
385 [(set_attr "conds" "set")])
387 (define_insn "*compare_addsi2_op0"
390 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
391 (match_operand:SI 1 "arm_add_operand" "rI,L"))
397 [(set_attr "conds" "set")])
399 (define_insn "*compare_addsi2_op1"
402 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
403 (match_operand:SI 1 "arm_add_operand" "rI,L"))
409 [(set_attr "conds" "set")])
411 (define_insn "*addsi3_carryin"
412 [(set (match_operand:SI 0 "s_register_operand" "=r")
413 (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
414 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
415 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
418 [(set_attr "conds" "use")])
420 (define_insn "*addsi3_carryin_alt1"
421 [(set (match_operand:SI 0 "s_register_operand" "=r")
422 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
423 (match_operand:SI 2 "arm_rhs_operand" "rI"))
424 (ltu:SI (reg:CC_C 24) (const_int 0))))]
427 [(set_attr "conds" "use")])
429 (define_insn "*addsi3_carryin_alt2"
430 [(set (match_operand:SI 0 "s_register_operand" "=r")
431 (plus:SI (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
432 (match_operand:SI 1 "s_register_operand" "r"))
433 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
436 [(set_attr "conds" "use")])
438 (define_insn "*addsi3_carryin_alt3"
439 [(set (match_operand:SI 0 "s_register_operand" "=r")
440 (plus:SI (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
441 (match_operand:SI 2 "arm_rhs_operand" "rI"))
442 (match_operand:SI 1 "s_register_operand" "r")))]
445 [(set_attr "conds" "use")])
447 (define_insn "incscc"
448 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
449 (plus:SI (match_operator:SI 2 "comparison_operator"
450 [(match_operand 3 "cc_register" "") (const_int 0)])
451 (match_operand:SI 1 "s_register_operand" "0,?r")))]
455 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
456 [(set_attr "conds" "use")
457 (set_attr "length" "4,8")])
459 ; If a constant is too big to fit in a single instruction then the constant
460 ; will be pre-loaded into a register taking at least two insns, we might be
461 ; able to merge it with an add, but it depends on the exact value.
464 [(set (match_operand:SI 0 "s_register_operand" "=r")
465 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
466 (match_operand:SI 2 "const_int_operand" "n")))]
467 "!(const_ok_for_arm (INTVAL (operands[2]))
468 || const_ok_for_arm (-INTVAL (operands[2])))"
469 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
470 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
473 unsigned int val = (unsigned) INTVAL (operands[2]);
477 /* this code is similar to the approach followed in movsi, but it must
478 generate exactly two insns */
480 for (i = 30; i >= 0; i -= 2)
486 if (const_ok_for_arm (temp = (val & ~(255 << i))))
491 /* we might be able to do this as (larger number - small number) */
492 temp = ((val >> i) & 255) + 1;
493 if (temp > 255 && i < 24)
496 temp = ((val >> i) & 255) + 1;
498 if (const_ok_for_arm ((temp << i) - val))
501 temp = (unsigned) - (int) (i - val);
508 /* if we got here, we have found a way of doing it in two instructions.
509 the two constants are in val and temp */
510 operands[2] = GEN_INT ((int)val);
511 operands[3] = GEN_INT ((int)temp);
515 (define_insn "addsf3"
516 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
517 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
518 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
522 suf%?s\\t%0, %1, #%N2"
523 [(set_attr "type" "farith")])
525 (define_insn "adddf3"
526 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
527 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
528 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
532 suf%?d\\t%0, %1, #%N2"
533 [(set_attr "type" "farith")])
535 (define_insn "*adddf_df_esfdf"
536 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
537 (plus:DF (float_extend:DF
538 (match_operand:SF 1 "s_register_operand" "f,f"))
539 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
543 suf%?d\\t%0, %1, #%N2"
544 [(set_attr "type" "farith")])
546 (define_insn "*adddf_df_esfdf"
547 [(set (match_operand:DF 0 "s_register_operand" "=f")
548 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
550 (match_operand:SF 2 "s_register_operand" "f"))))]
552 "adf%?d\\t%0, %1, %2"
553 [(set_attr "type" "farith")])
555 (define_insn "*adddf_esfdf_esfdf"
556 [(set (match_operand:DF 0 "s_register_operand" "=f")
557 (plus:DF (float_extend:DF
558 (match_operand:SF 1 "s_register_operand" "f"))
560 (match_operand:SF 2 "s_register_operand" "f"))))]
562 "adf%?d\\t%0, %1, %2"
563 [(set_attr "type" "farith")])
565 (define_insn "addxf3"
566 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
567 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
568 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
569 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
572 suf%?e\\t%0, %1, #%N2"
573 [(set_attr "type" "farith")])
575 (define_insn "subdi3"
576 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
577 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
578 (match_operand:DI 2 "s_register_operand" "r,0,0")))
579 (clobber (reg:CC 24))]
581 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
582 [(set_attr "conds" "clob")
583 (set_attr "length" "8")])
585 (define_insn "*subdi_di_zesidi"
586 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
587 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
589 (match_operand:SI 2 "s_register_operand" "r,r"))))
590 (clobber (reg:CC 24))]
592 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
593 [(set_attr "conds" "clob")
594 (set_attr "length" "8")])
596 (define_insn "*subdi_di_sesidi"
597 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
598 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
600 (match_operand:SI 2 "s_register_operand" "r,r"))))
601 (clobber (reg:CC 24))]
603 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
604 [(set_attr "conds" "clob")
605 (set_attr "length" "8")])
607 (define_insn "*subdi_zesidi_di"
608 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
609 (minus:DI (zero_extend:DI
610 (match_operand:SI 2 "s_register_operand" "r,r"))
611 (match_operand:DI 1 "s_register_operand" "?r,0")))
612 (clobber (reg:CC 24))]
614 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
615 [(set_attr "conds" "clob")
616 (set_attr "length" "8")])
618 (define_insn "*subdi_sesidi_di"
619 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
620 (minus:DI (sign_extend:DI
621 (match_operand:SI 2 "s_register_operand" "r,r"))
622 (match_operand:DI 1 "s_register_operand" "?r,0")))
623 (clobber (reg:CC 24))]
625 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
626 [(set_attr "conds" "clob")
627 (set_attr "length" "8")])
629 (define_insn "*subdi_zesidi_zesidi"
630 [(set (match_operand:DI 0 "s_register_operand" "=r")
631 (minus:DI (zero_extend:DI
632 (match_operand:SI 1 "s_register_operand" "r"))
634 (match_operand:SI 2 "s_register_operand" "r"))))
635 (clobber (reg:CC 24))]
637 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
638 [(set_attr "conds" "clob")
639 (set_attr "length" "8")])
641 (define_expand "subsi3"
642 [(set (match_operand:SI 0 "s_register_operand" "")
643 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
644 (match_operand:SI 2 "s_register_operand" "")))]
647 if (GET_CODE (operands[1]) == CONST_INT)
649 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
651 (reload_in_progress || reload_completed ? 0
652 : preserve_subexpressions_p ()));
657 (define_insn "*subsi3_insn"
658 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
659 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
660 (match_operand:SI 2 "s_register_operand" "r,r")))]
665 [(set_attr "length" "4,16")])
668 [(set (match_operand:SI 0 "s_register_operand" "")
669 (minus:SI (match_operand:SI 1 "const_int_operand" "")
670 (match_operand:SI 2 "s_register_operand" "")))]
671 "! const_ok_for_arm (INTVAL (operands[1]))"
672 [(clobber (const_int 0))]
674 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
679 (define_insn "*subsi3_compare0"
680 [(set (reg:CC_NOOV 24)
681 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
682 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
684 (set (match_operand:SI 0 "s_register_operand" "=r,r")
685 (minus:SI (match_dup 1) (match_dup 2)))]
690 [(set_attr "conds" "set")])
692 (define_insn "decscc"
693 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
694 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
695 (match_operator:SI 2 "comparison_operator"
696 [(match_operand 3 "cc_register" "") (const_int 0)])))]
700 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
701 [(set_attr "conds" "use")
702 (set_attr "length" "*,8")])
704 (define_insn "subsf3"
705 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
706 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
707 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
712 [(set_attr "type" "farith")])
714 (define_insn "subdf3"
715 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
716 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
717 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
722 [(set_attr "type" "farith")])
724 (define_insn "*subdf_esfdf_df"
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"))
728 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
730 "suf%?d\\t%0, %1, %2"
731 [(set_attr "type" "farith")])
733 (define_insn "*subdf_df_esfdf"
734 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
735 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
737 (match_operand:SF 2 "s_register_operand" "f,f"))))]
742 [(set_attr "type" "farith")])
744 (define_insn "*subdf_esfdf_esfdf"
745 [(set (match_operand:DF 0 "s_register_operand" "=f")
746 (minus:DF (float_extend:DF
747 (match_operand:SF 1 "s_register_operand" "f"))
749 (match_operand:SF 2 "s_register_operand" "f"))))]
751 "suf%?d\\t%0, %1, %2"
752 [(set_attr "type" "farith")])
754 (define_insn "subxf3"
755 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
756 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
757 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
758 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
762 [(set_attr "type" "farith")])
764 ;; Multiplication insns
766 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
767 (define_insn "mulsi3"
768 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
769 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
770 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
773 [(set_attr "type" "mult")])
775 (define_insn "*mulsi3_compare0"
776 [(set (reg:CC_NOOV 24)
777 (compare:CC_NOOV (mult:SI
778 (match_operand:SI 2 "s_register_operand" "r,r")
779 (match_operand:SI 1 "s_register_operand" "%?r,0"))
781 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
782 (mult:SI (match_dup 2) (match_dup 1)))]
784 "mul%?s\\t%0, %2, %1"
785 [(set_attr "conds" "set")
786 (set_attr "type" "mult")])
788 (define_insn "*mulsi_compare0_scratch"
789 [(set (reg:CC_NOOV 24)
790 (compare:CC_NOOV (mult:SI
791 (match_operand:SI 2 "s_register_operand" "r,r")
792 (match_operand:SI 1 "s_register_operand" "%?r,0"))
794 (clobber (match_scratch:SI 0 "=&r,&r"))]
796 "mul%?s\\t%0, %2, %1"
797 [(set_attr "conds" "set")
798 (set_attr "type" "mult")])
800 ;; Unnamed templates to match MLA instruction.
802 (define_insn "*mulsi3addsi"
803 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
805 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
806 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
807 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
809 "mla%?\\t%0, %2, %1, %3"
810 [(set_attr "type" "mult")])
812 (define_insn "*mulsi3addsi_compare0"
813 [(set (reg:CC_NOOV 24)
814 (compare:CC_NOOV (plus:SI
816 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
817 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
818 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
820 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
821 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
824 "mla%?s\\t%0, %2, %1, %3"
825 [(set_attr "conds" "set")
826 (set_attr "type" "mult")])
828 (define_insn "*mulsi3addsi_compare0_scratch"
829 [(set (reg:CC_NOOV 24)
830 (compare:CC_NOOV (plus:SI
832 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
833 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
834 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
836 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
838 "mla%?s\\t%0, %2, %1, %3"
839 [(set_attr "conds" "set")
840 (set_attr "type" "mult")])
842 (define_insn "mulsidi3"
843 [(set (match_operand:DI 0 "s_register_operand" "=&r")
844 (mult:DI (sign_extend:DI
845 (match_operand:SI 1 "s_register_operand" "%r"))
847 (match_operand:SI 2 "s_register_operand" "r"))))]
849 "smull%?\\t%Q0, %R0, %1, %2"
850 [(set_attr "type" "mult")])
852 (define_insn "umulsidi3"
853 [(set (match_operand:DI 0 "s_register_operand" "=&r")
854 (mult:DI (zero_extend:DI
855 (match_operand:SI 1 "s_register_operand" "%r"))
857 (match_operand:SI 2 "s_register_operand" "r"))))]
859 "umull%?\\t%Q0, %R0, %1, %2"
860 [(set_attr "type" "mult")])
862 (define_insn "mulsf3"
863 [(set (match_operand:SF 0 "s_register_operand" "=f")
864 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
865 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
867 "fml%?s\\t%0, %1, %2"
868 [(set_attr "type" "ffmul")])
870 (define_insn "muldf3"
871 [(set (match_operand:DF 0 "s_register_operand" "=f")
872 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
873 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
875 "muf%?d\\t%0, %1, %2"
876 [(set_attr "type" "fmul")])
878 (define_insn "*muldf_esfdf_df"
879 [(set (match_operand:DF 0 "s_register_operand" "=f")
880 (mult:DF (float_extend:DF
881 (match_operand:SF 1 "s_register_operand" "f"))
882 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
884 "muf%?d\\t%0, %1, %2"
885 [(set_attr "type" "fmul")])
887 (define_insn "*muldf_df_esfdf"
888 [(set (match_operand:DF 0 "s_register_operand" "=f")
889 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
891 (match_operand:SF 2 "s_register_operand" "f"))))]
893 "muf%?d\\t%0, %1, %2"
894 [(set_attr "type" "fmul")])
896 (define_insn "*muldf_esfdf_esfdf"
897 [(set (match_operand:DF 0 "s_register_operand" "=f")
898 (mult:DF (float_extend:DF
899 (match_operand:SF 1 "s_register_operand" "f"))
901 (match_operand:SF 2 "s_register_operand" "f"))))]
903 "muf%?d\\t%0, %1, %2"
904 [(set_attr "type" "fmul")])
906 (define_insn "mulxf3"
907 [(set (match_operand:XF 0 "s_register_operand" "=f")
908 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
909 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
910 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
911 "muf%?e\\t%0, %1, %2"
912 [(set_attr "type" "fmul")])
916 (define_insn "divsf3"
917 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
918 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
919 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
924 [(set_attr "type" "fdivs")])
926 (define_insn "divdf3"
927 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
928 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
929 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
934 [(set_attr "type" "fdivd")])
936 (define_insn "*divdf_esfdf_df"
937 [(set (match_operand:DF 0 "s_register_operand" "=f")
938 (div:DF (float_extend:DF
939 (match_operand:SF 1 "s_register_operand" "f"))
940 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
942 "dvf%?d\\t%0, %1, %2"
943 [(set_attr "type" "fdivd")])
945 (define_insn "*divdf_df_esfdf"
946 [(set (match_operand:DF 0 "s_register_operand" "=f")
947 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
949 (match_operand:SF 2 "s_register_operand" "f"))))]
951 "rdf%?d\\t%0, %2, %1"
952 [(set_attr "type" "fdivd")])
954 (define_insn "*divdf_esfdf_esfdf"
955 [(set (match_operand:DF 0 "s_register_operand" "=f")
956 (div:DF (float_extend:DF
957 (match_operand:SF 1 "s_register_operand" "f"))
959 (match_operand:SF 2 "s_register_operand" "f"))))]
961 "dvf%?d\\t%0, %1, %2"
962 [(set_attr "type" "fdivd")])
964 (define_insn "divxf3"
965 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
966 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
967 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
968 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
972 [(set_attr "type" "fdivx")])
976 (define_insn "modsf3"
977 [(set (match_operand:SF 0 "s_register_operand" "=f")
978 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
979 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
981 "rmf%?s\\t%0, %1, %2"
982 [(set_attr "type" "fdivs")])
984 (define_insn "moddf3"
985 [(set (match_operand:DF 0 "s_register_operand" "=f")
986 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
987 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
989 "rmf%?d\\t%0, %1, %2"
990 [(set_attr "type" "fdivd")])
992 (define_insn "*moddf_esfdf_df"
993 [(set (match_operand:DF 0 "s_register_operand" "=f")
994 (mod:DF (float_extend:DF
995 (match_operand:SF 1 "s_register_operand" "f"))
996 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
998 "rmf%?d\\t%0, %1, %2"
999 [(set_attr "type" "fdivd")])
1001 (define_insn "*moddf_df_esfdf"
1002 [(set (match_operand:DF 0 "s_register_operand" "=f")
1003 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
1005 (match_operand:SF 2 "s_register_operand" "f"))))]
1007 "rmf%?d\\t%0, %1, %2"
1008 [(set_attr "type" "fdivd")])
1010 (define_insn "*moddf_esfdf_esfdf"
1011 [(set (match_operand:DF 0 "s_register_operand" "=f")
1012 (mod:DF (float_extend:DF
1013 (match_operand:SF 1 "s_register_operand" "f"))
1015 (match_operand:SF 2 "s_register_operand" "f"))))]
1017 "rmf%?d\\t%0, %1, %2"
1018 [(set_attr "type" "fdivd")])
1020 (define_insn "modxf3"
1021 [(set (match_operand:XF 0 "s_register_operand" "=f")
1022 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
1023 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
1024 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1025 "rmf%?e\\t%0, %1, %2"
1026 [(set_attr "type" "fdivx")])
1028 ;; Boolean and,ior,xor insns
1030 (define_insn "anddi3"
1031 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1032 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1033 (match_operand:DI 2 "s_register_operand" "r,0")))]
1035 "and%?\\t%Q0, %Q1, %Q2\;and%?\\t%R0, %R1, %R2"
1036 [(set_attr "length" "8")])
1038 (define_insn "*anddi_zesidi_di"
1039 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1040 (and:DI (zero_extend:DI
1041 (match_operand:SI 2 "s_register_operand" "r,r"))
1042 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1044 "and%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, #0"
1045 [(set_attr "length" "8")])
1047 (define_insn "*anddi_sesdi_di"
1048 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1049 (and:DI (sign_extend:DI
1050 (match_operand:SI 2 "s_register_operand" "r,r"))
1051 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1053 "and%?\\t%Q0, %Q1, %2\;and%?\\t%R0, %R1, %2, asr #31"
1054 [(set_attr "length" "8")])
1056 (define_expand "andsi3"
1057 [(set (match_operand:SI 0 "s_register_operand" "")
1058 (and:SI (match_operand:SI 1 "s_register_operand" "")
1059 (match_operand:SI 2 "reg_or_int_operand" "")))]
1062 if (GET_CODE (operands[2]) == CONST_INT)
1064 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1066 (reload_in_progress || reload_completed
1067 ? 0 : preserve_subexpressions_p ()));
1072 (define_insn "*andsi3_insn"
1073 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1074 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1075 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1079 bic%?\\t%0, %1, #%B2
1081 [(set_attr "length" "4,4,16")])
1084 [(set (match_operand:SI 0 "s_register_operand" "")
1085 (and:SI (match_operand:SI 1 "s_register_operand" "")
1086 (match_operand:SI 2 "const_int_operand" "")))]
1087 "! (const_ok_for_arm (INTVAL (operands[2]))
1088 || const_ok_for_arm (~ INTVAL (operands[2])))"
1089 [(clobber (const_int 0))]
1091 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1096 (define_insn "*andsi3_compare0"
1097 [(set (reg:CC_NOOV 24)
1099 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1100 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1102 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1103 (and:SI (match_dup 1) (match_dup 2)))]
1107 bic%?s\\t%0, %1, #%B2"
1108 [(set_attr "conds" "set")])
1110 (define_insn "*andsi3_compare0_scratch"
1111 [(set (reg:CC_NOOV 24)
1113 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1114 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1116 (clobber (match_scratch:SI 3 "=X,r"))]
1120 bic%?s\\t%3, %0, #%B1"
1121 [(set_attr "conds" "set")])
1123 (define_insn "*zeroextractsi_compare0_scratch"
1124 [(set (reg:CC_NOOV 24)
1125 (compare:CC_NOOV (zero_extract:SI
1126 (match_operand:SI 0 "s_register_operand" "r")
1127 (match_operand 1 "const_int_operand" "n")
1128 (match_operand 2 "const_int_operand" "n"))
1130 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1131 && INTVAL (operands[1]) > 0
1132 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1133 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
1136 unsigned int mask = 0;
1137 int cnt = INTVAL (operands[1]);
1140 mask = (mask << 1) | 1;
1141 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1142 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1146 [(set_attr "conds" "set")])
1148 (define_insn "*zeroextractqi_compare0_scratch"
1149 [(set (reg:CC_NOOV 24)
1150 (compare:CC_NOOV (zero_extract:SI
1151 (match_operand:QI 0 "memory_operand" "m")
1152 (match_operand 1 "const_int_operand" "n")
1153 (match_operand 2 "const_int_operand" "n"))
1155 (clobber (match_scratch:QI 3 "=r"))]
1156 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
1157 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
1160 unsigned int mask = 0;
1161 int cnt = INTVAL (operands[1]);
1164 mask = (mask << 1) | 1;
1165 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1166 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
1167 output_asm_insn (\"tst%?\\t%3, %1\", operands);
1171 [(set_attr "conds" "set")
1172 (set_attr "length" "8")])
1174 (define_expand "insv"
1175 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1176 (match_operand:SI 1 "general_operand" "")
1177 (match_operand:SI 2 "general_operand" ""))
1178 (match_operand:SI 3 "nonmemory_operand" ""))]
1182 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << INTVAL (operands[1])) - 1;
1184 if (GET_CODE (operands[3]) == CONST_INT)
1186 /* Since we are inserting a known constant, we may be able to
1187 reduce the number of bits that we have to clear so that
1188 the mask becomes simple. */
1189 rtx op1 = gen_reg_rtx (SImode);
1190 HOST_WIDE_INT mask2 = ((mask & ~INTVAL (operands[3]))
1191 << INTVAL (operands[2]));
1193 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1194 emit_insn (gen_iorsi3 (operands[0], op1,
1195 GEN_INT (INTVAL (operands[3])
1196 << INTVAL (operands[2]))));
1198 else if (INTVAL (operands[2]) == 0
1199 && ! (const_ok_for_arm (mask)
1200 || const_ok_for_arm (~mask)))
1202 /* A Trick, since we are setting the bottom bits in the word,
1203 we can shift operand[3] up, operand[0] down, OR them together
1204 and rotate the result back again. This takes 3 insns, and
1205 the third might be mergable into another op. */
1207 rtx op0 = gen_reg_rtx (SImode);
1208 rtx op1 = gen_reg_rtx (SImode);
1210 emit_insn (gen_ashlsi3 (op0, operands[3],
1211 GEN_INT (32 - INTVAL (operands[1]))));
1212 emit_insn (gen_iorsi3 (op1, gen_rtx (LSHIFTRT, SImode, operands[0],
1215 emit_insn (gen_rotlsi3 (operands[0], op1, operands[1]));
1217 else if ((INTVAL (operands[1]) + INTVAL (operands[2]) == 32)
1218 && ! (const_ok_for_arm (mask)
1219 || const_ok_for_arm (~mask)))
1221 /* Similar trick, but slightly less efficient. */
1223 rtx op0 = gen_reg_rtx (SImode);
1224 rtx op1 = gen_reg_rtx (SImode);
1226 emit_insn (gen_ashlsi3 (op0, operands[3],
1227 GEN_INT (32 - INTVAL (operands[1]))));
1228 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1229 emit_insn (gen_iorsi3 (operands[0], gen_rtx (LSHIFTRT, SImode, op1,
1230 operands[1]), op0));
1234 rtx op0 = GEN_INT (mask);
1235 rtx op1 = gen_reg_rtx (SImode);
1236 rtx op2 = gen_reg_rtx (SImode);
1238 if (! (const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1240 rtx tmp = gen_reg_rtx (SImode);
1242 emit_insn (gen_movsi (tmp, op0));
1246 emit_insn (gen_andsi3 (op1, operands[3], op0));
1248 if (GET_CODE (op0) == CONST_INT
1249 && (const_ok_for_arm (mask << INTVAL (operands[2]))
1250 || const_ok_for_arm (~ (mask << INTVAL (operands[2])))))
1252 op0 = GEN_INT (~(mask << INTVAL (operands[2])));
1253 emit_insn (gen_andsi3 (op2, operands[0], op0));
1257 if (GET_CODE (op0) == CONST_INT)
1259 rtx tmp = gen_reg_rtx (SImode);
1261 emit_insn (gen_movsi (tmp, op0));
1265 if (INTVAL (operands[2]) != 0)
1266 op0 = gen_rtx (ASHIFT, SImode, op0, operands[2]);
1267 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1270 if (INTVAL (operands[2]) != 0)
1271 op1 = gen_rtx (ASHIFT, SImode, op1, operands[2]);
1273 emit_insn (gen_iorsi3 (operands[0], op1, op2));
1280 ;; constants for op 2 will never be given to these patterns.
1281 (define_insn "*anddi_notdi_di"
1282 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1283 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
1284 (match_operand:DI 1 "s_register_operand" "0,r")))]
1286 "bic%?\\t%Q0, %Q1, %Q2\;bic%?\\t%R0, %R1, %R2"
1287 [(set_attr "length" "8")])
1289 (define_insn "*anddi_notzesidi_di"
1290 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1291 (and:DI (not:DI (zero_extend:DI
1292 (match_operand:SI 2 "s_register_operand" "r,r")))
1293 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1296 bic%?\\t%Q0, %Q1, %2
1297 bic%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1298 [(set_attr "length" "4,8")])
1300 (define_insn "*anddi_notsesidi_di"
1301 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1302 (and:DI (not:DI (sign_extend:DI
1303 (match_operand:SI 2 "s_register_operand" "r,r")))
1304 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1306 "bic%?\\t%Q0, %Q1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
1307 [(set_attr "length" "8")])
1309 (define_insn "andsi_notsi_si"
1310 [(set (match_operand:SI 0 "s_register_operand" "=r")
1311 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1312 (match_operand:SI 1 "s_register_operand" "r")))]
1314 "bic%?\\t%0, %1, %2")
1316 (define_insn "andsi_not_shiftsi_si"
1317 [(set (match_operand:SI 0 "s_register_operand" "=r")
1318 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
1319 [(match_operand:SI 2 "s_register_operand" "r")
1320 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
1321 (match_operand:SI 1 "s_register_operand" "r")))]
1323 "bic%?\\t%0, %1, %2%S4")
1325 (define_insn "*andsi_notsi_si_compare0"
1326 [(set (reg:CC_NOOV 24)
1328 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1329 (match_operand:SI 1 "s_register_operand" "r"))
1331 (set (match_operand:SI 0 "s_register_operand" "=r")
1332 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1334 "bic%?s\\t%0, %1, %2"
1335 [(set_attr "conds" "set")])
1337 (define_insn "*andsi_notsi_si_compare0_scratch"
1338 [(set (reg:CC_NOOV 24)
1340 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1341 (match_operand:SI 1 "s_register_operand" "r"))
1343 (clobber (match_scratch:SI 0 "=r"))]
1345 "bic%?s\\t%0, %1, %2"
1346 [(set_attr "conds" "set")])
1348 (define_insn "iordi3"
1349 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1350 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1351 (match_operand:DI 2 "s_register_operand" "r")))]
1353 "orr%?\\t%Q0, %Q1, %Q2\;orr%?\\t%R0, %R1, %R2"
1354 [(set_attr "length" "8")])
1356 (define_insn "*iordi_zesidi_di"
1357 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1358 (ior:DI (zero_extend:DI
1359 (match_operand:SI 2 "s_register_operand" "r,r"))
1360 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1363 orr%?\\t%Q0, %Q1, %2
1364 orr%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1365 [(set_attr "length" "4,8")])
1367 (define_insn "*iordi_sesidi_di"
1368 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1369 (ior:DI (sign_extend:DI
1370 (match_operand:SI 2 "s_register_operand" "r,r"))
1371 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1373 "orr%?\\t%Q0, %Q1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1374 [(set_attr "length" "8")])
1376 (define_expand "iorsi3"
1377 [(set (match_operand:SI 0 "s_register_operand" "")
1378 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1379 (match_operand:SI 2 "reg_or_int_operand" "")))]
1382 if (GET_CODE (operands[2]) == CONST_INT)
1384 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1386 (reload_in_progress || reload_completed
1387 ? 0 : preserve_subexpressions_p ()));
1392 (define_insn "*iorsi3_insn"
1393 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1394 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1395 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
1400 [(set_attr "length" "4,16")])
1403 [(set (match_operand:SI 0 "s_register_operand" "")
1404 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1405 (match_operand:SI 2 "const_int_operand" "")))]
1406 "! const_ok_for_arm (INTVAL (operands[2]))"
1407 [(clobber (const_int 0))]
1409 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1414 (define_insn "*iorsi3_compare0"
1415 [(set (reg:CC_NOOV 24)
1416 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1417 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1419 (set (match_operand:SI 0 "s_register_operand" "=r")
1420 (ior:SI (match_dup 1) (match_dup 2)))]
1422 "orr%?s\\t%0, %1, %2"
1423 [(set_attr "conds" "set")])
1425 (define_insn "*iorsi3_compare0_scratch"
1426 [(set (reg:CC_NOOV 24)
1427 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1428 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1430 (clobber (match_scratch:SI 0 "=r"))]
1432 "orr%?s\\t%0, %1, %2"
1433 [(set_attr "conds" "set")])
1435 (define_insn "xordi3"
1436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1437 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1438 (match_operand:DI 2 "s_register_operand" "r,0")))]
1440 "eor%?\\t%Q0, %Q1, %Q2\;eor%?\\t%R0, %R1, %R2"
1441 [(set_attr "length" "8")])
1443 (define_insn "*xordi_zesidi_di"
1444 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1445 (xor:DI (zero_extend:DI
1446 (match_operand:SI 2 "s_register_operand" "r,r"))
1447 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1450 eor%?\\t%Q0, %Q1, %2
1451 eor%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1452 [(set_attr "length" "4,8")])
1454 (define_insn "*xordi_sesidi_di"
1455 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1456 (xor:DI (sign_extend:DI
1457 (match_operand:SI 2 "s_register_operand" "r,r"))
1458 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1460 "eor%?\\t%Q0, %Q1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1461 [(set_attr "length" "8")])
1463 (define_insn "xorsi3"
1464 [(set (match_operand:SI 0 "s_register_operand" "=r")
1465 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1466 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1468 "eor%?\\t%0, %1, %2")
1470 (define_insn "*xorsi3_compare0"
1471 [(set (reg:CC_NOOV 24)
1472 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1473 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1475 (set (match_operand:SI 0 "s_register_operand" "=r")
1476 (xor:SI (match_dup 1) (match_dup 2)))]
1478 "eor%?s\\t%0, %1, %2"
1479 [(set_attr "conds" "set")])
1481 (define_insn "*xorsi3_compare0_scratch"
1482 [(set (reg:CC_NOOV 24)
1483 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1484 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1488 [(set_attr "conds" "set")])
1490 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1491 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1495 [(set (match_operand:SI 0 "s_register_operand" "=r")
1496 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1497 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1498 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1499 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1501 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1502 (not:SI (match_dup 3))))
1503 (set (match_dup 0) (not:SI (match_dup 4)))]
1507 (define_insn "*andsi_iorsi3_notsi"
1508 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1509 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1510 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1511 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1513 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1514 [(set_attr "length" "8")])
1518 ;; Minimum and maximum insns
1520 (define_insn "smaxsi3"
1521 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1522 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1523 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1524 (clobber (reg:CC 24))]
1527 cmp\\t%1, %2\;movlt\\t%0, %2
1528 cmp\\t%1, %2\;movge\\t%0, %1
1529 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1530 [(set_attr "conds" "clob")
1531 (set_attr "length" "8,8,12")])
1533 (define_insn "sminsi3"
1534 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1535 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1536 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1537 (clobber (reg:CC 24))]
1540 cmp\\t%1, %2\;movge\\t%0, %2
1541 cmp\\t%1, %2\;movlt\\t%0, %1
1542 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1543 [(set_attr "conds" "clob")
1544 (set_attr "length" "8,8,12")])
1546 (define_insn "umaxsi3"
1547 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1548 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1549 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1550 (clobber (reg:CC 24))]
1553 cmp\\t%1, %2\;movcc\\t%0, %2
1554 cmp\\t%1, %2\;movcs\\t%0, %1
1555 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1556 [(set_attr "conds" "clob")
1557 (set_attr "length" "8,8,12")])
1559 (define_insn "uminsi3"
1560 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1561 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1562 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1563 (clobber (reg:CC 24))]
1566 cmp\\t%1, %2\;movcs\\t%0, %2
1567 cmp\\t%1, %2\;movcc\\t%0, %1
1568 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1569 [(set_attr "conds" "clob")
1570 (set_attr "length" "8,8,12")])
1572 (define_insn "*store_minmaxsi"
1573 [(set (match_operand:SI 0 "memory_operand" "=m")
1574 (match_operator:SI 3 "minmax_operator"
1575 [(match_operand:SI 1 "s_register_operand" "r")
1576 (match_operand:SI 2 "s_register_operand" "r")]))
1577 (clobber (reg:CC 24))]
1580 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1582 output_asm_insn (\"cmp\\t%1, %2\", operands);
1583 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1584 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1587 [(set_attr "conds" "clob")
1588 (set_attr "length" "12")
1589 (set_attr "type" "store1")])
1591 ; Reject the frame pointer in operand[1], since reloading this after
1592 ; it has been eliminated can cause carnage.
1593 (define_insn "*minmax_arithsi"
1594 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1595 (match_operator:SI 4 "shiftable_operator"
1596 [(match_operator:SI 5 "minmax_operator"
1597 [(match_operand:SI 2 "s_register_operand" "r,r")
1598 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1599 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1600 (clobber (reg:CC 24))]
1601 "GET_CODE (operands[1]) != REG
1602 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
1603 && REGNO(operands[1]) != ARG_POINTER_REGNUM)"
1606 enum rtx_code code = GET_CODE (operands[4]);
1608 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1610 output_asm_insn (\"cmp\\t%2, %3\", operands);
1611 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1612 if (which_alternative != 0 || operands[3] != const0_rtx
1613 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1614 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1618 [(set_attr "conds" "clob")
1619 (set_attr "length" "12")])
1622 ;; Shift and rotation insns
1624 (define_expand "ashlsi3"
1625 [(set (match_operand:SI 0 "s_register_operand" "")
1626 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1627 (match_operand:SI 2 "arm_rhs_operand" "")))]
1630 if (GET_CODE (operands[2]) == CONST_INT
1631 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1633 emit_insn (gen_movsi (operands[0], const0_rtx));
1638 (define_expand "ashrsi3"
1639 [(set (match_operand:SI 0 "s_register_operand" "")
1640 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1641 (match_operand:SI 2 "arm_rhs_operand" "")))]
1644 if (GET_CODE (operands[2]) == CONST_INT
1645 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1646 operands[2] = GEN_INT (31);
1649 (define_expand "lshrsi3"
1650 [(set (match_operand:SI 0 "s_register_operand" "")
1651 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1652 (match_operand:SI 2 "arm_rhs_operand" "")))]
1655 if (GET_CODE (operands[2]) == CONST_INT
1656 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1658 emit_insn (gen_movsi (operands[0], const0_rtx));
1663 (define_expand "rotlsi3"
1664 [(set (match_operand:SI 0 "s_register_operand" "")
1665 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1666 (match_operand:SI 2 "reg_or_int_operand" "")))]
1669 if (GET_CODE (operands[2]) == CONST_INT)
1670 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1673 rtx reg = gen_reg_rtx (SImode);
1674 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1679 (define_expand "rotrsi3"
1680 [(set (match_operand:SI 0 "s_register_operand" "")
1681 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1682 (match_operand:SI 2 "arm_rhs_operand" "")))]
1685 if (GET_CODE (operands[2]) == CONST_INT
1686 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1687 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1690 (define_insn "*shiftsi3"
1691 [(set (match_operand:SI 0 "s_register_operand" "=r")
1692 (match_operator:SI 3 "shift_operator"
1693 [(match_operand:SI 1 "s_register_operand" "r")
1694 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1696 "mov%?\\t%0, %1%S3")
1698 (define_insn "*shiftsi3_compare0"
1699 [(set (reg:CC_NOOV 24)
1700 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1701 [(match_operand:SI 1 "s_register_operand" "r")
1702 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1704 (set (match_operand:SI 0 "s_register_operand" "=r")
1705 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1707 "mov%?s\\t%0, %1%S3"
1708 [(set_attr "conds" "set")])
1710 (define_insn "*shiftsi3_compare0_scratch"
1711 [(set (reg:CC_NOOV 24)
1712 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1713 [(match_operand:SI 1 "s_register_operand" "r")
1714 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1716 (clobber (match_scratch:SI 0 "=r"))]
1718 "mov%?s\\t%0, %1%S3"
1719 [(set_attr "conds" "set")])
1721 (define_insn "*notsi_shiftsi"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1723 (not:SI (match_operator:SI 3 "shift_operator"
1724 [(match_operand:SI 1 "s_register_operand" "r")
1725 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
1727 "mvn%?\\t%0, %1%S3")
1729 (define_insn "*notsi_shiftsi_compare0"
1730 [(set (reg:CC_NOOV 24)
1731 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1732 [(match_operand:SI 1 "s_register_operand" "r")
1733 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1735 (set (match_operand:SI 0 "s_register_operand" "=r")
1736 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1738 "mvn%?s\\t%0, %1%S3"
1739 [(set_attr "conds" "set")])
1741 (define_insn "*not_shiftsi_compare0_scratch"
1742 [(set (reg:CC_NOOV 24)
1743 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1744 [(match_operand:SI 1 "s_register_operand" "r")
1745 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1747 (clobber (match_scratch:SI 0 "=r"))]
1749 "mvn%?s\\t%0, %1%S3"
1750 [(set_attr "conds" "set")])
1753 ;; Unary arithmetic insns
1755 (define_insn "negdi2"
1756 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1757 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1759 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
1760 [(set_attr "conds" "clob")
1761 (set_attr "length" "8")])
1763 (define_insn "negsi2"
1764 [(set (match_operand:SI 0 "s_register_operand" "=r")
1765 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1767 "rsb%?\\t%0, %1, #0")
1769 (define_insn "negsf2"
1770 [(set (match_operand:SF 0 "s_register_operand" "=f")
1771 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1774 [(set_attr "type" "ffarith")])
1776 (define_insn "negdf2"
1777 [(set (match_operand:DF 0 "s_register_operand" "=f")
1778 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1781 [(set_attr "type" "ffarith")])
1783 (define_insn "*negdf_esfdf"
1784 [(set (match_operand:DF 0 "s_register_operand" "=f")
1785 (neg:DF (float_extend:DF
1786 (match_operand:SF 1 "s_register_operand" "f"))))]
1789 [(set_attr "type" "ffarith")])
1791 (define_insn "negxf2"
1792 [(set (match_operand:XF 0 "s_register_operand" "=f")
1793 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1794 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1796 [(set_attr "type" "ffarith")])
1798 ;; abssi2 doesn't really clobber the condition codes if a different register
1799 ;; is being set. To keep things simple, assume during rtl manipulations that
1800 ;; it does, but tell the final scan operator the truth. Similarly for
1803 (define_insn "abssi2"
1804 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1805 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1809 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1810 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1811 [(set_attr "conds" "clob,*")
1812 (set_attr "length" "8")])
1814 (define_insn "*neg_abssi2"
1815 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1816 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1820 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1821 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1822 [(set_attr "conds" "clob,*")
1823 (set_attr "length" "8")])
1825 (define_insn "abssf2"
1826 [(set (match_operand:SF 0 "s_register_operand" "=f")
1827 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1830 [(set_attr "type" "ffarith")])
1832 (define_insn "absdf2"
1833 [(set (match_operand:DF 0 "s_register_operand" "=f")
1834 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1837 [(set_attr "type" "ffarith")])
1839 (define_insn "*absdf_esfdf"
1840 [(set (match_operand:DF 0 "s_register_operand" "=f")
1841 (abs:DF (float_extend:DF
1842 (match_operand:SF 1 "s_register_operand" "f"))))]
1845 [(set_attr "type" "ffarith")])
1847 (define_insn "absxf2"
1848 [(set (match_operand:XF 0 "s_register_operand" "=f")
1849 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1850 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1852 [(set_attr "type" "ffarith")])
1854 (define_insn "sqrtsf2"
1855 [(set (match_operand:SF 0 "s_register_operand" "=f")
1856 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1859 [(set_attr "type" "float_em")])
1861 (define_insn "sqrtdf2"
1862 [(set (match_operand:DF 0 "s_register_operand" "=f")
1863 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1866 [(set_attr "type" "float_em")])
1868 (define_insn "*sqrtdf_esfdf"
1869 [(set (match_operand:DF 0 "s_register_operand" "=f")
1870 (sqrt:DF (float_extend:DF
1871 (match_operand:SF 1 "s_register_operand" "f"))))]
1874 [(set_attr "type" "float_em")])
1876 (define_insn "sqrtxf2"
1877 [(set (match_operand:XF 0 "s_register_operand" "=f")
1878 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1879 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1881 [(set_attr "type" "float_em")])
1883 ;; SIN COS TAN and family are always emulated, so it's probably better
1884 ;; to always call a library function.
1885 ;(define_insn "sinsf2"
1886 ; [(set (match_operand:SF 0 "s_register_operand" "=f")
1887 ; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1888 ; "TARGET_HARD_FLOAT"
1890 ;[(set_attr "type" "float_em")])
1892 ;(define_insn "sindf2"
1893 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1894 ; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1895 ; "TARGET_HARD_FLOAT"
1897 ;[(set_attr "type" "float_em")])
1899 ;(define_insn "*sindf_esfdf"
1900 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1901 ; (unspec:DF [(float_extend:DF
1902 ; (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1903 ; "TARGET_HARD_FLOAT"
1905 ;[(set_attr "type" "float_em")])
1907 ;(define_insn "sinxf2"
1908 ; [(set (match_operand:XF 0 "s_register_operand" "=f")
1909 ; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1910 ; "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1912 ;[(set_attr "type" "float_em")])
1914 ;(define_insn "cossf2"
1915 ; [(set (match_operand:SF 0 "s_register_operand" "=f")
1916 ; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1917 ; "TARGET_HARD_FLOAT"
1919 ;[(set_attr "type" "float_em")])
1921 ;(define_insn "cosdf2"
1922 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1923 ; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1924 ; "TARGET_HARD_FLOAT"
1926 ;[(set_attr "type" "float_em")])
1928 ;(define_insn "*cosdf_esfdf"
1929 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1930 ; (unspec:DF [(float_extend:DF
1931 ; (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1932 ; "TARGET_HARD_FLOAT"
1934 ;[(set_attr "type" "float_em")])
1936 ;(define_insn "cosxf2"
1937 ; [(set (match_operand:XF 0 "s_register_operand" "=f")
1938 ; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1939 ; "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1941 ;[(set_attr "type" "float_em")])
1943 (define_insn "one_cmpldi2"
1944 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1945 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1947 "mvn%?\\t%Q0, %Q1\;mvn%?\\t%R0, %R1"
1948 [(set_attr "length" "8")])
1950 (define_insn "one_cmplsi2"
1951 [(set (match_operand:SI 0 "s_register_operand" "=r")
1952 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
1956 (define_insn "*notsi_compare0"
1957 [(set (reg:CC_NOOV 24)
1958 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1960 (set (match_operand:SI 0 "s_register_operand" "=r")
1961 (not:SI (match_dup 1)))]
1964 [(set_attr "conds" "set")])
1966 (define_insn "*notsi_compare0_scratch"
1967 [(set (reg:CC_NOOV 24)
1968 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1970 (clobber (match_scratch:SI 0 "=r"))]
1973 [(set_attr "conds" "set")])
1975 ;; Fixed <--> Floating conversion insns
1977 (define_insn "floatsisf2"
1978 [(set (match_operand:SF 0 "s_register_operand" "=f")
1979 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
1982 [(set_attr "type" "r_2_f")])
1984 (define_insn "floatsidf2"
1985 [(set (match_operand:DF 0 "s_register_operand" "=f")
1986 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
1989 [(set_attr "type" "r_2_f")])
1991 (define_insn "floatsixf2"
1992 [(set (match_operand:XF 0 "s_register_operand" "=f")
1993 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
1994 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1996 [(set_attr "type" "r_2_f")])
1998 (define_insn "fix_truncsfsi2"
1999 [(set (match_operand:SI 0 "s_register_operand" "=r")
2000 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
2003 [(set_attr "type" "f_2_r")])
2005 (define_insn "fix_truncdfsi2"
2006 [(set (match_operand:SI 0 "s_register_operand" "=r")
2007 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
2010 [(set_attr "type" "f_2_r")])
2012 (define_insn "fix_truncxfsi2"
2013 [(set (match_operand:SI 0 "s_register_operand" "=r")
2014 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
2015 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2017 [(set_attr "type" "f_2_r")])
2021 (define_insn "truncdfsf2"
2022 [(set (match_operand:SF 0 "s_register_operand" "=f")
2024 (match_operand:DF 1 "s_register_operand" "f")))]
2027 [(set_attr "type" "ffarith")])
2029 (define_insn "truncxfsf2"
2030 [(set (match_operand:SF 0 "s_register_operand" "=f")
2032 (match_operand:XF 1 "s_register_operand" "f")))]
2033 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2035 [(set_attr "type" "ffarith")])
2037 (define_insn "truncxfdf2"
2038 [(set (match_operand:DF 0 "s_register_operand" "=f")
2040 (match_operand:XF 1 "s_register_operand" "f")))]
2041 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2043 [(set_attr "type" "ffarith")])
2045 ;; Zero and sign extension instructions.
2047 (define_insn "zero_extendsidi2"
2048 [(set (match_operand:DI 0 "s_register_operand" "=r")
2049 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
2052 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
2053 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
2054 return \"mov%?\\t%R0, #0\";
2056 [(set_attr "length" "8")])
2058 (define_insn "zero_extendqidi2"
2059 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
2060 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2063 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
2064 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
2065 [(set_attr "length" "8")
2066 (set_attr "type" "*,load")])
2068 (define_insn "extendsidi2"
2069 [(set (match_operand:DI 0 "s_register_operand" "=r")
2070 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
2073 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
2074 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
2075 return \"mov%?\\t%R0, %Q0, asr #31\";
2077 [(set_attr "length" "8")])
2079 (define_expand "zero_extendhisi2"
2080 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2082 (set (match_operand:SI 0 "s_register_operand" "")
2083 (lshiftrt:SI (match_dup 2) (const_int 16)))]
2087 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2089 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2090 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
2093 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2095 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
2098 if (! s_register_operand (operands[1], HImode))
2099 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2100 operands[1] = gen_lowpart (SImode, operands[1]);
2101 operands[2] = gen_reg_rtx (SImode);
2104 (define_insn "*zero_extendhisi_insn"
2105 [(set (match_operand:SI 0 "s_register_operand" "=r")
2106 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2109 [(set_attr "type" "load")])
2112 [(set (match_operand:SI 0 "s_register_operand" "")
2113 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2114 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2116 [(set (match_dup 2) (match_dup 1))
2117 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
2120 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2125 [(set (match_operand:SI 0 "s_register_operand" "")
2126 (match_operator:SI 3 "shiftable_operator"
2127 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2128 (match_operand:SI 4 "s_register_operand" "")]))
2129 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2131 [(set (match_dup 2) (match_dup 1))
2134 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2137 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2141 (define_expand "zero_extendqisi2"
2142 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2144 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2147 if (GET_CODE (operands[1]) != MEM)
2149 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
2155 (define_insn "*load_extendqisi"
2156 [(set (match_operand:SI 0 "s_register_operand" "=r")
2157 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2159 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
2160 [(set_attr "type" "load")])
2163 [(set (match_operand:SI 0 "s_register_operand" "")
2164 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
2165 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2166 "GET_CODE (operands[1]) != MEM"
2167 [(set (match_dup 2) (match_dup 1))
2168 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
2171 (define_insn "*compareqi_eq0"
2173 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
2177 [(set_attr "conds" "set")])
2179 (define_expand "extendhisi2"
2181 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2183 (set (match_operand:SI 0 "s_register_operand" "")
2184 (ashiftrt:SI (match_dup 2)
2189 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2191 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2192 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2196 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2198 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
2201 if (! s_register_operand (operands[1], HImode))
2202 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2203 operands[1] = gen_lowpart (SImode, operands[1]);
2204 operands[2] = gen_reg_rtx (SImode);
2207 (define_expand "extendhisi2_mem"
2208 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2210 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2211 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
2212 (set (match_operand:SI 0 "" "")
2213 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
2216 operands[0] = gen_lowpart (SImode, operands[0]);
2217 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2218 operands[2] = gen_reg_rtx (SImode);
2219 operands[3] = gen_reg_rtx (SImode);
2220 operands[6] = gen_reg_rtx (SImode);
2222 if (BYTES_BIG_ENDIAN)
2224 operands[4] = operands[2];
2225 operands[5] = operands[3];
2229 operands[4] = operands[3];
2230 operands[5] = operands[2];
2234 (define_insn "*extendhisi_insn"
2235 [(set (match_operand:SI 0 "s_register_operand" "=r")
2236 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2239 [(set_attr "type" "load")])
2242 [(set (match_operand:SI 0 "s_register_operand" "")
2243 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2244 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2246 [(set (match_dup 2) (match_dup 1))
2247 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
2250 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2255 [(set (match_operand:SI 0 "s_register_operand" "")
2256 (match_operator:SI 3 "shiftable_operator"
2257 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2258 (match_operand:SI 4 "s_register_operand" "")]))
2259 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2261 [(set (match_dup 2) (match_dup 1))
2264 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2267 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2271 (define_expand "extendqihi2"
2273 (ashift:SI (match_operand:QI 1 "general_operand" "")
2275 (set (match_operand:HI 0 "s_register_operand" "")
2276 (ashiftrt:SI (match_dup 2)
2281 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2283 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2284 gen_rtx (SIGN_EXTEND, HImode, operands[1])));
2287 if (! s_register_operand (operands[1], QImode))
2288 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2289 operands[0] = gen_lowpart (SImode, operands[0]);
2290 operands[1] = gen_lowpart (SImode, operands[1]);
2291 operands[2] = gen_reg_rtx (SImode);
2294 (define_insn "*extendqihi_insn"
2295 [(set (match_operand:HI 0 "s_register_operand" "=r")
2296 (sign_extend:HI (match_operand:QI 1 "memory_operand" "o<>")))]
2299 [(set_attr "type" "load")])
2301 (define_expand "extendqisi2"
2303 (ashift:SI (match_operand:QI 1 "s_register_operand" "")
2305 (set (match_operand:SI 0 "s_register_operand" "")
2306 (ashiftrt:SI (match_dup 2)
2311 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2313 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2314 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2317 if (! s_register_operand (operands[1], QImode))
2318 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2319 operands[1] = gen_lowpart (SImode, operands[1]);
2320 operands[2] = gen_reg_rtx (SImode);
2323 (define_insn "*extendqisi_insn"
2324 [(set (match_operand:SI 0 "s_register_operand" "=r")
2325 (sign_extend:SI (match_operand:QI 1 "memory_operand" "o<>")))]
2328 [(set_attr "type" "load")])
2330 (define_insn "extendsfdf2"
2331 [(set (match_operand:DF 0 "s_register_operand" "=f")
2332 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
2335 [(set_attr "type" "ffarith")])
2337 (define_insn "extendsfxf2"
2338 [(set (match_operand:XF 0 "s_register_operand" "=f")
2339 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
2340 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2342 [(set_attr "type" "ffarith")])
2344 (define_insn "extenddfxf2"
2345 [(set (match_operand:XF 0 "s_register_operand" "=f")
2346 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
2347 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2349 [(set_attr "type" "ffarith")])
2352 ;; Move insns (including loads and stores)
2354 ;; XXX Just some ideas about movti.
2355 ;; I don't think these are a good idea on the arm, there just aren't enough
2357 ;;(define_expand "loadti"
2358 ;; [(set (match_operand:TI 0 "s_register_operand" "")
2359 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
2362 ;;(define_expand "storeti"
2363 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
2364 ;; (match_operand:TI 1 "s_register_operand" ""))]
2367 ;;(define_expand "movti"
2368 ;; [(set (match_operand:TI 0 "general_operand" "")
2369 ;; (match_operand:TI 1 "general_operand" ""))]
2375 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2376 ;; operands[1] = copy_to_reg (operands[1]);
2377 ;; if (GET_CODE (operands[0]) == MEM)
2378 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
2379 ;; else if (GET_CODE (operands[1]) == MEM)
2380 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
2384 ;; emit_insn (insn);
2388 ;; Recognise garbage generated above.
2391 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
2392 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
2396 ;; register mem = (which_alternative < 3);
2397 ;; register char *template;
2399 ;; operands[mem] = XEXP (operands[mem], 0);
2400 ;; switch (which_alternative)
2402 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
2403 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
2404 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
2405 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
2406 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
2407 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
2409 ;; output_asm_insn (template, operands);
2414 (define_insn "movdi"
2415 [(set (match_operand:DI 0 "di_operand" "=r,r,o<>")
2416 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
2419 return (output_move_double (operands));
2421 [(set_attr "length" "8,8,8")
2422 (set_attr "type" "*,load,store2")])
2424 (define_expand "movsi"
2425 [(set (match_operand:SI 0 "general_operand" "")
2426 (match_operand:SI 1 "general_operand" ""))]
2429 /* Everything except mem = const or mem = mem can be done easily */
2430 if (GET_CODE (operands[0]) == MEM)
2431 operands[1] = force_reg (SImode, operands[1]);
2432 if (GET_CODE (operands[1]) == CONST_INT
2433 && !(const_ok_for_arm (INTVAL (operands[1]))
2434 || const_ok_for_arm (~INTVAL (operands[1]))))
2436 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2438 (reload_in_progress || reload_completed ? 0
2439 : preserve_subexpressions_p ()));
2442 if (CONSTANT_P (operands[1]) && flag_pic)
2443 operands[1] = legitimize_pic_address (operands[1], SImode,
2444 ((reload_in_progress
2445 || reload_completed)
2446 ? operands[0] : 0));
2449 (define_insn "*movsi_insn"
2450 [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
2451 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
2452 "register_operand (operands[0], SImode)
2453 || register_operand (operands[1], SImode)"
2459 [(set_attr "type" "*,*,load,store1")])
2462 [(set (match_operand:SI 0 "s_register_operand" "")
2463 (match_operand:SI 1 "const_int_operand" ""))]
2464 "! (const_ok_for_arm (INTVAL (operands[1]))
2465 || const_ok_for_arm (~INTVAL (operands[1])))"
2466 [(clobber (const_int 0))]
2468 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2473 (define_expand "movaddr"
2474 [(set (match_operand:SI 0 "s_register_operand" "")
2475 (match_operand:DI 1 "address_operand" ""))]
2479 (define_insn "*movaddr_insn"
2480 [(set (match_operand:SI 0 "s_register_operand" "=r")
2481 (match_operand:DI 1 "address_operand" "p"))]
2483 && (GET_CODE (operands[1]) == LABEL_REF
2484 || (GET_CODE (operands[1]) == CONST
2485 && GET_CODE (XEXP (operands[1], 0)) == PLUS
2486 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2487 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
2490 /* When generating pic, we need to load the symbol offset into a register.
2491 So that the optimizer does not confuse this with a normal symbol load
2492 we use an unspec. The offset will be loaded from a constant pool entry,
2493 since that is the only type of relocation we can use. */
2495 (define_insn "pic_load_addr"
2496 [(set (match_operand:SI 0 "s_register_operand" "=r")
2497 (unspec:SI [(match_operand 1 "" "")] 3))]
2500 [(set_attr "type" "load")])
2502 ;; This variant is used for AOF assembly, since it needs to mention the
2503 ;; pic register in the rtl.
2504 (define_expand "pic_load_addr_based"
2505 [(set (match_operand:SI 0 "s_register_operand" "=r")
2506 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] 3))]
2508 "operands[2] = pic_offset_table_rtx;")
2510 (define_insn "*pic_load_addr_based_insn"
2511 [(set (match_operand:SI 0 "s_register_operand" "=r")
2512 (unspec:SI [(match_operand 1 "" "")
2513 (match_operand 2 "s_register_operand" "r")] 3))]
2514 "flag_pic && operands[2] == pic_offset_table_rtx"
2516 #ifdef AOF_ASSEMBLER
2517 operands[1] = aof_pic_entry (operands[1]);
2519 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
2521 " [(set_attr "type" "load")])
2523 (define_insn "pic_add_dot_plus_eight"
2524 [(set (pc) (label_ref (match_operand 0 "" "")))
2525 (set (match_operand 1 "register_operand" "+r")
2526 (plus:SI (match_dup 1) (const (plus:SI (pc) (const_int 8)))))]
2528 "add%?\\t%1, %|pc, %1")
2530 ;; If copying one reg to another we can set the condition codes according to
2531 ;; its value. Such a move is common after a return from subroutine and the
2532 ;; result is being tested against zero.
2534 (define_insn "*movsi_compare0"
2535 [(set (reg:CC 24) (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
2537 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2541 sub%?s\\t%0, %1, #0"
2542 [(set_attr "conds" "set")])
2544 ;; Subroutine to store a half word from a register into memory.
2545 ;; Operand 0 is the source register (HImode)
2546 ;; Operand 1 is the destination address in a register (SImode)
2548 ;; In both this routine and the next, we must be careful not to spill
2549 ;; a memory address of reg+large_const into a separate PLUS insn, since this
2550 ;; can generate unrecognizable rtl.
2552 (define_expand "storehi"
2553 [;; store the low byte
2554 (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
2555 ;; extract the high byte
2557 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2558 ;; store the high byte
2559 (set (mem:QI (match_dup 4))
2560 (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2564 enum rtx_code code = GET_CODE (operands[1]);
2566 if ((code == PLUS || code == MINUS)
2567 && (GET_CODE (XEXP (operands[1], 1)) == REG
2568 || GET_CODE (XEXP (operands[1], 0)) != REG))
2569 operands[1] = force_reg (SImode, operands[1]);
2570 operands[4] = plus_constant (operands[1], 1);
2571 operands[3] = gen_lowpart (QImode, operands[0]);
2572 operands[0] = gen_lowpart (SImode, operands[0]);
2573 operands[2] = gen_reg_rtx (SImode);
2577 (define_expand "storehi_bigend"
2578 [(set (mem:QI (match_dup 4)) (match_dup 3))
2580 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2581 (set (mem:QI (match_operand 1 "" ""))
2582 (subreg:QI (match_dup 2) 0))]
2586 enum rtx_code code = GET_CODE (operands[1]);
2587 if ((code == PLUS || code == MINUS)
2588 && (GET_CODE (XEXP (operands[1], 1)) == REG
2589 || GET_CODE (XEXP (operands[1], 0)) != REG))
2590 operands[1] = force_reg (SImode, operands[1]);
2592 operands[4] = plus_constant (operands[1], 1);
2593 operands[3] = gen_lowpart (QImode, operands[0]);
2594 operands[0] = gen_lowpart (SImode, operands[0]);
2595 operands[2] = gen_reg_rtx (SImode);
2599 ;; Subroutine to store a half word integer constant into memory.
2600 (define_expand "storeinthi"
2601 [(set (mem:QI (match_operand:SI 0 "" ""))
2602 (subreg:QI (match_operand 1 "" "") 0))
2603 (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
2607 HOST_WIDE_INT value = INTVAL (operands[1]);
2608 enum rtx_code code = GET_CODE (operands[0]);
2610 if ((code == PLUS || code == MINUS)
2611 && (GET_CODE (XEXP (operands[0], 1)) == REG
2612 || GET_CODE (XEXP (operands[0], 0)) != REG))
2613 operands[0] = force_reg (SImode, operands[0]);
2615 operands[1] = gen_reg_rtx (SImode);
2616 if (BYTES_BIG_ENDIAN)
2618 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2619 if ((value & 255) == ((value >> 8) & 255))
2620 operands[2] = operands[1];
2623 operands[2] = gen_reg_rtx (SImode);
2624 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2629 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2630 if ((value & 255) == ((value >> 8) & 255))
2631 operands[2] = operands[1];
2634 operands[2] = gen_reg_rtx (SImode);
2635 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2639 operands[3] = plus_constant (operands[0], 1);
2643 (define_expand "storehi_single_op"
2644 [(set (match_operand:HI 0 "memory_operand" "")
2645 (match_operand:HI 1 "general_operand" ""))]
2648 if (! s_register_operand (operands[1], HImode))
2649 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2652 (define_expand "movhi"
2653 [(set (match_operand:HI 0 "general_operand" "")
2654 (match_operand:HI 1 "general_operand" ""))]
2660 if (! (reload_in_progress || reload_completed))
2662 if (GET_CODE (operands[0]) == MEM)
2666 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
2669 if (GET_CODE (operands[1]) == CONST_INT)
2670 emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
2673 if (GET_CODE (operands[1]) == MEM)
2674 operands[1] = force_reg (HImode, operands[1]);
2675 if (BYTES_BIG_ENDIAN)
2676 emit_insn (gen_storehi_bigend (operands[1],
2677 XEXP (operands[0], 0)));
2679 emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
2683 /* Sign extend a constant, and keep it in an SImode reg. */
2684 else if (GET_CODE (operands[1]) == CONST_INT)
2686 rtx reg = gen_reg_rtx (SImode);
2687 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2689 /* If the constant is already valid, leave it alone. */
2690 if (! const_ok_for_arm (val))
2692 /* If setting all the top bits will make the constant
2693 loadable in a single instruction, then set them.
2694 Otherwise, sign extend the number. */
2696 if (const_ok_for_arm (~ (val | ~0xffff)))
2698 else if (val & 0x8000)
2702 emit_insn (gen_movsi (reg, GEN_INT (val)));
2703 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2705 else if (! arm_arch4)
2707 if (GET_CODE (operands[1]) == MEM)
2709 if (TARGET_SHORT_BY_BYTES)
2712 rtx offset = const0_rtx;
2713 rtx reg = gen_reg_rtx (SImode);
2715 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2716 || (GET_CODE (base) == PLUS
2717 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2718 && GET_CODE (base = XEXP (base, 0)) == REG))
2719 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2721 HOST_WIDE_INT new_offset = INTVAL (offset) & ~2;
2723 emit_insn (gen_movsi (reg, gen_rtx (MEM, SImode,
2724 plus_constant (base, new_offset))));
2725 if (((INTVAL (offset) & 2) != 0)
2726 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
2728 rtx reg2 = gen_reg_rtx (SImode);
2730 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
2735 emit_insn (gen_movhi_bytes (reg, operands[1]));
2737 operands[1] = gen_lowpart (HImode, reg);
2739 else if (BYTES_BIG_ENDIAN)
2742 rtx offset = const0_rtx;
2744 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2745 || (GET_CODE (base) == PLUS
2746 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2747 && GET_CODE (base = XEXP (base, 0)) == REG))
2748 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2750 rtx reg = gen_reg_rtx (SImode);
2753 if ((INTVAL (offset) & 2) == 2)
2755 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
2756 new_mem = gen_rtx (MEM, SImode,
2757 plus_constant (base, new_offset));
2759 emit_insn (gen_movsi (reg, new_mem));
2763 new_mem = gen_rtx (MEM, SImode,
2764 XEXP (operands[1], 0));
2765 emit_insn (gen_rotated_loadsi (reg, new_mem));
2768 operands[1] = gen_lowpart (HImode, reg);
2772 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2779 /* Handle loading a large integer during reload */
2780 else if (GET_CODE (operands[1]) == CONST_INT
2781 && ! const_ok_for_arm (INTVAL (operands[1]))
2782 && ! const_ok_for_arm (~INTVAL (operands[1])))
2784 /* Writing a constant to memory needs a scratch, which should
2785 be handled with SECONDARY_RELOADs. */
2786 if (GET_CODE (operands[0]) != REG)
2789 operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0);
2790 emit_insn (gen_movsi (operands[0], operands[1]));
2796 (define_insn "rotated_loadsi"
2797 [(set (match_operand:SI 0 "s_register_operand" "=r")
2798 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
2800 "! TARGET_SHORT_BY_BYTES"
2805 ops[0] = operands[0];
2806 ops[1] = gen_rtx (MEM, SImode, plus_constant (XEXP (operands[1], 0), 2));
2807 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
2810 [(set_attr "type" "load")])
2812 (define_expand "movhi_bytes"
2813 [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
2815 (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
2816 (set (match_operand:SI 0 "" "")
2817 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
2820 operands[0] = gen_lowpart (SImode, operands[0]);
2821 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2822 operands[2] = gen_reg_rtx (SImode);
2823 operands[3] = gen_reg_rtx (SImode);
2825 if (BYTES_BIG_ENDIAN)
2827 operands[4] = operands[2];
2828 operands[5] = operands[3];
2832 operands[4] = operands[3];
2833 operands[5] = operands[2];
2837 (define_expand "movhi_bigend"
2839 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
2842 (ashiftrt:SI (match_dup 2) (const_int 16)))
2843 (set (match_operand:HI 0 "s_register_operand" "")
2844 (subreg:HI (match_dup 3) 0))]
2847 operands[2] = gen_reg_rtx (SImode);
2848 operands[3] = gen_reg_rtx (SImode);
2851 ;; Pattern to recognise insn generated default case above
2853 (define_insn "*movhi_insn_arch4"
2854 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2855 (match_operand:HI 1 "general_operand" "rI,K,m,r"))]
2857 && (GET_CODE (operands[1]) != CONST_INT
2858 || const_ok_for_arm (INTVAL (operands[1]))
2859 || const_ok_for_arm (~INTVAL (operands[1])))"
2861 mov%?\\t%0, %1\\t%@ movhi
2862 mvn%?\\t%0, #%B1\\t%@ movhi
2863 ldr%?h\\t%0, %1\\t%@ movhi
2864 str%?h\\t%1, %0\\t%@ movhi"
2865 [(set_attr "type" "*,*,load,store1")])
2867 (define_insn "*movhi_insn_littleend"
2868 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
2869 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2871 && ! BYTES_BIG_ENDIAN
2872 && ! TARGET_SHORT_BY_BYTES
2873 && (GET_CODE (operands[1]) != CONST_INT
2874 || const_ok_for_arm (INTVAL (operands[1]))
2875 || const_ok_for_arm (~INTVAL (operands[1])))"
2877 mov%?\\t%0, %1\\t%@ movhi
2878 mvn%?\\t%0, #%B1\\t%@ movhi
2879 ldr%?\\t%0, %1\\t%@ movhi"
2880 [(set_attr "type" "*,*,load")])
2882 (define_insn "*movhi_insn_bigend"
2883 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
2884 (match_operand:HI 1 "general_operand" "rI,K,m"))]
2887 && ! TARGET_SHORT_BY_BYTES
2888 && (GET_CODE (operands[1]) != CONST_INT
2889 || const_ok_for_arm (INTVAL (operands[1]))
2890 || const_ok_for_arm (~INTVAL (operands[1])))"
2892 mov%?\\t%0, %1\\t%@ movhi
2893 mvn%?\\t%0, #%B1\\t%@ movhi
2894 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
2895 [(set_attr "type" "*,*,load")
2896 (set_attr "length" "4,4,8")])
2898 (define_insn "*loadhi_si_bigend"
2899 [(set (match_operand:SI 0 "s_register_operand" "=r")
2900 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
2903 && ! TARGET_SHORT_BY_BYTES"
2904 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
2905 [(set_attr "type" "load")])
2907 (define_insn "*movhi_bytes"
2908 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
2909 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
2910 "TARGET_SHORT_BY_BYTES"
2912 mov%?\\t%0, %1\\t%@ movhi
2913 mvn%?\\t%0, #%B1\\t%@ movhi")
2916 (define_expand "reload_outhi"
2917 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
2918 (match_operand:HI 1 "s_register_operand" "r")
2919 (match_operand:SI 2 "s_register_operand" "=&r")])]
2922 arm_reload_out_hi (operands);
2926 (define_expand "reload_inhi"
2927 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
2928 (match_operand:HI 1 "reload_memory_operand" "o")
2929 (match_operand:SI 2 "s_register_operand" "=&r")])]
2930 "TARGET_SHORT_BY_BYTES"
2932 arm_reload_in_hi (operands);
2936 (define_expand "movqi"
2937 [(set (match_operand:QI 0 "general_operand" "")
2938 (match_operand:QI 1 "general_operand" ""))]
2941 /* Everything except mem = const or mem = mem can be done easily */
2943 if (!(reload_in_progress || reload_completed))
2945 if (GET_CODE (operands[1]) == CONST_INT)
2947 rtx reg = gen_reg_rtx (SImode);
2949 emit_insn (gen_movsi (reg, operands[1]));
2950 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
2952 if (GET_CODE (operands[0]) == MEM)
2953 operands[1] = force_reg (QImode, operands[1]);
2958 (define_insn "*movqi_insn"
2959 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
2960 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
2961 "register_operand (operands[0], QImode)
2962 || register_operand (operands[1], QImode)"
2968 [(set_attr "type" "*,*,load,store1")])
2970 (define_expand "movsf"
2971 [(set (match_operand:SF 0 "general_operand" "")
2972 (match_operand:SF 1 "general_operand" ""))]
2975 if (GET_CODE (operands[0]) == MEM)
2976 operands[1] = force_reg (SFmode, operands[1]);
2979 (define_insn "*movsf_hard_insn"
2980 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
2981 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
2983 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
2989 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
2990 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
2992 ldr%?\\t%0, %1\\t%@ float
2993 str%?\\t%1, %0\\t%@ float"
2994 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
2996 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
2998 ;; Exactly the same as above, except that all `f' cases are deleted.
2999 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3000 ;; when -msoft-float.
3002 (define_insn "*movsf_soft_insn"
3003 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
3004 (match_operand:SF 1 "general_operand" "r,mE,r"))]
3006 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
3009 ldr%?\\t%0, %1\\t%@ float
3010 str%?\\t%1, %0\\t%@ float"
3011 [(set_attr "length" "4,4,4")
3012 (set_attr "type" "*,load,store1")])
3014 (define_expand "movdf"
3015 [(set (match_operand:DF 0 "general_operand" "")
3016 (match_operand:DF 1 "general_operand" ""))]
3019 if (GET_CODE (operands[0]) == MEM)
3020 operands[1] = force_reg (DFmode, operands[1]);
3023 ;; Reloading a df mode value stored in integer regs to memory can require a
3025 (define_expand "reload_outdf"
3026 [(match_operand:DF 0 "reload_memory_operand" "=o")
3027 (match_operand:DF 1 "s_register_operand" "r")
3028 (match_operand:SI 2 "s_register_operand" "=&r")]
3032 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
3035 operands[2] = XEXP (operands[0], 0);
3036 else if (code == POST_INC || code == PRE_DEC)
3038 operands[0] = gen_rtx (SUBREG, DImode, operands[0], 0);
3039 operands[1] = gen_rtx (SUBREG, DImode, operands[1], 0);
3040 emit_insn (gen_movdi (operands[0], operands[1]));
3043 else if (code == PRE_INC)
3045 rtx reg = XEXP (XEXP (operands[0], 0), 0);
3046 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
3049 else if (code == POST_DEC)
3050 operands[2] = XEXP (XEXP (operands[0], 0), 0);
3052 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
3053 XEXP (XEXP (operands[0], 0), 1)));
3055 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
3058 if (code == POST_DEC)
3059 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
3065 (define_insn "*movdf_hard_insn"
3066 [(set (match_operand:DF 0 "general_operand" "=r,Q,r,m,r,f,f,f,m,!f,!r")
3067 (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,fG,H,mF,f,r,f"))]
3069 && (GET_CODE (operands[0]) != MEM
3070 || register_operand (operands[1], DFmode))"
3075 switch (which_alternative)
3077 case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
3078 case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
3079 case 2: case 3: case 4: return output_move_double (operands);
3080 case 5: return \"mvf%?d\\t%0, %1\";
3081 case 6: return \"mnf%?d\\t%0, #%N1\";
3082 case 7: return \"ldf%?d\\t%0, %1\";
3083 case 8: return \"stf%?d\\t%1, %0\";
3084 case 9: return output_mov_double_fpu_from_arm (operands);
3085 case 10: return output_mov_double_arm_from_fpu (operands);
3089 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
3091 "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")])
3093 ;; Software floating point version. This is essentially the same as movdi.
3094 ;; Do not use `f' as a constraint to prevent reload from ever trying to use
3097 (define_insn "*movdf_soft_insn"
3098 [(set (match_operand:DF 0 "soft_df_operand" "=r,r,m")
3099 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
3101 "* return output_move_double (operands);"
3102 [(set_attr "length" "8,8,8")
3103 (set_attr "type" "*,load,store2")])
3105 (define_expand "movxf"
3106 [(set (match_operand:XF 0 "general_operand" "")
3107 (match_operand:XF 1 "general_operand" ""))]
3108 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3111 ;; Even when the XFmode patterns aren't enabled, we enable this after
3112 ;; reloading so that we can push floating point registers in the prologue.
3114 (define_insn "*movxf_hard_insn"
3115 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
3116 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
3117 "TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
3119 switch (which_alternative)
3121 case 0: return \"mvf%?e\\t%0, %1\";
3122 case 1: return \"mnf%?e\\t%0, #%N1\";
3123 case 2: return \"ldf%?e\\t%0, %1\";
3124 case 3: return \"stf%?e\\t%1, %0\";
3125 case 4: return output_mov_long_double_fpu_from_arm (operands);
3126 case 5: return output_mov_long_double_arm_from_fpu (operands);
3127 case 6: return output_mov_long_double_arm_from_arm (operands);
3130 [(set_attr "length" "4,4,4,4,8,8,12")
3131 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
3134 ;; load- and store-multiple insns
3135 ;; The arm can load/store any set of registers, provided that they are in
3136 ;; ascending order; but that is beyond GCC so stick with what it knows.
3138 (define_expand "load_multiple"
3139 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3140 (match_operand:SI 1 "" ""))
3141 (use (match_operand:SI 2 "" ""))])]
3144 /* Support only fixed point registers */
3145 if (GET_CODE (operands[2]) != CONST_INT
3146 || INTVAL (operands[2]) > 14
3147 || INTVAL (operands[2]) < 2
3148 || GET_CODE (operands[1]) != MEM
3149 || GET_CODE (operands[0]) != REG
3150 || REGNO (operands[0]) > 14
3151 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
3155 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
3156 force_reg (SImode, XEXP (operands[1], 0)),
3160 ;; Load multiple with write-back
3162 (define_insn "*ldmsi_postinc"
3163 [(match_parallel 0 "load_multiple_operation"
3164 [(set (match_operand:SI 1 "s_register_operand" "+r")
3165 (plus:SI (match_dup 1)
3166 (match_operand:SI 2 "const_int_operand" "n")))
3167 (set (match_operand:SI 3 "s_register_operand" "=r")
3168 (mem:SI (match_dup 1)))])]
3169 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3173 int count = XVECLEN (operands[0], 0);
3175 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3176 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
3177 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
3179 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
3183 [(set_attr "type" "load")])
3185 ;; Ordinary load multiple
3187 (define_insn "*ldmsi"
3188 [(match_parallel 0 "load_multiple_operation"
3189 [(set (match_operand:SI 1 "s_register_operand" "=r")
3190 (mem:SI (match_operand:SI 2 "s_register_operand" "r")))])]
3195 int count = XVECLEN (operands[0], 0);
3197 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3198 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
3199 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
3201 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
3205 [(set_attr "type" "load")])
3207 (define_expand "store_multiple"
3208 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3209 (match_operand:SI 1 "" ""))
3210 (use (match_operand:SI 2 "" ""))])]
3213 /* Support only fixed point registers */
3214 if (GET_CODE (operands[2]) != CONST_INT
3215 || INTVAL (operands[2]) > 14
3216 || INTVAL (operands[2]) < 2
3217 || GET_CODE (operands[1]) != REG
3218 || GET_CODE (operands[0]) != MEM
3219 || REGNO (operands[1]) > 14
3220 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
3224 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
3225 force_reg (SImode, XEXP (operands[0], 0)),
3229 ;; Store multiple with write-back
3231 (define_insn "*stmsi_postinc"
3232 [(match_parallel 0 "store_multiple_operation"
3233 [(set (match_operand:SI 1 "s_register_operand" "+r")
3234 (plus:SI (match_dup 1)
3235 (match_operand:SI 2 "const_int_operand" "n")))
3236 (set (mem:SI (match_dup 1))
3237 (match_operand:SI 3 "s_register_operand" "r"))])]
3238 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3242 int count = XVECLEN (operands[0], 0);
3244 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3245 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
3246 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
3248 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
3253 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3254 (const_string "store2")
3255 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
3256 (const_string "store3")]
3257 (const_string "store4")))])
3259 ;; Ordinary store multiple
3261 (define_insn "*stmsi"
3262 [(match_parallel 0 "store_multiple_operation"
3263 [(set (mem:SI (match_operand:SI 2 "s_register_operand" "r"))
3264 (match_operand:SI 1 "s_register_operand" "r"))])]
3269 int count = XVECLEN (operands[0], 0);
3271 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
3272 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
3273 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
3275 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
3280 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
3281 (const_string "store2")
3282 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3283 (const_string "store3")]
3284 (const_string "store4")))])
3286 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
3287 ;; We could let this apply for blocks of less than this, but it clobbers so
3288 ;; many registers that there is then probably a better way.
3290 (define_expand "movstrqi"
3291 [(match_operand:BLK 0 "general_operand" "")
3292 (match_operand:BLK 1 "general_operand" "")
3293 (match_operand:SI 2 "const_int_operand" "")
3294 (match_operand:SI 3 "const_int_operand" "")]
3297 if (arm_gen_movstrqi (operands))
3303 ;; Comparison and test insns
3305 (define_expand "cmpsi"
3306 [(match_operand:SI 0 "s_register_operand" "")
3307 (match_operand:SI 1 "arm_add_operand" "")]
3311 arm_compare_op0 = operands[0];
3312 arm_compare_op1 = operands[1];
3318 (define_expand "cmpsf"
3319 [(match_operand:SF 0 "s_register_operand" "")
3320 (match_operand:SF 1 "fpu_rhs_operand" "")]
3324 arm_compare_op0 = operands[0];
3325 arm_compare_op1 = operands[1];
3331 (define_expand "cmpdf"
3332 [(match_operand:DF 0 "s_register_operand" "")
3333 (match_operand:DF 1 "fpu_rhs_operand" "")]
3337 arm_compare_op0 = operands[0];
3338 arm_compare_op1 = operands[1];
3344 (define_expand "cmpxf"
3345 [(match_operand:XF 0 "s_register_operand" "")
3346 (match_operand:XF 1 "fpu_rhs_operand" "")]
3347 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3350 arm_compare_op0 = operands[0];
3351 arm_compare_op1 = operands[1];
3357 (define_insn "*cmpsi_insn"
3359 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
3360 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
3365 [(set_attr "conds" "set")])
3367 (define_insn "*cmpsi_shiftsi"
3369 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3370 (match_operator:SI 3 "shift_operator"
3371 [(match_operand:SI 1 "s_register_operand" "r")
3372 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
3375 [(set_attr "conds" "set")])
3377 (define_insn "*cmpsi_shiftsi_swp"
3378 [(set (reg:CC_SWP 24)
3379 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
3380 [(match_operand:SI 1 "s_register_operand" "r")
3381 (match_operand:SI 2 "reg_or_int_operand" "rM")])
3382 (match_operand:SI 0 "s_register_operand" "r")))]
3385 [(set_attr "conds" "set")])
3387 (define_insn "*cmpsi_neg_shiftsi"
3389 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3390 (neg:SI (match_operator:SI 3 "shift_operator"
3391 [(match_operand:SI 1 "s_register_operand" "r")
3392 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
3395 [(set_attr "conds" "set")])
3397 (define_insn "*cmpsf_insn"
3399 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
3400 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3405 [(set_attr "conds" "set")
3406 (set_attr "type" "f_2_r")])
3408 (define_insn "*cmpdf_insn"
3410 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
3411 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3416 [(set_attr "conds" "set")
3417 (set_attr "type" "f_2_r")])
3419 (define_insn "*cmpesfdf_df"
3421 (compare:CCFP (float_extend:DF
3422 (match_operand:SF 0 "s_register_operand" "f,f"))
3423 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3428 [(set_attr "conds" "set")
3429 (set_attr "type" "f_2_r")])
3431 (define_insn "*cmpdf_esfdf"
3433 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
3435 (match_operand:SF 1 "s_register_operand" "f"))))]
3438 [(set_attr "conds" "set")
3439 (set_attr "type" "f_2_r")])
3441 (define_insn "*cmpxf_insn"
3443 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
3444 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3445 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3449 [(set_attr "conds" "set")
3450 (set_attr "type" "f_2_r")])
3452 (define_insn "*cmpsf_trap"
3453 [(set (reg:CCFPE 24)
3454 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
3455 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3460 [(set_attr "conds" "set")
3461 (set_attr "type" "f_2_r")])
3463 (define_insn "*cmpdf_trap"
3464 [(set (reg:CCFPE 24)
3465 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
3466 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3471 [(set_attr "conds" "set")
3472 (set_attr "type" "f_2_r")])
3474 (define_insn "*cmp_esfdf_df_trap"
3475 [(set (reg:CCFPE 24)
3476 (compare:CCFPE (float_extend:DF
3477 (match_operand:SF 0 "s_register_operand" "f,f"))
3478 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3483 [(set_attr "conds" "set")
3484 (set_attr "type" "f_2_r")])
3486 (define_insn "*cmp_df_esfdf_trap"
3487 [(set (reg:CCFPE 24)
3488 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
3490 (match_operand:SF 1 "s_register_operand" "f"))))]
3493 [(set_attr "conds" "set")
3494 (set_attr "type" "f_2_r")])
3496 (define_insn "*cmpxf_trap"
3497 [(set (reg:CCFPE 24)
3498 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
3499 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3500 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3504 [(set_attr "conds" "set")
3505 (set_attr "type" "f_2_r")])
3507 ; This insn allows redundant compares to be removed by cse, nothing should
3508 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
3509 ; is deleted later on. The match_dup will match the mode here, so that
3510 ; mode changes of the condition codes aren't lost by this even though we don't
3511 ; specify what they are.
3513 (define_insn "*deleted_compare"
3514 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
3516 "\\t%@ deleted compare"
3517 [(set_attr "conds" "set")
3518 (set_attr "length" "0")])
3521 ;; Conditional branch insns
3523 (define_expand "beq"
3525 (if_then_else (eq (match_dup 1) (const_int 0))
3526 (label_ref (match_operand 0 "" ""))
3531 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3536 (define_expand "bne"
3538 (if_then_else (ne (match_dup 1) (const_int 0))
3539 (label_ref (match_operand 0 "" ""))
3544 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3549 (define_expand "bgt"
3551 (if_then_else (gt (match_dup 1) (const_int 0))
3552 (label_ref (match_operand 0 "" ""))
3557 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3562 (define_expand "ble"
3564 (if_then_else (le (match_dup 1) (const_int 0))
3565 (label_ref (match_operand 0 "" ""))
3570 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3575 (define_expand "bge"
3577 (if_then_else (ge (match_dup 1) (const_int 0))
3578 (label_ref (match_operand 0 "" ""))
3583 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3588 (define_expand "blt"
3590 (if_then_else (lt (match_dup 1) (const_int 0))
3591 (label_ref (match_operand 0 "" ""))
3596 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3601 (define_expand "bgtu"
3603 (if_then_else (gtu (match_dup 1) (const_int 0))
3604 (label_ref (match_operand 0 "" ""))
3609 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3614 (define_expand "bleu"
3616 (if_then_else (leu (match_dup 1) (const_int 0))
3617 (label_ref (match_operand 0 "" ""))
3622 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3627 (define_expand "bgeu"
3629 (if_then_else (geu (match_dup 1) (const_int 0))
3630 (label_ref (match_operand 0 "" ""))
3635 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3640 (define_expand "bltu"
3642 (if_then_else (ltu (match_dup 1) (const_int 0))
3643 (label_ref (match_operand 0 "" ""))
3648 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3653 ;; patterns to match conditional branch insns
3655 (define_insn "*condbranch"
3657 (if_then_else (match_operator 1 "comparison_operator"
3658 [(match_operand 2 "cc_register" "") (const_int 0)])
3659 (label_ref (match_operand 0 "" ""))
3664 extern int arm_ccfsm_state;
3666 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3668 arm_ccfsm_state += 2;
3671 return \"b%d1\\t%l0\";
3673 [(set_attr "conds" "use")])
3675 (define_insn "*condbranch_reversed"
3677 (if_then_else (match_operator 1 "comparison_operator"
3678 [(match_operand 2 "cc_register" "") (const_int 0)])
3680 (label_ref (match_operand 0 "" ""))))]
3684 extern int arm_ccfsm_state;
3686 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3688 arm_ccfsm_state += 2;
3691 return \"b%D1\\t%l0\";
3693 [(set_attr "conds" "use")])
3698 (define_expand "seq"
3699 [(set (match_operand:SI 0 "s_register_operand" "=r")
3700 (eq:SI (match_dup 1) (const_int 0)))]
3704 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3709 (define_expand "sne"
3710 [(set (match_operand:SI 0 "s_register_operand" "=r")
3711 (ne:SI (match_dup 1) (const_int 0)))]
3715 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3720 (define_expand "sgt"
3721 [(set (match_operand:SI 0 "s_register_operand" "=r")
3722 (gt:SI (match_dup 1) (const_int 0)))]
3726 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3731 (define_expand "sle"
3732 [(set (match_operand:SI 0 "s_register_operand" "=r")
3733 (le:SI (match_dup 1) (const_int 0)))]
3737 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3742 (define_expand "sge"
3743 [(set (match_operand:SI 0 "s_register_operand" "=r")
3744 (ge:SI (match_dup 1) (const_int 0)))]
3748 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3753 (define_expand "slt"
3754 [(set (match_operand:SI 0 "s_register_operand" "=r")
3755 (lt:SI (match_dup 1) (const_int 0)))]
3759 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3764 (define_expand "sgtu"
3765 [(set (match_operand:SI 0 "s_register_operand" "=r")
3766 (gtu:SI (match_dup 1) (const_int 0)))]
3770 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3775 (define_expand "sleu"
3776 [(set (match_operand:SI 0 "s_register_operand" "=r")
3777 (leu:SI (match_dup 1) (const_int 0)))]
3781 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3786 (define_expand "sgeu"
3787 [(set (match_operand:SI 0 "s_register_operand" "=r")
3788 (geu:SI (match_dup 1) (const_int 0)))]
3792 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3797 (define_expand "sltu"
3798 [(set (match_operand:SI 0 "s_register_operand" "=r")
3799 (ltu:SI (match_dup 1) (const_int 0)))]
3803 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3808 (define_insn "*mov_scc"
3809 [(set (match_operand:SI 0 "s_register_operand" "=r")
3810 (match_operator:SI 1 "comparison_operator"
3811 [(match_operand 2 "cc_register" "") (const_int 0)]))]
3813 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3814 [(set_attr "conds" "use")
3815 (set_attr "length" "8")])
3817 (define_insn "*mov_negscc"
3818 [(set (match_operand:SI 0 "s_register_operand" "=r")
3819 (neg:SI (match_operator:SI 1 "comparison_operator"
3820 [(match_operand 2 "cc_register" "") (const_int 0)])))]
3822 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3823 [(set_attr "conds" "use")
3824 (set_attr "length" "8")])
3826 (define_insn "*mov_notscc"
3827 [(set (match_operand:SI 0 "s_register_operand" "=r")
3828 (not:SI (match_operator:SI 1 "comparison_operator"
3829 [(match_operand 2 "cc_register" "") (const_int 0)])))]
3831 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3832 [(set_attr "conds" "use")
3833 (set_attr "length" "8")])
3836 ;; Conditional move insns
3838 (define_expand "movsicc"
3839 [(set (match_operand:SI 0 "s_register_operand" "")
3840 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3841 (match_operand:SI 2 "arm_not_operand" "")
3842 (match_operand:SI 3 "arm_not_operand" "")))]
3846 enum rtx_code code = GET_CODE (operands[1]);
3847 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3850 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3853 (define_expand "movsfcc"
3854 [(set (match_operand:SF 0 "s_register_operand" "")
3855 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3856 (match_operand:SF 2 "s_register_operand" "")
3857 (match_operand:SF 3 "nonmemory_operand" "")))]
3861 enum rtx_code code = GET_CODE (operands[1]);
3862 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3865 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3868 (define_expand "movdfcc"
3869 [(set (match_operand:DF 0 "s_register_operand" "")
3870 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3871 (match_operand:DF 2 "s_register_operand" "")
3872 (match_operand:DF 3 "nonmemory_operand" "")))]
3876 enum rtx_code code = GET_CODE (operands[1]);
3877 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
3880 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
3883 (define_insn "*movsicc_insn"
3884 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
3886 (match_operator 3 "comparison_operator"
3887 [(match_operand 4 "cc_register" "") (const_int 0)])
3888 (match_operand:SI 1 "arm_not_operand" "0,0,?rI,?rI,K,K")
3889 (match_operand:SI 2 "arm_not_operand" "rI,K,rI,K,rI,K")))]
3894 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
3895 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
3896 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
3897 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
3898 [(set_attr "length" "4,4,8,8,8,8")
3899 (set_attr "conds" "use")])
3901 (define_insn "*movsfcc_hard_insn"
3902 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
3903 (if_then_else:SF (match_operator 3 "comparison_operator"
3904 [(match_operand 4 "cc_register" "") (const_int 0)])
3905 (match_operand:SF 1 "s_register_operand" "0,0")
3906 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
3911 [(set_attr "type" "ffarith")
3912 (set_attr "conds" "use")])
3914 (define_insn "*movsfcc_soft_insn"
3915 [(set (match_operand:SF 0 "s_register_operand" "=r")
3916 (if_then_else:SF (match_operator 3 "comparison_operator"
3917 [(match_operand 4 "cc_register" "") (const_int 0)])
3918 (match_operand:SF 1 "s_register_operand" "0")
3919 (match_operand:SF 2 "s_register_operand" "r")))]
3922 [(set_attr "conds" "use")])
3924 (define_insn "*movdfcc_insn"
3925 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
3926 (if_then_else:DF (match_operator 3 "comparison_operator"
3927 [(match_operand 4 "cc_register" "") (const_int 0)])
3928 (match_operand:DF 1 "s_register_operand" "0,0")
3929 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
3934 [(set_attr "type" "ffarith")
3935 (set_attr "conds" "use")])
3937 ;; Jump and linkage insns
3941 (label_ref (match_operand 0 "" "")))]
3945 extern int arm_ccfsm_state;
3947 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3949 arm_ccfsm_state += 2;
3952 return \"b%?\\t%l0\";
3955 (define_expand "call"
3956 [(parallel [(call (match_operand 0 "memory_operand" "")
3957 (match_operand 1 "general_operand" ""))
3958 (clobber (reg:SI 14))])]
3962 (define_insn "*call_reg"
3963 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
3964 (match_operand 1 "" "g"))
3965 (clobber (reg:SI 14))]
3968 return output_call (operands);
3970 ;; length is worst case, normally it is only two
3971 [(set_attr "length" "12")
3972 (set_attr "type" "call")])
3974 (define_insn "*call_mem"
3975 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
3976 (match_operand 1 "general_operand" "g"))
3977 (clobber (reg:SI 14))]
3980 return output_call_mem (operands);
3982 [(set_attr "length" "12")
3983 (set_attr "type" "call")])
3985 (define_expand "call_value"
3986 [(parallel [(set (match_operand 0 "" "=rf")
3987 (call (match_operand 1 "memory_operand" "m")
3988 (match_operand 2 "general_operand" "g")))
3989 (clobber (reg:SI 14))])]
3993 (define_insn "*call_value_reg"
3994 [(set (match_operand 0 "" "=rf")
3995 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
3996 (match_operand 2 "general_operand" "g")))
3997 (clobber (reg:SI 14))]
4000 return output_call (&operands[1]);
4002 [(set_attr "length" "12")
4003 (set_attr "type" "call")])
4005 (define_insn "*call_value_mem"
4006 [(set (match_operand 0 "" "=rf")
4007 (call (mem:SI (match_operand 1 "memory_operand" "m"))
4008 (match_operand 2 "general_operand" "g")))
4009 (clobber (reg:SI 14))]
4010 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
4012 return output_call_mem (&operands[1]);
4014 [(set_attr "length" "12")
4015 (set_attr "type" "call")])
4017 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
4018 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
4020 (define_insn "*call_symbol"
4021 [(call (mem:SI (match_operand:SI 0 "" "X"))
4022 (match_operand:SI 1 "general_operand" "g"))
4023 (clobber (reg:SI 14))]
4024 "GET_CODE (operands[0]) == SYMBOL_REF"
4026 [(set_attr "type" "call")])
4028 (define_insn "*call_value_symbol"
4029 [(set (match_operand 0 "s_register_operand" "=rf")
4030 (call (mem:SI (match_operand:SI 1 "" "X"))
4031 (match_operand:SI 2 "general_operand" "g")))
4032 (clobber (reg:SI 14))]
4033 "GET_CODE(operands[1]) == SYMBOL_REF"
4035 [(set_attr "type" "call")])
4037 ;; Often the return insn will be the same as loading from memory, so set attr
4038 (define_insn "return"
4043 extern int arm_ccfsm_state;
4045 if (arm_ccfsm_state == 2)
4047 arm_ccfsm_state += 2;
4050 return output_return_instruction (NULL, TRUE, FALSE);
4052 [(set_attr "type" "load")])
4054 (define_insn "*cond_return"
4056 (if_then_else (match_operator 0 "comparison_operator"
4057 [(match_operand 1 "cc_register" "") (const_int 0)])
4063 extern int arm_ccfsm_state;
4065 if (arm_ccfsm_state == 2)
4067 arm_ccfsm_state += 2;
4070 return output_return_instruction (operands[0], TRUE, FALSE);
4072 [(set_attr "conds" "use")
4073 (set_attr "type" "load")])
4075 (define_insn "*cond_return_inverted"
4077 (if_then_else (match_operator 0 "comparison_operator"
4078 [(match_operand 1 "cc_register" "") (const_int 0)])
4084 extern int arm_ccfsm_state;
4086 if (arm_ccfsm_state == 2)
4088 arm_ccfsm_state += 2;
4091 return output_return_instruction (operands[0], TRUE, TRUE);
4093 [(set_attr "conds" "use")
4094 (set_attr "type" "load")])
4096 ;; Call subroutine returning any type.
4098 (define_expand "untyped_call"
4099 [(parallel [(call (match_operand 0 "" "")
4101 (match_operand 1 "" "")
4102 (match_operand 2 "" "")])]
4108 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4110 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4112 rtx set = XVECEXP (operands[2], 0, i);
4113 emit_move_insn (SET_DEST (set), SET_SRC (set));
4116 /* The optimizer does not know that the call sets the function value
4117 registers we stored in the result block. We avoid problems by
4118 claiming that all hard registers are used and clobbered at this
4120 emit_insn (gen_blockage ());
4125 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4126 ;; all of memory. This blocks insns from being moved across this point.
4128 (define_insn "blockage"
4129 [(unspec_volatile [(const_int 0)] 0)]
4132 [(set_attr "length" "0")
4133 (set_attr "type" "block")])
4135 (define_expand "casesi"
4136 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
4137 (match_operand:SI 1 "const_int_operand" "") ; lower bound
4138 (match_operand:SI 2 "const_int_operand" "") ; total range
4139 (match_operand:SI 3 "" "") ; table label
4140 (match_operand:SI 4 "" "")] ; Out of range label
4145 if (operands[1] != const0_rtx)
4147 reg = gen_reg_rtx (SImode);
4148 emit_insn (gen_addsi3 (reg, operands[0],
4149 GEN_INT (-INTVAL (operands[1]))));
4153 if (! const_ok_for_arm (INTVAL (operands[2])))
4154 operands[2] = force_reg (SImode, operands[2]);
4156 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
4161 (define_insn "casesi_internal"
4164 (leu (match_operand:SI 0 "s_register_operand" "r")
4165 (match_operand:SI 1 "arm_rhs_operand" "rI"))
4166 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
4167 (label_ref (match_operand 2 "" ""))))
4168 (label_ref (match_operand 3 "" ""))))]
4172 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
4173 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
4175 [(set_attr "conds" "clob")
4176 (set_attr "length" "12")])
4178 (define_insn "indirect_jump"
4180 (match_operand:SI 0 "s_register_operand" "r"))]
4182 "mov%?\\t%|pc, %0\\t%@ indirect jump")
4184 (define_insn "*load_indirect_jump"
4186 (match_operand:SI 0 "memory_operand" "m"))]
4188 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
4189 [(set_attr "type" "load")])
4196 "mov%?\\tr0, r0\\t%@ nop")
4198 ;; Patterns to allow combination of arithmetic, cond code and shifts
4200 (define_insn "*arith_shiftsi"
4201 [(set (match_operand:SI 0 "s_register_operand" "=r")
4202 (match_operator:SI 1 "shiftable_operator"
4203 [(match_operator:SI 3 "shift_operator"
4204 [(match_operand:SI 4 "s_register_operand" "r")
4205 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4206 (match_operand:SI 2 "s_register_operand" "r")]))]
4208 "%i1%?\\t%0, %2, %4%S3")
4210 (define_insn "*arith_shiftsi_compare0"
4211 [(set (reg:CC_NOOV 24)
4212 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4213 [(match_operator:SI 3 "shift_operator"
4214 [(match_operand:SI 4 "s_register_operand" "r")
4215 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4216 (match_operand:SI 2 "s_register_operand" "r")])
4218 (set (match_operand:SI 0 "s_register_operand" "=r")
4219 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
4222 "%i1%?s\\t%0, %2, %4%S3"
4223 [(set_attr "conds" "set")])
4225 (define_insn "*arith_shiftsi_compare0_scratch"
4226 [(set (reg:CC_NOOV 24)
4227 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4228 [(match_operator:SI 3 "shift_operator"
4229 [(match_operand:SI 4 "s_register_operand" "r")
4230 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4231 (match_operand:SI 2 "s_register_operand" "r")])
4233 (clobber (match_scratch:SI 0 "=r"))]
4235 "%i1%?s\\t%0, %2, %4%S3"
4236 [(set_attr "conds" "set")])
4238 (define_insn "*sub_shiftsi"
4239 [(set (match_operand:SI 0 "s_register_operand" "=r")
4240 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4241 (match_operator:SI 2 "shift_operator"
4242 [(match_operand:SI 3 "s_register_operand" "r")
4243 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
4245 "sub%?\\t%0, %1, %3%S2")
4247 (define_insn "*sub_shiftsi_compare0"
4248 [(set (reg:CC_NOOV 24)
4250 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4251 (match_operator:SI 2 "shift_operator"
4252 [(match_operand:SI 3 "s_register_operand" "r")
4253 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4255 (set (match_operand:SI 0 "s_register_operand" "=r")
4256 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4259 "sub%?s\\t%0, %1, %3%S2"
4260 [(set_attr "conds" "set")])
4262 (define_insn "*sub_shiftsi_compare0_scratch"
4263 [(set (reg:CC_NOOV 24)
4265 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4266 (match_operator:SI 2 "shift_operator"
4267 [(match_operand:SI 3 "s_register_operand" "r")
4268 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4270 (clobber (match_scratch:SI 0 "=r"))]
4272 "sub%?s\\t%0, %1, %3%S2"
4273 [(set_attr "conds" "set")])
4275 ;; These variants of the above insns can occur if the first operand is the
4276 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
4277 ;; seem to be a way around it. Most of the predicates have to be null
4278 ;; because the format can be generated part way through reload, so
4279 ;; if we don't match it as soon as it becomes available, reload doesn't know
4280 ;; how to reload pseudos that haven't got hard registers; the constraints will
4281 ;; sort everything out.
4283 (define_insn "*reload_mulsi3"
4284 [(set (match_operand:SI 0 "" "=&r")
4285 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
4286 [(match_operand:SI 3 "" "r")
4287 (match_operand:SI 4 "" "rM")])
4288 (match_operand:SI 2 "" "r"))
4289 (match_operand:SI 1 "const_int_operand" "n")))]
4290 "reload_in_progress"
4292 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
4293 operands[2] = operands[1];
4294 operands[1] = operands[0];
4295 return output_add_immediate (operands);
4297 ; we have no idea how long the add_immediate is, it could be up to 4.
4298 [(set_attr "length" "20")])
4300 (define_insn "*reload_mulsi_compare0"
4301 [(set (reg:CC_NOOV 24)
4302 (compare:CC_NOOV (plus:SI
4304 (match_operator:SI 5 "shift_operator"
4305 [(match_operand:SI 3 "" "r")
4306 (match_operand:SI 4 "" "rM")])
4307 (match_operand:SI 1 "" "r"))
4308 (match_operand:SI 2 "const_int_operand" "n"))
4310 (set (match_operand:SI 0 "" "=&r")
4311 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
4314 "reload_in_progress"
4316 output_add_immediate (operands);
4317 return \"add%?s\\t%0, %0, %3%S5\";
4319 [(set_attr "conds" "set")
4320 (set_attr "length" "20")])
4322 (define_insn "*reload_mulsi_compare0_scratch"
4323 [(set (reg:CC_NOOV 24)
4324 (compare:CC_NOOV (plus:SI
4326 (match_operator:SI 5 "shift_operator"
4327 [(match_operand:SI 3 "" "r")
4328 (match_operand:SI 4 "" "rM")])
4329 (match_operand:SI 1 "" "r"))
4330 (match_operand:SI 2 "const_int_operand" "n"))
4332 (clobber (match_scratch:SI 0 "=&r"))]
4333 "reload_in_progress"
4335 output_add_immediate (operands);
4336 return \"add%?s\\t%0, %0, %3%S5\";
4338 [(set_attr "conds" "set")
4339 (set_attr "length" "20")])
4341 ;; These are similar, but are needed when the mla pattern contains the
4342 ;; eliminated register as operand 3.
4344 (define_insn "*reload_muladdsi"
4345 [(set (match_operand:SI 0 "" "=&r,&r")
4346 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
4347 (match_operand:SI 2 "" "r,r"))
4348 (match_operand:SI 3 "" "r,r"))
4349 (match_operand:SI 4 "const_int_operand" "n,n")))]
4350 "reload_in_progress"
4352 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
4353 operands[2] = operands[4];
4354 operands[1] = operands[0];
4355 return output_add_immediate (operands);
4357 [(set_attr "length" "20")
4358 (set_attr "type" "mult")])
4360 (define_insn "*reload_muladdsi_compare0"
4361 [(set (reg:CC_NOOV 24)
4362 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4363 (match_operand:SI 3 "" "r")
4364 (match_operand:SI 4 "" "r"))
4365 (match_operand:SI 1 "" "r"))
4366 (match_operand:SI 2 "const_int_operand" "n"))
4368 (set (match_operand:SI 0 "" "=&r")
4369 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
4371 "reload_in_progress"
4373 output_add_immediate (operands);
4374 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
4377 [(set_attr "length" "20")
4378 (set_attr "conds" "set")
4379 (set_attr "type" "mult")])
4381 (define_insn "*reload_muladdsi_compare0_scratch"
4382 [(set (reg:CC_NOOV 24)
4383 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4384 (match_operand:SI 3 "" "r")
4385 (match_operand:SI 4 "" "r"))
4386 (match_operand:SI 1 "" "r"))
4387 (match_operand:SI 2 "const_int_operand" "n"))
4389 (clobber (match_scratch:SI 0 "=&r"))]
4390 "reload_in_progress"
4392 output_add_immediate (operands);
4393 return \"mla%?s\\t%0, %3, %4, %0\";
4395 [(set_attr "length" "20")
4396 (set_attr "conds" "set")
4397 (set_attr "type" "mult")])
4401 (define_insn "*and_scc"
4402 [(set (match_operand:SI 0 "s_register_operand" "=r")
4403 (and:SI (match_operator 1 "comparison_operator"
4404 [(match_operand 3 "cc_register" "") (const_int 0)])
4405 (match_operand:SI 2 "s_register_operand" "r")))]
4407 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
4408 [(set_attr "conds" "use")
4409 (set_attr "length" "8")])
4411 (define_insn "*ior_scc"
4412 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4413 (ior:SI (match_operator 2 "comparison_operator"
4414 [(match_operand 3 "cc_register" "") (const_int 0)])
4415 (match_operand:SI 1 "s_register_operand" "0,?r")))]
4419 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
4420 [(set_attr "conds" "use")
4421 (set_attr "length" "4,8")])
4423 (define_insn "*compare_scc"
4424 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4425 (match_operator 1 "comparison_operator"
4426 [(match_operand:SI 2 "s_register_operand" "r,r")
4427 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
4431 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
4432 return \"mov\\t%0, %2, lsr #31\";
4434 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
4435 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
4437 if (GET_CODE (operands[1]) == NE)
4439 if (which_alternative == 1)
4440 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
4441 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
4443 if (which_alternative == 1)
4444 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4446 output_asm_insn (\"cmp\\t%2, %3\", operands);
4447 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
4449 [(set_attr "conds" "clob")
4450 (set_attr "length" "12")])
4452 (define_insn "*cond_move"
4453 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4454 (if_then_else:SI (match_operator 3 "equality_operator"
4455 [(match_operator 4 "comparison_operator"
4456 [(match_operand 5 "cc_register" "") (const_int 0)])
4458 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4459 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
4462 if (GET_CODE (operands[3]) == NE)
4464 if (which_alternative != 1)
4465 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4466 if (which_alternative != 0)
4467 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
4470 if (which_alternative != 0)
4471 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4472 if (which_alternative != 1)
4473 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
4476 [(set_attr "conds" "use")
4477 (set_attr "length" "4,4,8")])
4479 (define_insn "*cond_arith"
4480 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4481 (match_operator:SI 5 "shiftable_operator"
4482 [(match_operator:SI 4 "comparison_operator"
4483 [(match_operand:SI 2 "s_register_operand" "r,r")
4484 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4485 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4489 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4490 return \"%i5\\t%0, %1, %2, lsr #31\";
4492 output_asm_insn (\"cmp\\t%2, %3\", operands);
4493 if (GET_CODE (operands[5]) == AND)
4494 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4495 else if (GET_CODE (operands[5]) == MINUS)
4496 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
4497 else if (which_alternative != 0)
4498 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4499 return \"%i5%d4\\t%0, %1, #1\";
4501 [(set_attr "conds" "clob")
4502 (set_attr "length" "12")])
4504 (define_insn "*cond_sub"
4505 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4506 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4507 (match_operator:SI 4 "comparison_operator"
4508 [(match_operand:SI 2 "s_register_operand" "r,r")
4509 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4513 output_asm_insn (\"cmp\\t%2, %3\", operands);
4514 if (which_alternative != 0)
4515 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4516 return \"sub%d4\\t%0, %1, #1\";
4518 [(set_attr "conds" "clob")
4519 (set_attr "length" "8,12")])
4521 (define_insn "*cmp_ite0"
4522 [(set (match_operand 6 "dominant_cc_register" "")
4525 (match_operator 4 "comparison_operator"
4526 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4527 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4528 (match_operator:SI 5 "comparison_operator"
4529 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4530 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4536 char* opcodes[4][2] =
4538 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
4539 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
4540 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
4541 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
4542 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
4545 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
4547 return opcodes[which_alternative][swap];
4550 [(set_attr "conds" "set")
4551 (set_attr "length" "8")])
4553 (define_insn "*cmp_ite1"
4554 [(set (match_operand 6 "dominant_cc_register" "")
4557 (match_operator 4 "comparison_operator"
4558 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4559 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4560 (match_operator:SI 5 "comparison_operator"
4561 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4562 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4568 char* opcodes[4][2] =
4570 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
4571 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
4572 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
4573 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
4574 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
4577 comparison_dominates_p (GET_CODE (operands[5]),
4578 reverse_condition (GET_CODE (operands[4])));
4580 return opcodes[which_alternative][swap];
4583 [(set_attr "conds" "set")
4584 (set_attr "length" "8")])
4586 (define_insn "*negscc"
4587 [(set (match_operand:SI 0 "s_register_operand" "=r")
4588 (neg:SI (match_operator 3 "comparison_operator"
4589 [(match_operand:SI 1 "s_register_operand" "r")
4590 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4594 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4595 return \"mov\\t%0, %1, asr #31\";
4597 if (GET_CODE (operands[3]) == NE)
4598 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4600 if (GET_CODE (operands[3]) == GT)
4601 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4603 output_asm_insn (\"cmp\\t%1, %2\", operands);
4604 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4605 return \"mvn%d3\\t%0, #0\";
4607 [(set_attr "conds" "clob")
4608 (set_attr "length" "12")])
4610 (define_insn "movcond"
4611 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4613 (match_operator 5 "comparison_operator"
4614 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4615 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4616 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4617 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4621 if (GET_CODE (operands[5]) == LT
4622 && (operands[4] == const0_rtx))
4624 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4626 if (operands[2] == const0_rtx)
4627 return \"and\\t%0, %1, %3, asr #31\";
4628 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4630 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4632 if (operands[1] == const0_rtx)
4633 return \"bic\\t%0, %2, %3, asr #31\";
4634 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4636 /* The only case that falls through to here is when both ops 1 & 2
4640 if (GET_CODE (operands[5]) == GE
4641 && (operands[4] == const0_rtx))
4643 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4645 if (operands[2] == const0_rtx)
4646 return \"bic\\t%0, %1, %3, asr #31\";
4647 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4649 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4651 if (operands[1] == const0_rtx)
4652 return \"and\\t%0, %2, %3, asr #31\";
4653 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4655 /* The only case that falls through to here is when both ops 1 & 2
4658 if (GET_CODE (operands[4]) == CONST_INT
4659 && !const_ok_for_arm (INTVAL (operands[4])))
4660 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4662 output_asm_insn (\"cmp\\t%3, %4\", operands);
4663 if (which_alternative != 0)
4664 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4665 if (which_alternative != 1)
4666 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4669 [(set_attr "conds" "clob")
4670 (set_attr "length" "8,8,12")])
4672 (define_insn "*ifcompare_plus_move"
4673 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4674 (if_then_else:SI (match_operator 6 "comparison_operator"
4675 [(match_operand:SI 4 "s_register_operand" "r,r")
4676 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4678 (match_operand:SI 2 "s_register_operand" "r,r")
4679 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
4680 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4684 [(set_attr "conds" "clob")
4685 (set_attr "length" "8,12")])
4687 (define_insn "*if_plus_move"
4688 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
4690 (match_operator 4 "comparison_operator"
4691 [(match_operand 5 "cc_register" "") (const_int 0)])
4693 (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
4694 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))
4695 (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")))]
4699 sub%d4\\t%0, %2, #%n3
4700 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
4701 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1
4702 add%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1
4703 sub%d4\\t%0, %2, #%n3\;ldr%D4\\t%0, %1"
4704 [(set_attr "conds" "use")
4705 (set_attr "length" "4,4,8,8,8,8")
4706 (set_attr "type" "*,*,*,*,load,load")])
4708 (define_insn "*ifcompare_move_plus"
4709 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4710 (if_then_else:SI (match_operator 6 "comparison_operator"
4711 [(match_operand:SI 4 "s_register_operand" "r,r")
4712 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4713 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4715 (match_operand:SI 2 "s_register_operand" "r,r")
4716 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4720 [(set_attr "conds" "clob")
4721 (set_attr "length" "8,12")])
4723 (define_insn "*if_move_plus"
4724 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
4726 (match_operator 4 "comparison_operator"
4727 [(match_operand 5 "cc_register" "") (const_int 0)])
4728 (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")
4730 (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
4731 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))))]
4735 sub%D4\\t%0, %2, #%n3
4736 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
4737 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1
4738 add%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1
4739 sub%D4\\t%0, %2, #%n3\;ldr%d4\\t%0, %1"
4740 [(set_attr "conds" "use")
4741 (set_attr "length" "4,4,8,8,8,8")
4742 (set_attr "type" "*,*,*,*,load,load")])
4744 (define_insn "*ifcompare_arith_arith"
4745 [(set (match_operand:SI 0 "s_register_operand" "=r")
4746 (if_then_else:SI (match_operator 9 "comparison_operator"
4747 [(match_operand:SI 5 "s_register_operand" "r")
4748 (match_operand:SI 6 "arm_add_operand" "rIL")])
4749 (match_operator:SI 8 "shiftable_operator"
4750 [(match_operand:SI 1 "s_register_operand" "r")
4751 (match_operand:SI 2 "arm_rhs_operand" "rI")])
4752 (match_operator:SI 7 "shiftable_operator"
4753 [(match_operand:SI 3 "s_register_operand" "r")
4754 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4758 [(set_attr "conds" "clob")
4759 (set_attr "length" "12")])
4761 (define_insn "*if_arith_arith"
4762 [(set (match_operand:SI 0 "s_register_operand" "=r")
4763 (if_then_else:SI (match_operator 5 "comparison_operator"
4764 [(match_operand 8 "cc_register" "") (const_int 0)])
4765 (match_operator:SI 6 "shiftable_operator"
4766 [(match_operand:SI 1 "s_register_operand" "r")
4767 (match_operand:SI 2 "arm_rhs_operand" "rI")])
4768 (match_operator:SI 7 "shiftable_operator"
4769 [(match_operand:SI 3 "s_register_operand" "r")
4770 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
4772 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
4773 [(set_attr "conds" "use")
4774 (set_attr "length" "8")])
4776 (define_insn "*ifcompare_arith_move"
4777 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4778 (if_then_else:SI (match_operator 6 "comparison_operator"
4779 [(match_operand:SI 2 "s_register_operand" "r,r")
4780 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4781 (match_operator:SI 7 "shiftable_operator"
4782 [(match_operand:SI 4 "s_register_operand" "r,r")
4783 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4784 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4788 /* If we have an operation where (op x 0) is the identity operation and
4789 the conditional operator is LT or GE and we are comparing against zero and
4790 everything is in registers then we can do this in two instructions */
4791 if (operands[3] == const0_rtx
4792 && GET_CODE (operands[7]) != AND
4793 && GET_CODE (operands[5]) == REG
4794 && GET_CODE (operands[1]) == REG
4795 && REGNO (operands[1]) == REGNO (operands[4])
4796 && REGNO (operands[4]) != REGNO (operands[0]))
4798 if (GET_CODE (operands[6]) == LT)
4799 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4800 else if (GET_CODE (operands[6]) == GE)
4801 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4803 if (GET_CODE (operands[3]) == CONST_INT
4804 && !const_ok_for_arm (INTVAL (operands[3])))
4805 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4807 output_asm_insn (\"cmp\\t%2, %3\", operands);
4808 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
4809 if (which_alternative != 0)
4811 if (GET_CODE (operands[1]) == MEM)
4812 return \"ldr%D6\\t%0, %1\";
4814 return \"mov%D6\\t%0, %1\";
4818 [(set_attr "conds" "clob")
4819 (set_attr "length" "8,12")])
4821 (define_insn "*if_arith_move"
4822 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4823 (if_then_else:SI (match_operator 4 "comparison_operator"
4824 [(match_operand 6 "cc_register" "") (const_int 0)])
4825 (match_operator:SI 5 "shiftable_operator"
4826 [(match_operand:SI 2 "s_register_operand" "r,r,r")
4827 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])
4828 (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")))]
4832 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
4833 %I5%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1"
4834 [(set_attr "conds" "use")
4835 (set_attr "length" "4,8,8")
4836 (set_attr "type" "*,*,load")])
4838 (define_insn "*ifcompare_move_arith"
4839 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4840 (if_then_else:SI (match_operator 6 "comparison_operator"
4841 [(match_operand:SI 4 "s_register_operand" "r,r")
4842 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4843 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4844 (match_operator:SI 7 "shiftable_operator"
4845 [(match_operand:SI 2 "s_register_operand" "r,r")
4846 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4850 /* If we have an operation where (op x 0) is the identity operation and
4851 the conditional operator is LT or GE and we are comparing against zero and
4852 everything is in registers then we can do this in two instructions */
4853 if (operands[5] == const0_rtx
4854 && GET_CODE (operands[7]) != AND
4855 && GET_CODE (operands[3]) == REG
4856 && GET_CODE (operands[1]) == REG
4857 && REGNO (operands[1]) == REGNO (operands[2])
4858 && REGNO (operands[2]) != REGNO (operands[0]))
4860 if (GET_CODE (operands[6]) == GE)
4861 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4862 else if (GET_CODE (operands[6]) == LT)
4863 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
4866 if (GET_CODE (operands[5]) == CONST_INT
4867 && !const_ok_for_arm (INTVAL (operands[5])))
4868 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
4870 output_asm_insn (\"cmp\\t%4, %5\", operands);
4872 if (which_alternative != 0)
4874 if (GET_CODE (operands[1]) == MEM)
4875 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
4877 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
4879 return \"%I7%D6\\t%0, %2, %3\";
4881 [(set_attr "conds" "clob")
4882 (set_attr "length" "8,12")])
4884 (define_insn "*if_move_arith"
4885 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4887 (match_operator 4 "comparison_operator"
4888 [(match_operand 6 "cc_register" "") (const_int 0)])
4889 (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")
4890 (match_operator:SI 5 "shiftable_operator"
4891 [(match_operand:SI 2 "s_register_operand" "r,r,r")
4892 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])))]
4896 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
4897 %I5%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1"
4898 [(set_attr "conds" "use")
4899 (set_attr "length" "4,8,8")
4900 (set_attr "type" "*,*,load")])
4902 (define_insn "*ifcompare_move_not"
4903 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4905 (match_operator 5 "comparison_operator"
4906 [(match_operand:SI 3 "s_register_operand" "r,r")
4907 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4908 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
4910 (match_operand:SI 2 "s_register_operand" "r,r"))))
4914 [(set_attr "conds" "clob")
4915 (set_attr "length" "8,12")])
4917 (define_insn "*if_move_not"
4918 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4920 (match_operator 4 "comparison_operator"
4921 [(match_operand 3 "cc_register" "") (const_int 0)])
4922 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
4923 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
4927 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
4928 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
4929 [(set_attr "conds" "use")
4930 (set_attr "length" "4,8,8")])
4932 (define_insn "*ifcompare_not_move"
4933 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4935 (match_operator 5 "comparison_operator"
4936 [(match_operand:SI 3 "s_register_operand" "r,r")
4937 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
4939 (match_operand:SI 2 "s_register_operand" "r,r"))
4940 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
4944 [(set_attr "conds" "clob")
4945 (set_attr "length" "8,12")])
4947 (define_insn "*if_not_move"
4948 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4950 (match_operator 4 "comparison_operator"
4951 [(match_operand 3 "cc_register" "") (const_int 0)])
4952 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
4953 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
4957 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
4958 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
4959 [(set_attr "conds" "use")
4960 (set_attr "length" "4,8,8")])
4962 (define_insn "*ifcompare_shift_move"
4963 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4965 (match_operator 6 "comparison_operator"
4966 [(match_operand:SI 4 "s_register_operand" "r,r")
4967 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4968 (match_operator:SI 7 "shift_operator"
4969 [(match_operand:SI 2 "s_register_operand" "r,r")
4970 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
4971 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
4975 [(set_attr "conds" "clob")
4976 (set_attr "length" "8,12")])
4978 (define_insn "*if_shift_move"
4979 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4981 (match_operator 5 "comparison_operator"
4982 [(match_operand 6 "cc_register" "") (const_int 0)])
4983 (match_operator:SI 4 "shift_operator"
4984 [(match_operand:SI 2 "s_register_operand" "r,r,r")
4985 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
4986 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
4990 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
4991 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
4992 [(set_attr "conds" "use")
4993 (set_attr "length" "4,8,8")])
4995 (define_insn "*ifcompare_move_shift"
4996 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4998 (match_operator 6 "comparison_operator"
4999 [(match_operand:SI 4 "s_register_operand" "r,r")
5000 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5001 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5002 (match_operator:SI 7 "shift_operator"
5003 [(match_operand:SI 2 "s_register_operand" "r,r")
5004 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
5008 [(set_attr "conds" "clob")
5009 (set_attr "length" "8,12")])
5011 (define_insn "*if_move_shift"
5012 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5014 (match_operator 5 "comparison_operator"
5015 [(match_operand 6 "cc_register" "") (const_int 0)])
5016 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5017 (match_operator:SI 4 "shift_operator"
5018 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5019 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
5023 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
5024 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
5025 [(set_attr "conds" "use")
5026 (set_attr "length" "4,8,8")])
5028 (define_insn "*ifcompare_shift_shift"
5029 [(set (match_operand:SI 0 "s_register_operand" "=r")
5031 (match_operator 7 "comparison_operator"
5032 [(match_operand:SI 5 "s_register_operand" "r")
5033 (match_operand:SI 6 "arm_add_operand" "rIL")])
5034 (match_operator:SI 8 "shift_operator"
5035 [(match_operand:SI 1 "s_register_operand" "r")
5036 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5037 (match_operator:SI 9 "shift_operator"
5038 [(match_operand:SI 3 "s_register_operand" "r")
5039 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
5043 [(set_attr "conds" "clob")
5044 (set_attr "length" "12")])
5046 (define_insn "*if_shift_shift"
5047 [(set (match_operand:SI 0 "s_register_operand" "=r")
5049 (match_operator 5 "comparison_operator"
5050 [(match_operand 8 "cc_register" "") (const_int 0)])
5051 (match_operator:SI 6 "shift_operator"
5052 [(match_operand:SI 1 "s_register_operand" "r")
5053 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5054 (match_operator:SI 7 "shift_operator"
5055 [(match_operand:SI 3 "s_register_operand" "r")
5056 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
5058 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
5059 [(set_attr "conds" "use")
5060 (set_attr "length" "8")])
5062 (define_insn "*ifcompare_not_arith"
5063 [(set (match_operand:SI 0 "s_register_operand" "=r")
5065 (match_operator 6 "comparison_operator"
5066 [(match_operand:SI 4 "s_register_operand" "r")
5067 (match_operand:SI 5 "arm_add_operand" "rIL")])
5068 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5069 (match_operator:SI 7 "shiftable_operator"
5070 [(match_operand:SI 2 "s_register_operand" "r")
5071 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
5075 [(set_attr "conds" "clob")
5076 (set_attr "length" "12")])
5078 (define_insn "*if_not_arith"
5079 [(set (match_operand:SI 0 "s_register_operand" "=r")
5081 (match_operator 5 "comparison_operator"
5082 [(match_operand 4 "cc_register" "") (const_int 0)])
5083 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5084 (match_operator:SI 6 "shiftable_operator"
5085 [(match_operand:SI 2 "s_register_operand" "r")
5086 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
5088 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
5089 [(set_attr "conds" "use")
5090 (set_attr "length" "8")])
5092 (define_insn "*ifcompare_arith_not"
5093 [(set (match_operand:SI 0 "s_register_operand" "=r")
5095 (match_operator 6 "comparison_operator"
5096 [(match_operand:SI 4 "s_register_operand" "r")
5097 (match_operand:SI 5 "arm_add_operand" "rIL")])
5098 (match_operator:SI 7 "shiftable_operator"
5099 [(match_operand:SI 2 "s_register_operand" "r")
5100 (match_operand:SI 3 "arm_rhs_operand" "rI")])
5101 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
5105 [(set_attr "conds" "clob")
5106 (set_attr "length" "12")])
5108 (define_insn "*if_arith_not"
5109 [(set (match_operand:SI 0 "s_register_operand" "=r")
5111 (match_operator 5 "comparison_operator"
5112 [(match_operand 4 "cc_register" "") (const_int 0)])
5113 (match_operator:SI 6 "shiftable_operator"
5114 [(match_operand:SI 2 "s_register_operand" "r")
5115 (match_operand:SI 3 "arm_rhs_operand" "rI")])
5116 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
5118 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
5119 [(set_attr "conds" "use")
5120 (set_attr "length" "8")])
5122 (define_insn "*ifcompare_neg_move"
5123 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5125 (match_operator 5 "comparison_operator"
5126 [(match_operand:SI 3 "s_register_operand" "r,r")
5127 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5128 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
5129 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5130 (clobber (reg:CC 24))]
5133 [(set_attr "conds" "clob")
5134 (set_attr "length" "8,12")])
5136 (define_insn "*if_neg_move"
5137 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5139 (match_operator 4 "comparison_operator"
5140 [(match_operand 3 "cc_register" "") (const_int 0)])
5141 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
5142 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5146 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
5147 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
5148 [(set_attr "conds" "use")
5149 (set_attr "length" "4,8,8")])
5151 (define_insn "*ifcompare_move_neg"
5152 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5154 (match_operator 5 "comparison_operator"
5155 [(match_operand:SI 3 "s_register_operand" "r,r")
5156 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5157 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5158 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
5159 (clobber (reg:CC 24))]
5162 [(set_attr "conds" "clob")
5163 (set_attr "length" "8,12")])
5165 (define_insn "*if_move_neg"
5166 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5168 (match_operator 4 "comparison_operator"
5169 [(match_operand 3 "cc_register" "") (const_int 0)])
5170 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5171 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
5175 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
5176 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
5177 [(set_attr "conds" "use")
5178 (set_attr "length" "4,8,8")])
5180 (define_insn "*arith_adjacentmem"
5181 [(set (match_operand:SI 0 "s_register_operand" "=r")
5182 (match_operator:SI 1 "shiftable_operator"
5183 [(match_operand:SI 2 "memory_operand" "m")
5184 (match_operand:SI 3 "memory_operand" "m")]))
5185 (clobber (match_scratch:SI 4 "=r"))]
5186 "adjacent_mem_locations (operands[2], operands[3])"
5191 int val1 = 0, val2 = 0;
5193 if (REGNO (operands[0]) > REGNO (operands[4]))
5195 ldm[1] = operands[4];
5196 ldm[2] = operands[0];
5200 ldm[1] = operands[0];
5201 ldm[2] = operands[4];
5203 if (GET_CODE (XEXP (operands[2], 0)) != REG)
5204 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
5205 if (GET_CODE (XEXP (operands[3], 0)) != REG)
5206 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
5207 arith[0] = operands[0];
5208 arith[3] = operands[1];
5222 ldm[0] = ops[0] = operands[4];
5223 ops[1] = XEXP (XEXP (operands[2], 0), 0);
5224 ops[2] = XEXP (XEXP (operands[2], 0), 1);
5225 output_add_immediate (ops);
5227 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5229 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5233 ldm[0] = XEXP (operands[3], 0);
5235 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5237 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5241 ldm[0] = XEXP (operands[2], 0);
5243 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5245 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5247 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
5251 [(set_attr "length" "12")
5252 (set_attr "type" "load")])
5254 ;; the arm can support extended pre-inc instructions
5256 ;; In all these cases, we use operands 0 and 1 for the register being
5257 ;; incremented because those are the operands that local-alloc will
5258 ;; tie and these are the pair most likely to be tieable (and the ones
5259 ;; that will benefit the most).
5261 ;; We reject the frame pointer if it occurs anywhere in these patterns since
5262 ;; elimination will cause too many headaches.
5264 (define_insn "*strqi_preinc"
5265 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5266 (match_operand:SI 2 "index_operand" "rJ")))
5267 (match_operand:QI 3 "s_register_operand" "r"))
5268 (set (match_operand:SI 0 "s_register_operand" "=r")
5269 (plus:SI (match_dup 1) (match_dup 2)))]
5270 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5271 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5272 && (GET_CODE (operands[2]) != REG
5273 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5274 "str%?b\\t%3, [%0, %2]!"
5275 [(set_attr "type" "store1")])
5277 (define_insn "*strqi_predec"
5278 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5279 (match_operand:SI 2 "s_register_operand" "r")))
5280 (match_operand:QI 3 "s_register_operand" "r"))
5281 (set (match_operand:SI 0 "s_register_operand" "=r")
5282 (minus:SI (match_dup 1) (match_dup 2)))]
5283 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5284 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5285 && (GET_CODE (operands[2]) != REG
5286 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5287 "str%?b\\t%3, [%0, -%2]!"
5288 [(set_attr "type" "store1")])
5290 (define_insn "*loadqi_preinc"
5291 [(set (match_operand:QI 3 "s_register_operand" "=r")
5292 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5293 (match_operand:SI 2 "index_operand" "rJ"))))
5294 (set (match_operand:SI 0 "s_register_operand" "=r")
5295 (plus:SI (match_dup 1) (match_dup 2)))]
5296 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5297 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5298 && (GET_CODE (operands[2]) != REG
5299 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5300 "ldr%?b\\t%3, [%0, %2]!"
5301 [(set_attr "type" "load")])
5303 (define_insn "*loadqi_predec"
5304 [(set (match_operand:QI 3 "s_register_operand" "=r")
5305 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5306 (match_operand:SI 2 "s_register_operand" "r"))))
5307 (set (match_operand:SI 0 "s_register_operand" "=r")
5308 (minus:SI (match_dup 1) (match_dup 2)))]
5309 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5310 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5311 && (GET_CODE (operands[2]) != REG
5312 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5313 "ldr%?b\\t%3, [%0, -%2]!"
5314 [(set_attr "type" "load")])
5316 (define_insn "*loadqisi_preinc"
5317 [(set (match_operand:SI 3 "s_register_operand" "=r")
5319 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5320 (match_operand:SI 2 "index_operand" "rJ")))))
5321 (set (match_operand:SI 0 "s_register_operand" "=r")
5322 (plus:SI (match_dup 1) (match_dup 2)))]
5323 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5324 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5325 && (GET_CODE (operands[2]) != REG
5326 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5327 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
5328 [(set_attr "type" "load")])
5330 (define_insn "*loadqisi_predec"
5331 [(set (match_operand:SI 3 "s_register_operand" "=r")
5333 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5334 (match_operand:SI 2 "s_register_operand" "r")))))
5335 (set (match_operand:SI 0 "s_register_operand" "=r")
5336 (minus:SI (match_dup 1) (match_dup 2)))]
5337 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5338 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5339 && (GET_CODE (operands[2]) != REG
5340 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5341 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
5342 [(set_attr "type" "load")])
5344 (define_insn "*strsi_preinc"
5345 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5346 (match_operand:SI 2 "index_operand" "rJ")))
5347 (match_operand:SI 3 "s_register_operand" "r"))
5348 (set (match_operand:SI 0 "s_register_operand" "=r")
5349 (plus:SI (match_dup 1) (match_dup 2)))]
5350 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5351 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5352 && (GET_CODE (operands[2]) != REG
5353 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5354 "str%?\\t%3, [%0, %2]!"
5355 [(set_attr "type" "store1")])
5357 (define_insn "*strqi_predec"
5358 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5359 (match_operand:SI 2 "s_register_operand" "r")))
5360 (match_operand:SI 3 "s_register_operand" "r"))
5361 (set (match_operand:SI 0 "s_register_operand" "=r")
5362 (minus:SI (match_dup 1) (match_dup 2)))]
5363 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5364 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5365 && (GET_CODE (operands[2]) != REG
5366 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5367 "str%?\\t%3, [%0, -%2]!"
5368 [(set_attr "type" "store1")])
5370 (define_insn "*loadsi_preinc"
5371 [(set (match_operand:SI 3 "s_register_operand" "=r")
5372 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5373 (match_operand:SI 2 "index_operand" "rJ"))))
5374 (set (match_operand:SI 0 "s_register_operand" "=r")
5375 (plus:SI (match_dup 1) (match_dup 2)))]
5376 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5377 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5378 && (GET_CODE (operands[2]) != REG
5379 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5380 "ldr%?\\t%3, [%0, %2]!"
5381 [(set_attr "type" "load")])
5383 (define_insn "*loadsi_predec"
5384 [(set (match_operand:SI 3 "s_register_operand" "=r")
5385 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5386 (match_operand:SI 2 "s_register_operand" "r"))))
5387 (set (match_operand:SI 0 "s_register_operand" "=r")
5388 (minus:SI (match_dup 1) (match_dup 2)))]
5389 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5390 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5391 && (GET_CODE (operands[2]) != REG
5392 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5393 "ldr%?\\t%3, [%0, -%2]!"
5394 [(set_attr "type" "load")])
5396 (define_insn "*loadhi_preinc"
5397 [(set (match_operand:HI 3 "s_register_operand" "=r")
5398 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5399 (match_operand:SI 2 "index_operand" "rJ"))))
5400 (set (match_operand:SI 0 "s_register_operand" "=r")
5401 (plus:SI (match_dup 1) (match_dup 2)))]
5402 "(! BYTES_BIG_ENDIAN)
5403 && ! TARGET_SHORT_BY_BYTES
5404 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5405 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5406 && (GET_CODE (operands[2]) != REG
5407 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5408 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
5409 [(set_attr "type" "load")])
5411 (define_insn "*loadhi_predec"
5412 [(set (match_operand:HI 3 "s_register_operand" "=r")
5413 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5414 (match_operand:SI 2 "s_register_operand" "r"))))
5415 (set (match_operand:SI 0 "s_register_operand" "=r")
5416 (minus:SI (match_dup 1) (match_dup 2)))]
5417 "(!BYTES_BIG_ENDIAN)
5418 && ! TARGET_SHORT_BY_BYTES
5419 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5420 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5421 && (GET_CODE (operands[2]) != REG
5422 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5423 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
5424 [(set_attr "type" "load")])
5426 (define_insn "*strqi_shiftpreinc"
5427 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5428 [(match_operand:SI 3 "s_register_operand" "r")
5429 (match_operand:SI 4 "const_shift_operand" "n")])
5430 (match_operand:SI 1 "s_register_operand" "0")))
5431 (match_operand:QI 5 "s_register_operand" "r"))
5432 (set (match_operand:SI 0 "s_register_operand" "=r")
5433 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5435 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5436 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5437 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5438 "str%?b\\t%5, [%0, %3%S2]!"
5439 [(set_attr "type" "store1")])
5441 (define_insn "*strqi_shiftpredec"
5442 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5443 (match_operator:SI 2 "shift_operator"
5444 [(match_operand:SI 3 "s_register_operand" "r")
5445 (match_operand:SI 4 "const_shift_operand" "n")])))
5446 (match_operand:QI 5 "s_register_operand" "r"))
5447 (set (match_operand:SI 0 "s_register_operand" "=r")
5448 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5450 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5451 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5452 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5453 "str%?b\\t%5, [%0, -%3%S2]!"
5454 [(set_attr "type" "store1")])
5456 (define_insn "*loadqi_shiftpreinc"
5457 [(set (match_operand:QI 5 "s_register_operand" "=r")
5458 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5459 [(match_operand:SI 3 "s_register_operand" "r")
5460 (match_operand:SI 4 "const_shift_operand" "n")])
5461 (match_operand:SI 1 "s_register_operand" "0"))))
5462 (set (match_operand:SI 0 "s_register_operand" "=r")
5463 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5465 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5466 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5467 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5468 "ldr%?b\\t%5, [%0, %3%S2]!"
5469 [(set_attr "type" "load")])
5471 (define_insn "*loadqi_shiftpredec"
5472 [(set (match_operand:QI 5 "s_register_operand" "=r")
5473 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5474 (match_operator:SI 2 "shift_operator"
5475 [(match_operand:SI 3 "s_register_operand" "r")
5476 (match_operand:SI 4 "const_shift_operand" "n")]))))
5477 (set (match_operand:SI 0 "s_register_operand" "=r")
5478 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5480 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5481 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5482 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5483 "ldr%?b\\t%5, [%0, -%3%S2]!"
5484 [(set_attr "type" "load")])
5486 (define_insn "*strsi_shiftpreinc"
5487 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5488 [(match_operand:SI 3 "s_register_operand" "r")
5489 (match_operand:SI 4 "const_shift_operand" "n")])
5490 (match_operand:SI 1 "s_register_operand" "0")))
5491 (match_operand:SI 5 "s_register_operand" "r"))
5492 (set (match_operand:SI 0 "s_register_operand" "=r")
5493 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5495 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5496 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5497 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5498 "str%?\\t%5, [%0, %3%S2]!"
5499 [(set_attr "type" "store1")])
5501 (define_insn "*strsi_shiftpredec"
5502 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5503 (match_operator:SI 2 "shift_operator"
5504 [(match_operand:SI 3 "s_register_operand" "r")
5505 (match_operand:SI 4 "const_shift_operand" "n")])))
5506 (match_operand:SI 5 "s_register_operand" "r"))
5507 (set (match_operand:SI 0 "s_register_operand" "=r")
5508 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5510 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5511 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5512 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5513 "str%?\\t%5, [%0, -%3%S2]!"
5514 [(set_attr "type" "store1")])
5516 (define_insn "*loadqi_shiftpreinc"
5517 [(set (match_operand:SI 5 "s_register_operand" "=r")
5518 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5519 [(match_operand:SI 3 "s_register_operand" "r")
5520 (match_operand:SI 4 "const_shift_operand" "n")])
5521 (match_operand:SI 1 "s_register_operand" "0"))))
5522 (set (match_operand:SI 0 "s_register_operand" "=r")
5523 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5525 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5526 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5527 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5528 "ldr%?\\t%5, [%0, %3%S2]!"
5529 [(set_attr "type" "load")])
5531 (define_insn "*loadqi_shiftpredec"
5532 [(set (match_operand:SI 5 "s_register_operand" "=r")
5533 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5534 (match_operator:SI 2 "shift_operator"
5535 [(match_operand:SI 3 "s_register_operand" "r")
5536 (match_operand:SI 4 "const_shift_operand" "n")]))))
5537 (set (match_operand:SI 0 "s_register_operand" "=r")
5538 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5540 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5541 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5542 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5543 "ldr%?\\t%5, [%0, -%3%S2]!"
5544 [(set_attr "type" "load")])
5546 (define_insn "*loadhi_shiftpreinc"
5547 [(set (match_operand:HI 5 "s_register_operand" "=r")
5548 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5549 [(match_operand:SI 3 "s_register_operand" "r")
5550 (match_operand:SI 4 "const_shift_operand" "n")])
5551 (match_operand:SI 1 "s_register_operand" "0"))))
5552 (set (match_operand:SI 0 "s_register_operand" "=r")
5553 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5555 "(! BYTES_BIG_ENDIAN)
5556 && ! TARGET_SHORT_BY_BYTES
5557 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5558 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5559 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5560 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
5561 [(set_attr "type" "load")])
5563 (define_insn "*loadhi_shiftpredec"
5564 [(set (match_operand:HI 5 "s_register_operand" "=r")
5565 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5566 (match_operator:SI 2 "shift_operator"
5567 [(match_operand:SI 3 "s_register_operand" "r")
5568 (match_operand:SI 4 "const_shift_operand" "n")]))))
5569 (set (match_operand:SI 0 "s_register_operand" "=r")
5570 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5572 "(! BYTES_BIG_ENDIAN)
5573 && ! TARGET_SHORT_BY_BYTES
5574 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5575 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5576 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5577 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
5578 [(set_attr "type" "load")])
5580 ; It can also support extended post-inc expressions, but combine doesn't
5582 ; It doesn't seem worth adding peepholes for anything but the most common
5583 ; cases since, unlike combine, the increment must immediately follow the load
5584 ; for this pattern to match.
5585 ; When loading we must watch to see that the base register isn't trampled by
5586 ; the load. In such cases this isn't a post-inc expression.
5589 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5590 (match_operand:QI 2 "s_register_operand" "r"))
5592 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5594 "str%?b\\t%2, [%0], %1")
5597 [(set (match_operand:QI 0 "s_register_operand" "=r")
5598 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5600 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5601 "REGNO(operands[0]) != REGNO(operands[1])
5602 && (GET_CODE (operands[2]) != REG
5603 || REGNO(operands[0]) != REGNO (operands[2]))"
5604 "ldr%?b\\t%0, [%1], %2")
5607 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5608 (match_operand:SI 2 "s_register_operand" "r"))
5610 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5612 "str%?\\t%2, [%0], %1")
5615 [(set (match_operand:HI 0 "s_register_operand" "=r")
5616 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5618 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5619 "(! BYTES_BIG_ENDIAN)
5620 && ! TARGET_SHORT_BY_BYTES
5621 && REGNO(operands[0]) != REGNO(operands[1])
5622 && (GET_CODE (operands[2]) != REG
5623 || REGNO(operands[0]) != REGNO (operands[2]))"
5624 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5627 [(set (match_operand:SI 0 "s_register_operand" "=r")
5628 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5630 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5631 "REGNO(operands[0]) != REGNO(operands[1])
5632 && (GET_CODE (operands[2]) != REG
5633 || REGNO(operands[0]) != REGNO (operands[2]))"
5634 "ldr%?\\t%0, [%1], %2")
5637 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5638 (match_operand:SI 1 "index_operand" "rJ")))
5639 (match_operand:QI 2 "s_register_operand" "r"))
5640 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5642 "str%?b\\t%2, [%0, %1]!")
5645 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5646 [(match_operand:SI 0 "s_register_operand" "r")
5647 (match_operand:SI 1 "const_int_operand" "n")])
5648 (match_operand:SI 2 "s_register_operand" "+r")))
5649 (match_operand:QI 3 "s_register_operand" "r"))
5650 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5653 "str%?b\\t%3, [%2, %0%S4]!")
5655 ; This pattern is never tried by combine, so do it as a peephole
5658 [(set (match_operand:SI 0 "s_register_operand" "=r")
5659 (match_operand:SI 1 "s_register_operand" "r"))
5661 (compare:CC (match_dup 1) (const_int 0)))]
5663 "sub%?s\\t%0, %1, #0"
5664 [(set_attr "conds" "set")])
5666 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5667 ; reversed, check that the memory references aren't volatile.
5670 [(set (match_operand:SI 0 "s_register_operand" "=r")
5671 (match_operand:SI 4 "memory_operand" "m"))
5672 (set (match_operand:SI 1 "s_register_operand" "=r")
5673 (match_operand:SI 5 "memory_operand" "m"))
5674 (set (match_operand:SI 2 "s_register_operand" "=r")
5675 (match_operand:SI 6 "memory_operand" "m"))
5676 (set (match_operand:SI 3 "s_register_operand" "=r")
5677 (match_operand:SI 7 "memory_operand" "m"))]
5678 "load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5680 return emit_ldm_seq (operands, 4);
5684 [(set (match_operand:SI 0 "s_register_operand" "=r")
5685 (match_operand:SI 3 "memory_operand" "m"))
5686 (set (match_operand:SI 1 "s_register_operand" "=r")
5687 (match_operand:SI 4 "memory_operand" "m"))
5688 (set (match_operand:SI 2 "s_register_operand" "=r")
5689 (match_operand:SI 5 "memory_operand" "m"))]
5690 "load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5692 return emit_ldm_seq (operands, 3);
5696 [(set (match_operand:SI 0 "s_register_operand" "=r")
5697 (match_operand:SI 2 "memory_operand" "m"))
5698 (set (match_operand:SI 1 "s_register_operand" "=r")
5699 (match_operand:SI 3 "memory_operand" "m"))]
5700 "load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5702 return emit_ldm_seq (operands, 2);
5706 [(set (match_operand:SI 4 "memory_operand" "=m")
5707 (match_operand:SI 0 "s_register_operand" "r"))
5708 (set (match_operand:SI 5 "memory_operand" "=m")
5709 (match_operand:SI 1 "s_register_operand" "r"))
5710 (set (match_operand:SI 6 "memory_operand" "=m")
5711 (match_operand:SI 2 "s_register_operand" "r"))
5712 (set (match_operand:SI 7 "memory_operand" "=m")
5713 (match_operand:SI 3 "s_register_operand" "r"))]
5714 "store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5716 return emit_stm_seq (operands, 4);
5720 [(set (match_operand:SI 3 "memory_operand" "=m")
5721 (match_operand:SI 0 "s_register_operand" "r"))
5722 (set (match_operand:SI 4 "memory_operand" "=m")
5723 (match_operand:SI 1 "s_register_operand" "r"))
5724 (set (match_operand:SI 5 "memory_operand" "=m")
5725 (match_operand:SI 2 "s_register_operand" "r"))]
5726 "store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5728 return emit_stm_seq (operands, 3);
5732 [(set (match_operand:SI 2 "memory_operand" "=m")
5733 (match_operand:SI 0 "s_register_operand" "r"))
5734 (set (match_operand:SI 3 "memory_operand" "=m")
5735 (match_operand:SI 1 "s_register_operand" "r"))]
5736 "store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5738 return emit_stm_seq (operands, 2);
5741 ;; A call followed by return can be replaced by restoring the regs and
5742 ;; jumping to the subroutine, provided we aren't passing the address of
5743 ;; any of our local variables. If we call alloca then this is unsafe
5744 ;; since restoring the frame frees the memory, which is not what we want.
5745 ;; Sometimes the return might have been targeted by the final prescan:
5746 ;; if so then emit a proper return insn as well.
5747 ;; Unfortunately, if the frame pointer is required, we don't know if the
5748 ;; current function has any implicit stack pointer adjustments that will
5749 ;; be restored by the return: we can't therefore do a tail call.
5750 ;; Another unfortunate that we can't handle is if current_function_args_size
5751 ;; is non-zero: in this case elimination of the argument pointer assumed
5752 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5756 [(parallel [(call (mem:SI (match_operand:SI 0 "" "X"))
5757 (match_operand:SI 1 "general_operand" "g"))
5758 (clobber (reg:SI 14))])
5760 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5761 && !get_frame_size () && !current_function_calls_alloca
5762 && !frame_pointer_needed && !current_function_args_size)"
5765 extern rtx arm_target_insn;
5766 extern int arm_ccfsm_state;
5768 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5770 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5771 output_return_instruction (NULL, TRUE, FALSE);
5772 arm_ccfsm_state = 0;
5773 arm_target_insn = NULL;
5776 output_return_instruction (NULL, FALSE, FALSE);
5777 return \"b%?\\t%a0\";
5779 [(set_attr "type" "call")
5780 (set_attr "length" "8")])
5783 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5784 (call (mem:SI (match_operand:SI 1 "" "X"))
5785 (match_operand:SI 2 "general_operand" "g")))
5786 (clobber (reg:SI 14))])
5788 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5789 && !get_frame_size () && !current_function_calls_alloca
5790 && !frame_pointer_needed && !current_function_args_size)"
5793 extern rtx arm_target_insn;
5794 extern int arm_ccfsm_state;
5796 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5798 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5799 output_return_instruction (NULL, TRUE, FALSE);
5800 arm_ccfsm_state = 0;
5801 arm_target_insn = NULL;
5804 output_return_instruction (NULL, FALSE, FALSE);
5805 return \"b%?\\t%a1\";
5807 [(set_attr "type" "call")
5808 (set_attr "length" "8")])
5810 ;; As above but when this function is not void, we must be returning the
5811 ;; result of the called subroutine.
5814 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5815 (call (mem:SI (match_operand:SI 1 "" "X"))
5816 (match_operand:SI 2 "general_operand" "g")))
5817 (clobber (reg:SI 14))])
5820 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5821 && !get_frame_size () && !current_function_calls_alloca
5822 && !frame_pointer_needed && !current_function_args_size)"
5825 extern rtx arm_target_insn;
5826 extern int arm_ccfsm_state;
5828 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5830 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5831 output_return_instruction (NULL, TRUE, FALSE);
5832 arm_ccfsm_state = 0;
5833 arm_target_insn = NULL;
5836 output_return_instruction (NULL, FALSE, FALSE);
5837 return \"b%?\\t%a1\";
5839 [(set_attr "type" "call")
5840 (set_attr "length" "8")])
5843 [(set (match_operand:SI 0 "s_register_operand" "")
5844 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
5846 (neg:SI (match_operator:SI 2 "comparison_operator"
5847 [(match_operand:SI 3 "s_register_operand" "")
5848 (match_operand:SI 4 "arm_rhs_operand" "")]))))
5849 (clobber (match_operand:SI 5 "s_register_operand" ""))]
5851 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
5852 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5856 ;; This split can be used because CC_Z mode implies that the following
5857 ;; branch will be an equality, or an unsigned inequality, so the sign
5858 ;; extension is not needed.
5863 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
5865 (match_operand 1 "const_int_operand" "")))
5866 (clobber (match_scratch:SI 2 ""))]
5867 "((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
5868 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24"
5869 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
5870 (set (reg:CC 24) (compare:CC (match_dup 2) (match_dup 1)))]
5872 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
5875 (define_expand "prologue"
5876 [(clobber (const_int 0))]
5879 arm_expand_prologue ();
5883 ;; This split is only used during output to reduce the number of patterns
5884 ;; that need assembler instructions adding to them. We allowed the setting
5885 ;; of the conditions to be implicit during rtl generation so that
5886 ;; the conditional compare patterns would work. However this conflicts to
5887 ;; some extent with the conditional data operations, so we have to split them
5891 [(set (match_operand:SI 0 "s_register_operand" "")
5892 (if_then_else:SI (match_operator 1 "comparison_operator"
5893 [(match_operand 2 "" "") (match_operand 3 "" "")])
5894 (match_operand 4 "" "")
5895 (match_operand 5 "" "")))
5898 [(set (match_dup 6) (match_dup 7))
5900 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
5905 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
5908 operands[6] = gen_rtx (REG, mode, 24);
5909 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
5914 ;; The next two patterns occur when an AND operation is followed by a
5915 ;; scc insn sequence
5917 (define_insn "*sign_extract_onebit"
5918 [(set (match_operand:SI 0 "s_register_operand" "=r")
5919 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5921 (match_operand:SI 2 "const_int_operand" "n")))]
5924 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5925 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
5926 return \"mvnne\\t%0, #0\";
5928 [(set_attr "conds" "clob")
5929 (set_attr "length" "8")])
5931 (define_insn "*not_signextract_onebit"
5932 [(set (match_operand:SI 0 "s_register_operand" "=r")
5934 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
5936 (match_operand:SI 2 "const_int_operand" "n"))))]
5939 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5940 output_asm_insn (\"tst\\t%1, %2\", operands);
5941 output_asm_insn (\"mvneq\\t%0, #0\", operands);
5942 return \"movne\\t%0, #0\";
5944 [(set_attr "conds" "clob")
5945 (set_attr "length" "12")])
5947 ;; Push multiple registers to the stack. The first register is in the
5948 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
5950 (define_insn "*push_multi"
5951 [(match_parallel 2 "multi_register_push"
5952 [(set (match_operand:BLK 0 "memory_operand" "=m")
5953 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
5959 extern int lr_save_eliminated;
5961 if (lr_save_eliminated)
5963 if (XVECLEN (operands[2], 0) > 1)
5967 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
5968 for (i = 1; i < XVECLEN (operands[2], 0); i++)
5970 strcat (pattern, \", %|\");
5971 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
5974 strcat (pattern, \"}\");
5975 output_asm_insn (pattern, operands);
5978 [(set_attr "type" "store4")])
5980 ;; Special patterns for dealing with the constant pool
5982 (define_insn "consttable_4"
5983 [(unspec_volatile [(match_operand 0 "" "")] 2)]
5987 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
5991 union real_extract u;
5992 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
5993 assemble_real (u.d, GET_MODE (operands[0]));
5997 assemble_integer (operands[0], 4, 1);
6002 [(set_attr "length" "4")])
6004 (define_insn "consttable_8"
6005 [(unspec_volatile [(match_operand 0 "" "")] 3)]
6009 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
6013 union real_extract u;
6014 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
6015 assemble_real (u.d, GET_MODE (operands[0]));
6019 assemble_integer (operands[0], 8, 1);
6024 [(set_attr "length" "8")])
6026 (define_insn "consttable_end"
6027 [(unspec_volatile [(const_int 0)] 4)]
6030 /* Nothing to do (currently). */
6034 (define_insn "align_4"
6035 [(unspec_volatile [(const_int 0)] 5)]
6038 assemble_align (32);