1 ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
2 ;; Copyright (C) 1991, 93-97, 1998 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 "smulsi3_highpart"
863 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
866 (mult:DI (sign_extend:DI
867 (match_operand:SI 1 "s_register_operand" "%r,0"))
869 (match_operand:SI 2 "s_register_operand" "r,r")))
871 (clobber (match_scratch:SI 3 "=&r,&r"))]
873 "smull%?\\t%3, %0, %2, %1"
874 [(set_attr "type" "mult")])
876 (define_insn "umulsi3_highpart"
877 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
880 (mult:DI (zero_extend:DI
881 (match_operand:SI 1 "s_register_operand" "%r,0"))
883 (match_operand:SI 2 "s_register_operand" "r,r")))
885 (clobber (match_scratch:SI 3 "=&r,&r"))]
887 "umull%?\\t%3, %0, %2, %1"
888 [(set_attr "type" "mult")])
890 (define_insn "mulsf3"
891 [(set (match_operand:SF 0 "s_register_operand" "=f")
892 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
893 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
895 "fml%?s\\t%0, %1, %2"
896 [(set_attr "type" "ffmul")])
898 (define_insn "muldf3"
899 [(set (match_operand:DF 0 "s_register_operand" "=f")
900 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
901 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
903 "muf%?d\\t%0, %1, %2"
904 [(set_attr "type" "fmul")])
906 (define_insn "*muldf_esfdf_df"
907 [(set (match_operand:DF 0 "s_register_operand" "=f")
908 (mult:DF (float_extend:DF
909 (match_operand:SF 1 "s_register_operand" "f"))
910 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
912 "muf%?d\\t%0, %1, %2"
913 [(set_attr "type" "fmul")])
915 (define_insn "*muldf_df_esfdf"
916 [(set (match_operand:DF 0 "s_register_operand" "=f")
917 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
919 (match_operand:SF 2 "s_register_operand" "f"))))]
921 "muf%?d\\t%0, %1, %2"
922 [(set_attr "type" "fmul")])
924 (define_insn "*muldf_esfdf_esfdf"
925 [(set (match_operand:DF 0 "s_register_operand" "=f")
926 (mult:DF (float_extend:DF
927 (match_operand:SF 1 "s_register_operand" "f"))
929 (match_operand:SF 2 "s_register_operand" "f"))))]
931 "muf%?d\\t%0, %1, %2"
932 [(set_attr "type" "fmul")])
934 (define_insn "mulxf3"
935 [(set (match_operand:XF 0 "s_register_operand" "=f")
936 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
937 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
938 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
939 "muf%?e\\t%0, %1, %2"
940 [(set_attr "type" "fmul")])
944 (define_insn "divsf3"
945 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
946 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
947 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
952 [(set_attr "type" "fdivs")])
954 (define_insn "divdf3"
955 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
956 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
957 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
962 [(set_attr "type" "fdivd")])
964 (define_insn "*divdf_esfdf_df"
965 [(set (match_operand:DF 0 "s_register_operand" "=f")
966 (div:DF (float_extend:DF
967 (match_operand:SF 1 "s_register_operand" "f"))
968 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
970 "dvf%?d\\t%0, %1, %2"
971 [(set_attr "type" "fdivd")])
973 (define_insn "*divdf_df_esfdf"
974 [(set (match_operand:DF 0 "s_register_operand" "=f")
975 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
977 (match_operand:SF 2 "s_register_operand" "f"))))]
979 "rdf%?d\\t%0, %2, %1"
980 [(set_attr "type" "fdivd")])
982 (define_insn "*divdf_esfdf_esfdf"
983 [(set (match_operand:DF 0 "s_register_operand" "=f")
984 (div:DF (float_extend:DF
985 (match_operand:SF 1 "s_register_operand" "f"))
987 (match_operand:SF 2 "s_register_operand" "f"))))]
989 "dvf%?d\\t%0, %1, %2"
990 [(set_attr "type" "fdivd")])
992 (define_insn "divxf3"
993 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
994 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
995 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
996 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1000 [(set_attr "type" "fdivx")])
1004 (define_insn "modsf3"
1005 [(set (match_operand:SF 0 "s_register_operand" "=f")
1006 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
1007 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
1009 "rmf%?s\\t%0, %1, %2"
1010 [(set_attr "type" "fdivs")])
1012 (define_insn "moddf3"
1013 [(set (match_operand:DF 0 "s_register_operand" "=f")
1014 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
1015 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1017 "rmf%?d\\t%0, %1, %2"
1018 [(set_attr "type" "fdivd")])
1020 (define_insn "*moddf_esfdf_df"
1021 [(set (match_operand:DF 0 "s_register_operand" "=f")
1022 (mod:DF (float_extend:DF
1023 (match_operand:SF 1 "s_register_operand" "f"))
1024 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1026 "rmf%?d\\t%0, %1, %2"
1027 [(set_attr "type" "fdivd")])
1029 (define_insn "*moddf_df_esfdf"
1030 [(set (match_operand:DF 0 "s_register_operand" "=f")
1031 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
1033 (match_operand:SF 2 "s_register_operand" "f"))))]
1035 "rmf%?d\\t%0, %1, %2"
1036 [(set_attr "type" "fdivd")])
1038 (define_insn "*moddf_esfdf_esfdf"
1039 [(set (match_operand:DF 0 "s_register_operand" "=f")
1040 (mod:DF (float_extend:DF
1041 (match_operand:SF 1 "s_register_operand" "f"))
1043 (match_operand:SF 2 "s_register_operand" "f"))))]
1045 "rmf%?d\\t%0, %1, %2"
1046 [(set_attr "type" "fdivd")])
1048 (define_insn "modxf3"
1049 [(set (match_operand:XF 0 "s_register_operand" "=f")
1050 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
1051 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
1052 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1053 "rmf%?e\\t%0, %1, %2"
1054 [(set_attr "type" "fdivx")])
1056 ;; Boolean and,ior,xor insns
1058 (define_insn "anddi3"
1059 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1060 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1061 (match_operand:DI 2 "s_register_operand" "r,0")))]
1063 "and%?\\t%Q0, %Q1, %Q2\;and%?\\t%R0, %R1, %R2"
1064 [(set_attr "length" "8")])
1066 (define_insn "*anddi_zesidi_di"
1067 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1068 (and:DI (zero_extend:DI
1069 (match_operand:SI 2 "s_register_operand" "r,r"))
1070 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1072 "and%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, #0"
1073 [(set_attr "length" "8")])
1075 (define_insn "*anddi_sesdi_di"
1076 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1077 (and:DI (sign_extend:DI
1078 (match_operand:SI 2 "s_register_operand" "r,r"))
1079 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1081 "and%?\\t%Q0, %Q1, %2\;and%?\\t%R0, %R1, %2, asr #31"
1082 [(set_attr "length" "8")])
1084 (define_expand "andsi3"
1085 [(set (match_operand:SI 0 "s_register_operand" "")
1086 (and:SI (match_operand:SI 1 "s_register_operand" "")
1087 (match_operand:SI 2 "reg_or_int_operand" "")))]
1090 if (GET_CODE (operands[2]) == CONST_INT)
1092 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1094 (reload_in_progress || reload_completed
1095 ? 0 : preserve_subexpressions_p ()));
1100 (define_insn "*andsi3_insn"
1101 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1102 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1103 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1107 bic%?\\t%0, %1, #%B2
1109 [(set_attr "length" "4,4,16")])
1112 [(set (match_operand:SI 0 "s_register_operand" "")
1113 (and:SI (match_operand:SI 1 "s_register_operand" "")
1114 (match_operand:SI 2 "const_int_operand" "")))]
1115 "! (const_ok_for_arm (INTVAL (operands[2]))
1116 || const_ok_for_arm (~ INTVAL (operands[2])))"
1117 [(clobber (const_int 0))]
1119 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1124 (define_insn "*andsi3_compare0"
1125 [(set (reg:CC_NOOV 24)
1127 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1128 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1130 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1131 (and:SI (match_dup 1) (match_dup 2)))]
1135 bic%?s\\t%0, %1, #%B2"
1136 [(set_attr "conds" "set")])
1138 (define_insn "*andsi3_compare0_scratch"
1139 [(set (reg:CC_NOOV 24)
1141 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1142 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1144 (clobber (match_scratch:SI 3 "=X,r"))]
1148 bic%?s\\t%3, %0, #%B1"
1149 [(set_attr "conds" "set")])
1151 (define_insn "*zeroextractsi_compare0_scratch"
1152 [(set (reg:CC_NOOV 24)
1153 (compare:CC_NOOV (zero_extract:SI
1154 (match_operand:SI 0 "s_register_operand" "r")
1155 (match_operand 1 "const_int_operand" "n")
1156 (match_operand 2 "const_int_operand" "n"))
1158 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1159 && INTVAL (operands[1]) > 0
1160 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1161 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
1164 unsigned int mask = 0;
1165 int cnt = INTVAL (operands[1]);
1168 mask = (mask << 1) | 1;
1169 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1170 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1174 [(set_attr "conds" "set")])
1176 (define_insn "*zeroextractqi_compare0_scratch"
1177 [(set (reg:CC_NOOV 24)
1178 (compare:CC_NOOV (zero_extract:SI
1179 (match_operand:QI 0 "memory_operand" "m")
1180 (match_operand 1 "const_int_operand" "n")
1181 (match_operand 2 "const_int_operand" "n"))
1183 (clobber (match_scratch:QI 3 "=r"))]
1184 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
1185 && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
1188 unsigned int mask = 0;
1189 int cnt = INTVAL (operands[1]);
1192 mask = (mask << 1) | 1;
1193 operands[1] = GEN_INT (mask << INTVAL (operands[2]));
1194 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
1195 output_asm_insn (\"tst%?\\t%3, %1\", operands);
1199 [(set_attr "conds" "set")
1200 (set_attr "length" "8")])
1202 (define_expand "insv"
1203 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1204 (match_operand:SI 1 "general_operand" "")
1205 (match_operand:SI 2 "general_operand" ""))
1206 (match_operand:SI 3 "nonmemory_operand" ""))]
1210 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << INTVAL (operands[1])) - 1;
1211 rtx target, subtarget;
1213 target = operands[0];
1214 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1215 subreg as the final target. */
1216 if (GET_CODE (target) == SUBREG)
1218 subtarget = gen_reg_rtx (SImode);
1219 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1220 < GET_MODE_SIZE (SImode))
1221 target = SUBREG_REG (target);
1226 if (GET_CODE (operands[3]) == CONST_INT)
1228 /* Since we are inserting a known constant, we may be able to
1229 reduce the number of bits that we have to clear so that
1230 the mask becomes simple. */
1231 rtx op1 = gen_reg_rtx (SImode);
1232 HOST_WIDE_INT mask2 = ((mask & ~INTVAL (operands[3]))
1233 << INTVAL (operands[2]));
1235 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1236 emit_insn (gen_iorsi3 (subtarget, op1,
1237 GEN_INT (INTVAL (operands[3])
1238 << INTVAL (operands[2]))));
1240 else if (INTVAL (operands[2]) == 0
1241 && ! (const_ok_for_arm (mask)
1242 || const_ok_for_arm (~mask)))
1244 /* A Trick, since we are setting the bottom bits in the word,
1245 we can shift operand[3] up, operand[0] down, OR them together
1246 and rotate the result back again. This takes 3 insns, and
1247 the third might be mergable into another op. */
1249 rtx op0 = gen_reg_rtx (SImode);
1250 rtx op1 = gen_reg_rtx (SImode);
1252 emit_insn (gen_ashlsi3 (op0, operands[3],
1253 GEN_INT (32 - INTVAL (operands[1]))));
1254 emit_insn (gen_iorsi3 (op1, gen_rtx (LSHIFTRT, SImode, operands[0],
1257 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1259 else if ((INTVAL (operands[1]) + INTVAL (operands[2]) == 32)
1260 && ! (const_ok_for_arm (mask)
1261 || const_ok_for_arm (~mask)))
1263 /* Similar trick, but slightly less efficient. */
1265 rtx op0 = gen_reg_rtx (SImode);
1266 rtx op1 = gen_reg_rtx (SImode);
1268 emit_insn (gen_ashlsi3 (op0, operands[3],
1269 GEN_INT (32 - INTVAL (operands[1]))));
1270 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1271 emit_insn (gen_iorsi3 (subtarget,
1272 gen_rtx (LSHIFTRT, SImode, op1,
1273 operands[1]), op0));
1277 rtx op0 = GEN_INT (mask);
1278 rtx op1 = gen_reg_rtx (SImode);
1279 rtx op2 = gen_reg_rtx (SImode);
1281 if (! (const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1283 rtx tmp = gen_reg_rtx (SImode);
1285 emit_insn (gen_movsi (tmp, op0));
1289 emit_insn (gen_andsi3 (op1, operands[3], op0));
1291 if (GET_CODE (op0) == CONST_INT
1292 && (const_ok_for_arm (mask << INTVAL (operands[2]))
1293 || const_ok_for_arm (~ (mask << INTVAL (operands[2])))))
1295 op0 = GEN_INT (~(mask << INTVAL (operands[2])));
1296 emit_insn (gen_andsi3 (op2, operands[0], op0));
1300 if (GET_CODE (op0) == CONST_INT)
1302 rtx tmp = gen_reg_rtx (SImode);
1304 emit_insn (gen_movsi (tmp, op0));
1308 if (INTVAL (operands[2]) != 0)
1309 op0 = gen_rtx (ASHIFT, SImode, op0, operands[2]);
1310 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1313 if (INTVAL (operands[2]) != 0)
1314 op1 = gen_rtx (ASHIFT, SImode, op1, operands[2]);
1316 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1319 if (subtarget != target)
1321 /* If TARGET is still a SUBREG, then it must be wider than a word,
1322 so we must be careful only to set the subword we were asked to. */
1323 if (GET_CODE (target) == SUBREG)
1324 emit_move_insn (target, subtarget);
1326 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1333 ;; constants for op 2 will never be given to these patterns.
1334 (define_insn "*anddi_notdi_di"
1335 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1336 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
1337 (match_operand:DI 1 "s_register_operand" "0,r")))]
1339 "bic%?\\t%Q0, %Q1, %Q2\;bic%?\\t%R0, %R1, %R2"
1340 [(set_attr "length" "8")])
1342 (define_insn "*anddi_notzesidi_di"
1343 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1344 (and:DI (not:DI (zero_extend:DI
1345 (match_operand:SI 2 "s_register_operand" "r,r")))
1346 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1349 bic%?\\t%Q0, %Q1, %2
1350 bic%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1351 [(set_attr "length" "4,8")])
1353 (define_insn "*anddi_notsesidi_di"
1354 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1355 (and:DI (not:DI (sign_extend:DI
1356 (match_operand:SI 2 "s_register_operand" "r,r")))
1357 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1359 "bic%?\\t%Q0, %Q1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
1360 [(set_attr "length" "8")])
1362 (define_insn "andsi_notsi_si"
1363 [(set (match_operand:SI 0 "s_register_operand" "=r")
1364 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1365 (match_operand:SI 1 "s_register_operand" "r")))]
1367 "bic%?\\t%0, %1, %2")
1369 (define_insn "andsi_not_shiftsi_si"
1370 [(set (match_operand:SI 0 "s_register_operand" "=r")
1371 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
1372 [(match_operand:SI 2 "s_register_operand" "r")
1373 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
1374 (match_operand:SI 1 "s_register_operand" "r")))]
1376 "bic%?\\t%0, %1, %2%S4")
1378 (define_insn "*andsi_notsi_si_compare0"
1379 [(set (reg:CC_NOOV 24)
1381 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1382 (match_operand:SI 1 "s_register_operand" "r"))
1384 (set (match_operand:SI 0 "s_register_operand" "=r")
1385 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1387 "bic%?s\\t%0, %1, %2"
1388 [(set_attr "conds" "set")])
1390 (define_insn "*andsi_notsi_si_compare0_scratch"
1391 [(set (reg:CC_NOOV 24)
1393 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1394 (match_operand:SI 1 "s_register_operand" "r"))
1396 (clobber (match_scratch:SI 0 "=r"))]
1398 "bic%?s\\t%0, %1, %2"
1399 [(set_attr "conds" "set")])
1401 (define_insn "iordi3"
1402 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1403 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1404 (match_operand:DI 2 "s_register_operand" "r")))]
1406 "orr%?\\t%Q0, %Q1, %Q2\;orr%?\\t%R0, %R1, %R2"
1407 [(set_attr "length" "8")])
1409 (define_insn "*iordi_zesidi_di"
1410 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1411 (ior:DI (zero_extend:DI
1412 (match_operand:SI 2 "s_register_operand" "r,r"))
1413 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1416 orr%?\\t%Q0, %Q1, %2
1417 orr%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1418 [(set_attr "length" "4,8")])
1420 (define_insn "*iordi_sesidi_di"
1421 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1422 (ior:DI (sign_extend:DI
1423 (match_operand:SI 2 "s_register_operand" "r,r"))
1424 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1426 "orr%?\\t%Q0, %Q1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1427 [(set_attr "length" "8")])
1429 (define_expand "iorsi3"
1430 [(set (match_operand:SI 0 "s_register_operand" "")
1431 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1432 (match_operand:SI 2 "reg_or_int_operand" "")))]
1435 if (GET_CODE (operands[2]) == CONST_INT)
1437 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1439 (reload_in_progress || reload_completed
1440 ? 0 : preserve_subexpressions_p ()));
1445 (define_insn "*iorsi3_insn"
1446 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1447 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1448 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
1453 [(set_attr "length" "4,16")])
1456 [(set (match_operand:SI 0 "s_register_operand" "")
1457 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1458 (match_operand:SI 2 "const_int_operand" "")))]
1459 "! const_ok_for_arm (INTVAL (operands[2]))"
1460 [(clobber (const_int 0))]
1462 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1467 (define_insn "*iorsi3_compare0"
1468 [(set (reg:CC_NOOV 24)
1469 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1470 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1472 (set (match_operand:SI 0 "s_register_operand" "=r")
1473 (ior:SI (match_dup 1) (match_dup 2)))]
1475 "orr%?s\\t%0, %1, %2"
1476 [(set_attr "conds" "set")])
1478 (define_insn "*iorsi3_compare0_scratch"
1479 [(set (reg:CC_NOOV 24)
1480 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1481 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1483 (clobber (match_scratch:SI 0 "=r"))]
1485 "orr%?s\\t%0, %1, %2"
1486 [(set_attr "conds" "set")])
1488 (define_insn "xordi3"
1489 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1490 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1491 (match_operand:DI 2 "s_register_operand" "r,0")))]
1493 "eor%?\\t%Q0, %Q1, %Q2\;eor%?\\t%R0, %R1, %R2"
1494 [(set_attr "length" "8")])
1496 (define_insn "*xordi_zesidi_di"
1497 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1498 (xor:DI (zero_extend:DI
1499 (match_operand:SI 2 "s_register_operand" "r,r"))
1500 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1503 eor%?\\t%Q0, %Q1, %2
1504 eor%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1505 [(set_attr "length" "4,8")])
1507 (define_insn "*xordi_sesidi_di"
1508 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1509 (xor:DI (sign_extend:DI
1510 (match_operand:SI 2 "s_register_operand" "r,r"))
1511 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1513 "eor%?\\t%Q0, %Q1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1514 [(set_attr "length" "8")])
1516 (define_insn "xorsi3"
1517 [(set (match_operand:SI 0 "s_register_operand" "=r")
1518 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1519 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1521 "eor%?\\t%0, %1, %2")
1523 (define_insn "*xorsi3_compare0"
1524 [(set (reg:CC_NOOV 24)
1525 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1526 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1528 (set (match_operand:SI 0 "s_register_operand" "=r")
1529 (xor:SI (match_dup 1) (match_dup 2)))]
1531 "eor%?s\\t%0, %1, %2"
1532 [(set_attr "conds" "set")])
1534 (define_insn "*xorsi3_compare0_scratch"
1535 [(set (reg:CC_NOOV 24)
1536 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1537 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1541 [(set_attr "conds" "set")])
1543 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1544 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1548 [(set (match_operand:SI 0 "s_register_operand" "=r")
1549 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1550 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1551 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1552 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1554 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1555 (not:SI (match_dup 3))))
1556 (set (match_dup 0) (not:SI (match_dup 4)))]
1560 (define_insn "*andsi_iorsi3_notsi"
1561 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1562 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1563 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1564 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1566 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1567 [(set_attr "length" "8")])
1571 ;; Minimum and maximum insns
1573 (define_insn "smaxsi3"
1574 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1575 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1576 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1577 (clobber (reg:CC 24))]
1580 cmp\\t%1, %2\;movlt\\t%0, %2
1581 cmp\\t%1, %2\;movge\\t%0, %1
1582 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1583 [(set_attr "conds" "clob")
1584 (set_attr "length" "8,8,12")])
1586 (define_insn "sminsi3"
1587 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1588 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1589 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1590 (clobber (reg:CC 24))]
1593 cmp\\t%1, %2\;movge\\t%0, %2
1594 cmp\\t%1, %2\;movlt\\t%0, %1
1595 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1596 [(set_attr "conds" "clob")
1597 (set_attr "length" "8,8,12")])
1599 (define_insn "umaxsi3"
1600 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1601 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1602 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1603 (clobber (reg:CC 24))]
1606 cmp\\t%1, %2\;movcc\\t%0, %2
1607 cmp\\t%1, %2\;movcs\\t%0, %1
1608 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1609 [(set_attr "conds" "clob")
1610 (set_attr "length" "8,8,12")])
1612 (define_insn "uminsi3"
1613 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1614 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1615 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1616 (clobber (reg:CC 24))]
1619 cmp\\t%1, %2\;movcs\\t%0, %2
1620 cmp\\t%1, %2\;movcc\\t%0, %1
1621 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1622 [(set_attr "conds" "clob")
1623 (set_attr "length" "8,8,12")])
1625 (define_insn "*store_minmaxsi"
1626 [(set (match_operand:SI 0 "memory_operand" "=m")
1627 (match_operator:SI 3 "minmax_operator"
1628 [(match_operand:SI 1 "s_register_operand" "r")
1629 (match_operand:SI 2 "s_register_operand" "r")]))
1630 (clobber (reg:CC 24))]
1633 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1635 output_asm_insn (\"cmp\\t%1, %2\", operands);
1636 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1637 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1640 [(set_attr "conds" "clob")
1641 (set_attr "length" "12")
1642 (set_attr "type" "store1")])
1644 ; Reject the frame pointer in operand[1], since reloading this after
1645 ; it has been eliminated can cause carnage.
1646 (define_insn "*minmax_arithsi"
1647 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1648 (match_operator:SI 4 "shiftable_operator"
1649 [(match_operator:SI 5 "minmax_operator"
1650 [(match_operand:SI 2 "s_register_operand" "r,r")
1651 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1652 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1653 (clobber (reg:CC 24))]
1654 "GET_CODE (operands[1]) != REG
1655 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
1656 && REGNO(operands[1]) != ARG_POINTER_REGNUM)"
1659 enum rtx_code code = GET_CODE (operands[4]);
1661 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1663 output_asm_insn (\"cmp\\t%2, %3\", operands);
1664 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1665 if (which_alternative != 0 || operands[3] != const0_rtx
1666 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1667 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1671 [(set_attr "conds" "clob")
1672 (set_attr "length" "12")])
1675 ;; Shift and rotation insns
1677 (define_expand "ashlsi3"
1678 [(set (match_operand:SI 0 "s_register_operand" "")
1679 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1680 (match_operand:SI 2 "arm_rhs_operand" "")))]
1683 if (GET_CODE (operands[2]) == CONST_INT
1684 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1686 emit_insn (gen_movsi (operands[0], const0_rtx));
1691 (define_expand "ashrsi3"
1692 [(set (match_operand:SI 0 "s_register_operand" "")
1693 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1694 (match_operand:SI 2 "arm_rhs_operand" "")))]
1697 if (GET_CODE (operands[2]) == CONST_INT
1698 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1699 operands[2] = GEN_INT (31);
1702 (define_expand "lshrsi3"
1703 [(set (match_operand:SI 0 "s_register_operand" "")
1704 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1705 (match_operand:SI 2 "arm_rhs_operand" "")))]
1708 if (GET_CODE (operands[2]) == CONST_INT
1709 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1711 emit_insn (gen_movsi (operands[0], const0_rtx));
1716 (define_expand "rotlsi3"
1717 [(set (match_operand:SI 0 "s_register_operand" "")
1718 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1719 (match_operand:SI 2 "reg_or_int_operand" "")))]
1722 if (GET_CODE (operands[2]) == CONST_INT)
1723 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1726 rtx reg = gen_reg_rtx (SImode);
1727 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1732 (define_expand "rotrsi3"
1733 [(set (match_operand:SI 0 "s_register_operand" "")
1734 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1735 (match_operand:SI 2 "arm_rhs_operand" "")))]
1738 if (GET_CODE (operands[2]) == CONST_INT
1739 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1740 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1743 (define_insn "*shiftsi3"
1744 [(set (match_operand:SI 0 "s_register_operand" "=r")
1745 (match_operator:SI 3 "shift_operator"
1746 [(match_operand:SI 1 "s_register_operand" "r")
1747 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1749 "mov%?\\t%0, %1%S3")
1751 (define_insn "*shiftsi3_compare0"
1752 [(set (reg:CC_NOOV 24)
1753 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1754 [(match_operand:SI 1 "s_register_operand" "r")
1755 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1757 (set (match_operand:SI 0 "s_register_operand" "=r")
1758 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1760 "mov%?s\\t%0, %1%S3"
1761 [(set_attr "conds" "set")])
1763 (define_insn "*shiftsi3_compare0_scratch"
1764 [(set (reg:CC_NOOV 24)
1765 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1766 [(match_operand:SI 1 "s_register_operand" "r")
1767 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1769 (clobber (match_scratch:SI 0 "=r"))]
1771 "mov%?s\\t%0, %1%S3"
1772 [(set_attr "conds" "set")])
1774 (define_insn "*notsi_shiftsi"
1775 [(set (match_operand:SI 0 "s_register_operand" "=r")
1776 (not:SI (match_operator:SI 3 "shift_operator"
1777 [(match_operand:SI 1 "s_register_operand" "r")
1778 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
1780 "mvn%?\\t%0, %1%S3")
1782 (define_insn "*notsi_shiftsi_compare0"
1783 [(set (reg:CC_NOOV 24)
1784 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1785 [(match_operand:SI 1 "s_register_operand" "r")
1786 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1788 (set (match_operand:SI 0 "s_register_operand" "=r")
1789 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1791 "mvn%?s\\t%0, %1%S3"
1792 [(set_attr "conds" "set")])
1794 (define_insn "*not_shiftsi_compare0_scratch"
1795 [(set (reg:CC_NOOV 24)
1796 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1797 [(match_operand:SI 1 "s_register_operand" "r")
1798 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1800 (clobber (match_scratch:SI 0 "=r"))]
1802 "mvn%?s\\t%0, %1%S3"
1803 [(set_attr "conds" "set")])
1806 ;; Unary arithmetic insns
1808 (define_insn "negdi2"
1809 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1810 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1812 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
1813 [(set_attr "conds" "clob")
1814 (set_attr "length" "8")])
1816 (define_insn "negsi2"
1817 [(set (match_operand:SI 0 "s_register_operand" "=r")
1818 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1820 "rsb%?\\t%0, %1, #0")
1822 (define_insn "negsf2"
1823 [(set (match_operand:SF 0 "s_register_operand" "=f")
1824 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1827 [(set_attr "type" "ffarith")])
1829 (define_insn "negdf2"
1830 [(set (match_operand:DF 0 "s_register_operand" "=f")
1831 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1834 [(set_attr "type" "ffarith")])
1836 (define_insn "*negdf_esfdf"
1837 [(set (match_operand:DF 0 "s_register_operand" "=f")
1838 (neg:DF (float_extend:DF
1839 (match_operand:SF 1 "s_register_operand" "f"))))]
1842 [(set_attr "type" "ffarith")])
1844 (define_insn "negxf2"
1845 [(set (match_operand:XF 0 "s_register_operand" "=f")
1846 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1847 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1849 [(set_attr "type" "ffarith")])
1851 ;; abssi2 doesn't really clobber the condition codes if a different register
1852 ;; is being set. To keep things simple, assume during rtl manipulations that
1853 ;; it does, but tell the final scan operator the truth. Similarly for
1856 (define_insn "abssi2"
1857 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1858 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1862 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1863 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1864 [(set_attr "conds" "clob,*")
1865 (set_attr "length" "8")])
1867 (define_insn "*neg_abssi2"
1868 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1869 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1873 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1874 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1875 [(set_attr "conds" "clob,*")
1876 (set_attr "length" "8")])
1878 (define_insn "abssf2"
1879 [(set (match_operand:SF 0 "s_register_operand" "=f")
1880 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1883 [(set_attr "type" "ffarith")])
1885 (define_insn "absdf2"
1886 [(set (match_operand:DF 0 "s_register_operand" "=f")
1887 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1890 [(set_attr "type" "ffarith")])
1892 (define_insn "*absdf_esfdf"
1893 [(set (match_operand:DF 0 "s_register_operand" "=f")
1894 (abs:DF (float_extend:DF
1895 (match_operand:SF 1 "s_register_operand" "f"))))]
1898 [(set_attr "type" "ffarith")])
1900 (define_insn "absxf2"
1901 [(set (match_operand:XF 0 "s_register_operand" "=f")
1902 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1903 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1905 [(set_attr "type" "ffarith")])
1907 (define_insn "sqrtsf2"
1908 [(set (match_operand:SF 0 "s_register_operand" "=f")
1909 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1912 [(set_attr "type" "float_em")])
1914 (define_insn "sqrtdf2"
1915 [(set (match_operand:DF 0 "s_register_operand" "=f")
1916 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1919 [(set_attr "type" "float_em")])
1921 (define_insn "*sqrtdf_esfdf"
1922 [(set (match_operand:DF 0 "s_register_operand" "=f")
1923 (sqrt:DF (float_extend:DF
1924 (match_operand:SF 1 "s_register_operand" "f"))))]
1927 [(set_attr "type" "float_em")])
1929 (define_insn "sqrtxf2"
1930 [(set (match_operand:XF 0 "s_register_operand" "=f")
1931 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1932 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1934 [(set_attr "type" "float_em")])
1936 ;; SIN COS TAN and family are always emulated, so it's probably better
1937 ;; to always call a library function.
1938 ;(define_insn "sinsf2"
1939 ; [(set (match_operand:SF 0 "s_register_operand" "=f")
1940 ; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1941 ; "TARGET_HARD_FLOAT"
1943 ;[(set_attr "type" "float_em")])
1945 ;(define_insn "sindf2"
1946 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1947 ; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1948 ; "TARGET_HARD_FLOAT"
1950 ;[(set_attr "type" "float_em")])
1952 ;(define_insn "*sindf_esfdf"
1953 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1954 ; (unspec:DF [(float_extend:DF
1955 ; (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1956 ; "TARGET_HARD_FLOAT"
1958 ;[(set_attr "type" "float_em")])
1960 ;(define_insn "sinxf2"
1961 ; [(set (match_operand:XF 0 "s_register_operand" "=f")
1962 ; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1963 ; "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1965 ;[(set_attr "type" "float_em")])
1967 ;(define_insn "cossf2"
1968 ; [(set (match_operand:SF 0 "s_register_operand" "=f")
1969 ; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
1970 ; "TARGET_HARD_FLOAT"
1972 ;[(set_attr "type" "float_em")])
1974 ;(define_insn "cosdf2"
1975 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1976 ; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
1977 ; "TARGET_HARD_FLOAT"
1979 ;[(set_attr "type" "float_em")])
1981 ;(define_insn "*cosdf_esfdf"
1982 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1983 ; (unspec:DF [(float_extend:DF
1984 ; (match_operand:SF 1 "s_register_operand" "f"))] 1))]
1985 ; "TARGET_HARD_FLOAT"
1987 ;[(set_attr "type" "float_em")])
1989 ;(define_insn "cosxf2"
1990 ; [(set (match_operand:XF 0 "s_register_operand" "=f")
1991 ; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
1992 ; "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1994 ;[(set_attr "type" "float_em")])
1996 (define_insn "one_cmpldi2"
1997 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1998 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
2000 "mvn%?\\t%Q0, %Q1\;mvn%?\\t%R0, %R1"
2001 [(set_attr "length" "8")])
2003 (define_insn "one_cmplsi2"
2004 [(set (match_operand:SI 0 "s_register_operand" "=r")
2005 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
2009 (define_insn "*notsi_compare0"
2010 [(set (reg:CC_NOOV 24)
2011 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
2013 (set (match_operand:SI 0 "s_register_operand" "=r")
2014 (not:SI (match_dup 1)))]
2017 [(set_attr "conds" "set")])
2019 (define_insn "*notsi_compare0_scratch"
2020 [(set (reg:CC_NOOV 24)
2021 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
2023 (clobber (match_scratch:SI 0 "=r"))]
2026 [(set_attr "conds" "set")])
2028 ;; Fixed <--> Floating conversion insns
2030 (define_insn "floatsisf2"
2031 [(set (match_operand:SF 0 "s_register_operand" "=f")
2032 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
2035 [(set_attr "type" "r_2_f")])
2037 (define_insn "floatsidf2"
2038 [(set (match_operand:DF 0 "s_register_operand" "=f")
2039 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
2042 [(set_attr "type" "r_2_f")])
2044 (define_insn "floatsixf2"
2045 [(set (match_operand:XF 0 "s_register_operand" "=f")
2046 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
2047 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2049 [(set_attr "type" "r_2_f")])
2051 (define_insn "fix_truncsfsi2"
2052 [(set (match_operand:SI 0 "s_register_operand" "=r")
2053 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
2056 [(set_attr "type" "f_2_r")])
2058 (define_insn "fix_truncdfsi2"
2059 [(set (match_operand:SI 0 "s_register_operand" "=r")
2060 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
2063 [(set_attr "type" "f_2_r")])
2065 (define_insn "fix_truncxfsi2"
2066 [(set (match_operand:SI 0 "s_register_operand" "=r")
2067 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
2068 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2070 [(set_attr "type" "f_2_r")])
2074 (define_insn "truncdfsf2"
2075 [(set (match_operand:SF 0 "s_register_operand" "=f")
2077 (match_operand:DF 1 "s_register_operand" "f")))]
2080 [(set_attr "type" "ffarith")])
2082 (define_insn "truncxfsf2"
2083 [(set (match_operand:SF 0 "s_register_operand" "=f")
2085 (match_operand:XF 1 "s_register_operand" "f")))]
2086 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2088 [(set_attr "type" "ffarith")])
2090 (define_insn "truncxfdf2"
2091 [(set (match_operand:DF 0 "s_register_operand" "=f")
2093 (match_operand:XF 1 "s_register_operand" "f")))]
2094 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2096 [(set_attr "type" "ffarith")])
2098 ;; Zero and sign extension instructions.
2100 (define_insn "zero_extendsidi2"
2101 [(set (match_operand:DI 0 "s_register_operand" "=r")
2102 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
2105 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
2106 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
2107 return \"mov%?\\t%R0, #0\";
2109 [(set_attr "length" "8")])
2111 (define_insn "zero_extendqidi2"
2112 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
2113 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2116 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
2117 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
2118 [(set_attr "length" "8")
2119 (set_attr "type" "*,load")])
2121 (define_insn "extendsidi2"
2122 [(set (match_operand:DI 0 "s_register_operand" "=r")
2123 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
2126 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
2127 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
2128 return \"mov%?\\t%R0, %Q0, asr #31\";
2130 [(set_attr "length" "8")])
2132 (define_expand "zero_extendhisi2"
2133 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2135 (set (match_operand:SI 0 "s_register_operand" "")
2136 (lshiftrt:SI (match_dup 2) (const_int 16)))]
2140 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2142 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2143 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
2146 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2148 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
2151 if (! s_register_operand (operands[1], HImode))
2152 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2153 operands[1] = gen_lowpart (SImode, operands[1]);
2154 operands[2] = gen_reg_rtx (SImode);
2157 (define_insn "*zero_extendhisi_insn"
2158 [(set (match_operand:SI 0 "s_register_operand" "=r")
2159 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2162 [(set_attr "type" "load")])
2165 [(set (match_operand:SI 0 "s_register_operand" "")
2166 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2167 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2169 [(set (match_dup 2) (match_dup 1))
2170 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
2173 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2178 [(set (match_operand:SI 0 "s_register_operand" "")
2179 (match_operator:SI 3 "shiftable_operator"
2180 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2181 (match_operand:SI 4 "s_register_operand" "")]))
2182 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2184 [(set (match_dup 2) (match_dup 1))
2187 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2190 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2194 (define_expand "zero_extendqisi2"
2195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2197 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2200 if (GET_CODE (operands[1]) != MEM)
2202 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
2208 (define_insn "*load_extendqisi"
2209 [(set (match_operand:SI 0 "s_register_operand" "=r")
2210 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2212 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
2213 [(set_attr "type" "load")])
2216 [(set (match_operand:SI 0 "s_register_operand" "")
2217 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
2218 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2219 "GET_CODE (operands[1]) != MEM"
2220 [(set (match_dup 2) (match_dup 1))
2221 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
2224 (define_insn "*compareqi_eq0"
2226 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
2230 [(set_attr "conds" "set")])
2232 (define_expand "extendhisi2"
2234 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2236 (set (match_operand:SI 0 "s_register_operand" "")
2237 (ashiftrt:SI (match_dup 2)
2242 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2244 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2245 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2249 if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
2251 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
2254 if (! s_register_operand (operands[1], HImode))
2255 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2256 operands[1] = gen_lowpart (SImode, operands[1]);
2257 operands[2] = gen_reg_rtx (SImode);
2260 (define_expand "extendhisi2_mem"
2261 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
2263 (zero_extend:SI (match_dup 7)))
2264 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
2265 (set (match_operand:SI 0 "" "")
2266 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
2271 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2273 mem1 = gen_rtx (MEM, QImode, addr);
2274 MEM_VOLATILE_P (mem1) = MEM_VOLATILE_P (operands[1]);
2275 MEM_IN_STRUCT_P (mem1) = MEM_IN_STRUCT_P (operands[1]);
2276 RTX_UNCHANGING_P (mem1) = RTX_UNCHANGING_P (operands[1]);
2277 mem2 = gen_rtx (MEM, QImode, plus_constant (addr, 1));
2278 MEM_VOLATILE_P (mem2) = MEM_VOLATILE_P (operands[1]);
2279 MEM_IN_STRUCT_P (mem2) = MEM_IN_STRUCT_P (operands[1]);
2280 RTX_UNCHANGING_P (mem2) = RTX_UNCHANGING_P (operands[1]);
2281 operands[0] = gen_lowpart (SImode, operands[0]);
2283 operands[2] = gen_reg_rtx (SImode);
2284 operands[3] = gen_reg_rtx (SImode);
2285 operands[6] = gen_reg_rtx (SImode);
2288 if (BYTES_BIG_ENDIAN)
2290 operands[4] = operands[2];
2291 operands[5] = operands[3];
2295 operands[4] = operands[3];
2296 operands[5] = operands[2];
2301 (define_insn "*extendhisi_insn"
2302 [(set (match_operand:SI 0 "s_register_operand" "=r")
2303 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2306 [(set_attr "type" "load")])
2309 [(set (match_operand:SI 0 "s_register_operand" "")
2310 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2311 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2313 [(set (match_dup 2) (match_dup 1))
2314 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
2317 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2322 [(set (match_operand:SI 0 "s_register_operand" "")
2323 (match_operator:SI 3 "shiftable_operator"
2324 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2325 (match_operand:SI 4 "s_register_operand" "")]))
2326 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2328 [(set (match_dup 2) (match_dup 1))
2331 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2334 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2338 (define_expand "extendqihi2"
2340 (ashift:SI (match_operand:QI 1 "general_operand" "")
2342 (set (match_operand:HI 0 "s_register_operand" "")
2343 (ashiftrt:SI (match_dup 2)
2348 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2350 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2351 gen_rtx (SIGN_EXTEND, HImode, operands[1])));
2354 if (! s_register_operand (operands[1], QImode))
2355 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2356 operands[0] = gen_lowpart (SImode, operands[0]);
2357 operands[1] = gen_lowpart (SImode, operands[1]);
2358 operands[2] = gen_reg_rtx (SImode);
2361 ; Rather than restricting all byte accesses to memory addresses that ldrsb
2362 ; can handle, we fix up the ones that ldrsb can't grok with a split.
2363 (define_insn "*extendqihi_insn"
2364 [(set (match_operand:HI 0 "s_register_operand" "=r")
2365 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2368 /* If the address is invalid, this will split the instruction into two. */
2369 if (bad_signed_byte_operand(operands[1], QImode))
2371 return \"ldr%?sb\\t%0, %1\";
2373 [(set_attr "type" "load")
2374 (set_attr "length" "8")])
2377 [(set (match_operand:HI 0 "s_register_operand" "")
2378 (sign_extend:HI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
2379 "arm_arch4 && reload_completed"
2380 [(set (match_dup 3) (match_dup 1))
2381 (set (match_dup 0) (sign_extend:HI (match_dup 2)))]
2384 HOST_WIDE_INT offset;
2386 operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]));
2387 operands[2] = gen_rtx (MEM, QImode, operands[3]);
2388 MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
2389 MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
2390 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
2391 operands[1] = XEXP (operands[1], 0);
2392 if (GET_CODE (operands[1]) == PLUS
2393 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2394 && ! (const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1)))
2395 || const_ok_for_arm (-offset)))
2397 HOST_WIDE_INT low = (offset > 0
2398 ? (offset & 0xff) : -((-offset) & 0xff));
2399 XEXP (operands[2], 0) = plus_constant (operands[3], low);
2400 operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
2405 (define_expand "extendqisi2"
2407 (ashift:SI (match_operand:QI 1 "general_operand" "")
2409 (set (match_operand:SI 0 "s_register_operand" "")
2410 (ashiftrt:SI (match_dup 2)
2415 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2417 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2418 gen_rtx (SIGN_EXTEND, SImode, operands[1])));
2421 if (! s_register_operand (operands[1], QImode))
2422 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2423 operands[1] = gen_lowpart (SImode, operands[1]);
2424 operands[2] = gen_reg_rtx (SImode);
2427 ; Rather than restricting all byte accesses to memory addresses that ldrsb
2428 ; can handle, we fix up the ones that ldrsb can't grok with a split.
2429 (define_insn "*extendqisi_insn"
2430 [(set (match_operand:SI 0 "s_register_operand" "=r")
2431 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2434 /* If the address is invalid, this will split the instruction into two. */
2435 if (bad_signed_byte_operand(operands[1], QImode))
2437 return \"ldr%?sb\\t%0, %1\";
2439 [(set_attr "type" "load")
2440 (set_attr "length" "8")])
2443 [(set (match_operand:SI 0 "s_register_operand" "")
2444 (sign_extend:SI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
2445 "arm_arch4 && reload_completed"
2446 [(set (match_dup 0) (match_dup 1))
2447 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2450 HOST_WIDE_INT offset;
2452 operands[2] = gen_rtx (MEM, QImode, operands[0]);
2453 MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
2454 MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
2455 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
2456 operands[1] = XEXP (operands[1], 0);
2457 if (GET_CODE (operands[1]) == PLUS
2458 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2459 && ! (const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1)))
2460 || const_ok_for_arm (-offset)))
2462 HOST_WIDE_INT low = (offset > 0
2463 ? (offset & 0xff) : -((-offset) & 0xff));
2464 XEXP (operands[2], 0) = plus_constant (operands[0], low);
2465 operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
2470 (define_insn "extendsfdf2"
2471 [(set (match_operand:DF 0 "s_register_operand" "=f")
2472 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
2475 [(set_attr "type" "ffarith")])
2477 (define_insn "extendsfxf2"
2478 [(set (match_operand:XF 0 "s_register_operand" "=f")
2479 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
2480 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2482 [(set_attr "type" "ffarith")])
2484 (define_insn "extenddfxf2"
2485 [(set (match_operand:XF 0 "s_register_operand" "=f")
2486 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
2487 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2489 [(set_attr "type" "ffarith")])
2492 ;; Move insns (including loads and stores)
2494 ;; XXX Just some ideas about movti.
2495 ;; I don't think these are a good idea on the arm, there just aren't enough
2497 ;;(define_expand "loadti"
2498 ;; [(set (match_operand:TI 0 "s_register_operand" "")
2499 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
2502 ;;(define_expand "storeti"
2503 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
2504 ;; (match_operand:TI 1 "s_register_operand" ""))]
2507 ;;(define_expand "movti"
2508 ;; [(set (match_operand:TI 0 "general_operand" "")
2509 ;; (match_operand:TI 1 "general_operand" ""))]
2515 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2516 ;; operands[1] = copy_to_reg (operands[1]);
2517 ;; if (GET_CODE (operands[0]) == MEM)
2518 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
2519 ;; else if (GET_CODE (operands[1]) == MEM)
2520 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
2524 ;; emit_insn (insn);
2528 ;; Recognise garbage generated above.
2531 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
2532 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
2536 ;; register mem = (which_alternative < 3);
2537 ;; register char *template;
2539 ;; operands[mem] = XEXP (operands[mem], 0);
2540 ;; switch (which_alternative)
2542 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
2543 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
2544 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
2545 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
2546 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
2547 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
2549 ;; output_asm_insn (template, operands);
2554 (define_insn "movdi"
2555 [(set (match_operand:DI 0 "di_operand" "=r,r,o<>")
2556 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
2559 return (output_move_double (operands));
2561 [(set_attr "length" "8,8,8")
2562 (set_attr "type" "*,load,store2")])
2564 (define_expand "movsi"
2565 [(set (match_operand:SI 0 "general_operand" "")
2566 (match_operand:SI 1 "general_operand" ""))]
2569 /* Everything except mem = const or mem = mem can be done easily */
2570 if (GET_CODE (operands[0]) == MEM)
2571 operands[1] = force_reg (SImode, operands[1]);
2572 if (GET_CODE (operands[1]) == CONST_INT
2573 && !(const_ok_for_arm (INTVAL (operands[1]))
2574 || const_ok_for_arm (~INTVAL (operands[1]))))
2576 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2578 (reload_in_progress || reload_completed ? 0
2579 : preserve_subexpressions_p ()));
2582 if (CONSTANT_P (operands[1]) && flag_pic)
2583 operands[1] = legitimize_pic_address (operands[1], SImode,
2584 ((reload_in_progress
2585 || reload_completed)
2586 ? operands[0] : 0));
2589 (define_insn "*movsi_insn"
2590 [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
2591 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
2592 "register_operand (operands[0], SImode)
2593 || register_operand (operands[1], SImode)"
2599 [(set_attr "type" "*,*,load,store1")])
2602 [(set (match_operand:SI 0 "s_register_operand" "")
2603 (match_operand:SI 1 "const_int_operand" ""))]
2604 "! (const_ok_for_arm (INTVAL (operands[1]))
2605 || const_ok_for_arm (~INTVAL (operands[1])))"
2606 [(clobber (const_int 0))]
2608 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2613 (define_expand "movaddr"
2614 [(set (match_operand:SI 0 "s_register_operand" "")
2615 (match_operand:DI 1 "address_operand" ""))]
2619 (define_insn "*movaddr_insn"
2620 [(set (match_operand:SI 0 "s_register_operand" "=r")
2621 (match_operand:DI 1 "address_operand" "p"))]
2623 && (GET_CODE (operands[1]) == LABEL_REF
2624 || (GET_CODE (operands[1]) == CONST
2625 && GET_CODE (XEXP (operands[1], 0)) == PLUS
2626 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2627 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
2630 /* When generating pic, we need to load the symbol offset into a register.
2631 So that the optimizer does not confuse this with a normal symbol load
2632 we use an unspec. The offset will be loaded from a constant pool entry,
2633 since that is the only type of relocation we can use. */
2635 (define_insn "pic_load_addr"
2636 [(set (match_operand:SI 0 "s_register_operand" "=r")
2637 (unspec:SI [(match_operand 1 "" "")] 3))]
2640 [(set_attr "type" "load")])
2642 ;; This variant is used for AOF assembly, since it needs to mention the
2643 ;; pic register in the rtl.
2644 (define_expand "pic_load_addr_based"
2645 [(set (match_operand:SI 0 "s_register_operand" "=r")
2646 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] 3))]
2648 "operands[2] = pic_offset_table_rtx;")
2650 (define_insn "*pic_load_addr_based_insn"
2651 [(set (match_operand:SI 0 "s_register_operand" "=r")
2652 (unspec:SI [(match_operand 1 "" "")
2653 (match_operand 2 "s_register_operand" "r")] 3))]
2654 "flag_pic && operands[2] == pic_offset_table_rtx"
2656 #ifdef AOF_ASSEMBLER
2657 operands[1] = aof_pic_entry (operands[1]);
2659 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
2661 " [(set_attr "type" "load")])
2663 (define_insn "pic_add_dot_plus_eight"
2664 [(set (pc) (label_ref (match_operand 0 "" "")))
2665 (set (match_operand 1 "register_operand" "+r")
2666 (plus:SI (match_dup 1) (const (plus:SI (pc) (const_int 8)))))]
2668 "add%?\\t%1, %|pc, %1")
2670 ;; If copying one reg to another we can set the condition codes according to
2671 ;; its value. Such a move is common after a return from subroutine and the
2672 ;; result is being tested against zero.
2674 (define_insn "*movsi_compare0"
2675 [(set (reg:CC 24) (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
2677 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2681 sub%?s\\t%0, %1, #0"
2682 [(set_attr "conds" "set")])
2684 ;; Subroutine to store a half word from a register into memory.
2685 ;; Operand 0 is the source register (HImode)
2686 ;; Operand 1 is the destination address in a register (SImode)
2688 ;; In both this routine and the next, we must be careful not to spill
2689 ;; a memory address of reg+large_const into a separate PLUS insn, since this
2690 ;; can generate unrecognizable rtl.
2692 (define_expand "storehi"
2693 [;; store the low byte
2694 (set (match_operand 1 "" "") (match_dup 3))
2695 ;; extract the high byte
2697 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2698 ;; store the high byte
2699 (set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2703 rtx addr = XEXP (operands[1], 0);
2704 enum rtx_code code = GET_CODE (addr);
2706 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
2708 addr = force_reg (SImode, addr);
2710 operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1));
2711 operands[1] = change_address (operands[1], QImode, NULL_RTX);
2712 operands[3] = gen_lowpart (QImode, operands[0]);
2713 operands[0] = gen_lowpart (SImode, operands[0]);
2714 operands[2] = gen_reg_rtx (SImode);
2718 (define_expand "storehi_bigend"
2719 [(set (match_dup 4) (match_dup 3))
2721 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2722 (set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))]
2726 rtx addr = XEXP (operands[1], 0);
2727 enum rtx_code code = GET_CODE (addr);
2729 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
2731 addr = force_reg (SImode, addr);
2733 operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1));
2734 operands[1] = change_address (operands[1], QImode, NULL_RTX);
2735 operands[3] = gen_lowpart (QImode, operands[0]);
2736 operands[0] = gen_lowpart (SImode, operands[0]);
2737 operands[2] = gen_reg_rtx (SImode);
2741 ;; Subroutine to store a half word integer constant into memory.
2742 (define_expand "storeinthi"
2743 [(set (match_operand 0 "" "")
2744 (subreg:QI (match_operand 1 "" "") 0))
2745 (set (match_dup 3) (subreg:QI (match_dup 2) 0))]
2749 HOST_WIDE_INT value = INTVAL (operands[1]);
2750 rtx addr = XEXP (operands[0], 0);
2751 enum rtx_code code = GET_CODE (addr);
2753 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
2755 addr = force_reg (SImode, addr);
2757 operands[1] = gen_reg_rtx (SImode);
2758 if (BYTES_BIG_ENDIAN)
2760 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2761 if ((value & 255) == ((value >> 8) & 255))
2762 operands[2] = operands[1];
2765 operands[2] = gen_reg_rtx (SImode);
2766 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2771 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2772 if ((value & 255) == ((value >> 8) & 255))
2773 operands[2] = operands[1];
2776 operands[2] = gen_reg_rtx (SImode);
2777 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2781 operands[3] = change_address (operands[0], QImode, plus_constant (addr, 1));
2782 operands[0] = change_address (operands[0], QImode, NULL_RTX);
2786 (define_expand "storehi_single_op"
2787 [(set (match_operand:HI 0 "memory_operand" "")
2788 (match_operand:HI 1 "general_operand" ""))]
2791 if (! s_register_operand (operands[1], HImode))
2792 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2795 (define_expand "movhi"
2796 [(set (match_operand:HI 0 "general_operand" "")
2797 (match_operand:HI 1 "general_operand" ""))]
2803 if (! (reload_in_progress || reload_completed))
2805 if (GET_CODE (operands[0]) == MEM)
2809 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
2812 if (GET_CODE (operands[1]) == CONST_INT)
2813 emit_insn (gen_storeinthi (operands[0], operands[1]));
2816 if (GET_CODE (operands[1]) == MEM)
2817 operands[1] = force_reg (HImode, operands[1]);
2818 if (BYTES_BIG_ENDIAN)
2819 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
2821 emit_insn (gen_storehi (operands[1], operands[0]));
2825 /* Sign extend a constant, and keep it in an SImode reg. */
2826 else if (GET_CODE (operands[1]) == CONST_INT)
2828 rtx reg = gen_reg_rtx (SImode);
2829 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2831 /* If the constant is already valid, leave it alone. */
2832 if (! const_ok_for_arm (val))
2834 /* If setting all the top bits will make the constant
2835 loadable in a single instruction, then set them.
2836 Otherwise, sign extend the number. */
2838 if (const_ok_for_arm (~ (val | ~0xffff)))
2840 else if (val & 0x8000)
2844 emit_insn (gen_movsi (reg, GEN_INT (val)));
2845 operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
2847 else if (! arm_arch4)
2849 if (GET_CODE (operands[1]) == MEM)
2851 if (TARGET_SHORT_BY_BYTES)
2854 rtx offset = const0_rtx;
2855 rtx reg = gen_reg_rtx (SImode);
2857 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2858 || (GET_CODE (base) == PLUS
2859 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2860 && GET_CODE (base = XEXP (base, 0)) == REG))
2861 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2863 HOST_WIDE_INT new_offset = INTVAL (offset) & ~2;
2866 new = gen_rtx (MEM, SImode,
2867 plus_constant (base, new_offset));
2868 MEM_VOLATILE_P (new) = MEM_VOLATILE_P (operands[1]);
2869 MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (operands[1]);
2870 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
2871 emit_insn (gen_movsi (reg, new));
2872 if (((INTVAL (offset) & 2) != 0)
2873 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
2875 rtx reg2 = gen_reg_rtx (SImode);
2877 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
2882 emit_insn (gen_movhi_bytes (reg, operands[1]));
2884 operands[1] = gen_lowpart (HImode, reg);
2886 else if (BYTES_BIG_ENDIAN)
2889 rtx offset = const0_rtx;
2891 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2892 || (GET_CODE (base) == PLUS
2893 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2894 && GET_CODE (base = XEXP (base, 0)) == REG))
2895 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2897 rtx reg = gen_reg_rtx (SImode);
2900 if ((INTVAL (offset) & 2) == 2)
2902 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
2903 new = gen_rtx (MEM, SImode,
2904 plus_constant (base, new_offset));
2905 MEM_VOLATILE_P (new) = MEM_VOLATILE_P (operands[1]);
2906 MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (operands[1]);
2907 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
2908 emit_insn (gen_movsi (reg, new));
2912 new = gen_rtx (MEM, SImode, XEXP (operands[1], 0));
2913 MEM_VOLATILE_P (new) = MEM_VOLATILE_P (operands[1]);
2914 MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (operands[1]);
2915 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
2916 emit_insn (gen_rotated_loadsi (reg, new));
2919 operands[1] = gen_lowpart (HImode, reg);
2923 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2930 /* Handle loading a large integer during reload */
2931 else if (GET_CODE (operands[1]) == CONST_INT
2932 && ! const_ok_for_arm (INTVAL (operands[1]))
2933 && ! const_ok_for_arm (~INTVAL (operands[1])))
2935 /* Writing a constant to memory needs a scratch, which should
2936 be handled with SECONDARY_RELOADs. */
2937 if (GET_CODE (operands[0]) != REG)
2940 operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0);
2941 emit_insn (gen_movsi (operands[0], operands[1]));
2947 (define_insn "rotated_loadsi"
2948 [(set (match_operand:SI 0 "s_register_operand" "=r")
2949 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
2951 "! TARGET_SHORT_BY_BYTES"
2956 ops[0] = operands[0];
2957 ops[1] = gen_rtx (MEM, SImode, plus_constant (XEXP (operands[1], 0), 2));
2958 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
2961 [(set_attr "type" "load")])
2963 (define_expand "movhi_bytes"
2964 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
2966 (zero_extend:SI (match_dup 6)))
2967 (set (match_operand:SI 0 "" "")
2968 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
2973 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2975 mem1 = gen_rtx (MEM, QImode, addr);
2976 MEM_VOLATILE_P (mem1) = MEM_VOLATILE_P (operands[1]);
2977 MEM_IN_STRUCT_P (mem1) = MEM_IN_STRUCT_P (operands[1]);
2978 RTX_UNCHANGING_P (mem1) = RTX_UNCHANGING_P (operands[1]);
2979 mem2 = gen_rtx (MEM, QImode, plus_constant (addr, 1));
2980 MEM_VOLATILE_P (mem2) = MEM_VOLATILE_P (operands[1]);
2981 MEM_IN_STRUCT_P (mem2) = MEM_IN_STRUCT_P (operands[1]);
2982 RTX_UNCHANGING_P (mem2) = RTX_UNCHANGING_P (operands[1]);
2983 operands[0] = gen_lowpart (SImode, operands[0]);
2985 operands[2] = gen_reg_rtx (SImode);
2986 operands[3] = gen_reg_rtx (SImode);
2989 if (BYTES_BIG_ENDIAN)
2991 operands[4] = operands[2];
2992 operands[5] = operands[3];
2996 operands[4] = operands[3];
2997 operands[5] = operands[2];
3002 (define_expand "movhi_bigend"
3004 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
3007 (ashiftrt:SI (match_dup 2) (const_int 16)))
3008 (set (match_operand:HI 0 "s_register_operand" "")
3009 (subreg:HI (match_dup 3) 0))]
3012 operands[2] = gen_reg_rtx (SImode);
3013 operands[3] = gen_reg_rtx (SImode);
3016 ;; Pattern to recognise insn generated default case above
3018 (define_insn "*movhi_insn_arch4"
3019 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
3020 (match_operand:HI 1 "general_operand" "rI,K,m,r"))]
3022 && (GET_CODE (operands[1]) != CONST_INT
3023 || const_ok_for_arm (INTVAL (operands[1]))
3024 || const_ok_for_arm (~INTVAL (operands[1])))"
3026 mov%?\\t%0, %1\\t%@ movhi
3027 mvn%?\\t%0, #%B1\\t%@ movhi
3028 ldr%?h\\t%0, %1\\t%@ movhi
3029 str%?h\\t%1, %0\\t%@ movhi"
3030 [(set_attr "type" "*,*,load,store1")])
3032 (define_insn "*movhi_insn_littleend"
3033 [(set (match_operand:HI 0 "general_operand" "=r,r,r")
3034 (match_operand:HI 1 "general_operand" "rI,K,m"))]
3036 && ! BYTES_BIG_ENDIAN
3037 && ! TARGET_SHORT_BY_BYTES
3038 && (GET_CODE (operands[1]) != CONST_INT
3039 || const_ok_for_arm (INTVAL (operands[1]))
3040 || const_ok_for_arm (~INTVAL (operands[1])))"
3042 mov%?\\t%0, %1\\t%@ movhi
3043 mvn%?\\t%0, #%B1\\t%@ movhi
3044 ldr%?\\t%0, %1\\t%@ movhi"
3045 [(set_attr "type" "*,*,load")])
3047 (define_insn "*movhi_insn_bigend"
3048 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
3049 (match_operand:HI 1 "general_operand" "rI,K,m"))]
3052 && ! TARGET_SHORT_BY_BYTES
3053 && (GET_CODE (operands[1]) != CONST_INT
3054 || const_ok_for_arm (INTVAL (operands[1]))
3055 || const_ok_for_arm (~INTVAL (operands[1])))"
3057 mov%?\\t%0, %1\\t%@ movhi
3058 mvn%?\\t%0, #%B1\\t%@ movhi
3059 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
3060 [(set_attr "type" "*,*,load")
3061 (set_attr "length" "4,4,8")])
3063 (define_insn "*loadhi_si_bigend"
3064 [(set (match_operand:SI 0 "s_register_operand" "=r")
3065 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
3068 && ! TARGET_SHORT_BY_BYTES"
3069 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
3070 [(set_attr "type" "load")])
3072 (define_insn "*movhi_bytes"
3073 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
3074 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
3075 "TARGET_SHORT_BY_BYTES"
3077 mov%?\\t%0, %1\\t%@ movhi
3078 mvn%?\\t%0, #%B1\\t%@ movhi")
3081 (define_expand "reload_outhi"
3082 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
3083 (match_operand:HI 1 "s_register_operand" "r")
3084 (match_operand:SI 2 "s_register_operand" "=&r")])]
3087 arm_reload_out_hi (operands);
3091 (define_expand "reload_inhi"
3092 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
3093 (match_operand:HI 1 "reload_memory_operand" "o")
3094 (match_operand:SI 2 "s_register_operand" "=&r")])]
3095 "TARGET_SHORT_BY_BYTES"
3097 arm_reload_in_hi (operands);
3101 (define_expand "movqi"
3102 [(set (match_operand:QI 0 "general_operand" "")
3103 (match_operand:QI 1 "general_operand" ""))]
3106 /* Everything except mem = const or mem = mem can be done easily */
3108 if (!(reload_in_progress || reload_completed))
3110 if (GET_CODE (operands[1]) == CONST_INT)
3112 rtx reg = gen_reg_rtx (SImode);
3114 emit_insn (gen_movsi (reg, operands[1]));
3115 operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
3117 if (GET_CODE (operands[0]) == MEM)
3118 operands[1] = force_reg (QImode, operands[1]);
3123 (define_insn "*movqi_insn"
3124 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
3125 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
3126 "register_operand (operands[0], QImode)
3127 || register_operand (operands[1], QImode)"
3133 [(set_attr "type" "*,*,load,store1")])
3135 (define_expand "movsf"
3136 [(set (match_operand:SF 0 "general_operand" "")
3137 (match_operand:SF 1 "general_operand" ""))]
3140 if (GET_CODE (operands[0]) == MEM)
3141 operands[1] = force_reg (SFmode, operands[1]);
3144 (define_insn "*movsf_hard_insn"
3145 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
3146 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
3148 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
3154 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
3155 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
3157 ldr%?\\t%0, %1\\t%@ float
3158 str%?\\t%1, %0\\t%@ float"
3159 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
3161 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
3163 ;; Exactly the same as above, except that all `f' cases are deleted.
3164 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3165 ;; when -msoft-float.
3167 (define_insn "*movsf_soft_insn"
3168 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
3169 (match_operand:SF 1 "general_operand" "r,mE,r"))]
3171 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
3174 ldr%?\\t%0, %1\\t%@ float
3175 str%?\\t%1, %0\\t%@ float"
3176 [(set_attr "length" "4,4,4")
3177 (set_attr "type" "*,load,store1")])
3179 (define_expand "movdf"
3180 [(set (match_operand:DF 0 "general_operand" "")
3181 (match_operand:DF 1 "general_operand" ""))]
3184 if (GET_CODE (operands[0]) == MEM)
3185 operands[1] = force_reg (DFmode, operands[1]);
3188 ;; Reloading a df mode value stored in integer regs to memory can require a
3190 (define_expand "reload_outdf"
3191 [(match_operand:DF 0 "reload_memory_operand" "=o")
3192 (match_operand:DF 1 "s_register_operand" "r")
3193 (match_operand:SI 2 "s_register_operand" "=&r")]
3197 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
3200 operands[2] = XEXP (operands[0], 0);
3201 else if (code == POST_INC || code == PRE_DEC)
3203 operands[0] = gen_rtx (SUBREG, DImode, operands[0], 0);
3204 operands[1] = gen_rtx (SUBREG, DImode, operands[1], 0);
3205 emit_insn (gen_movdi (operands[0], operands[1]));
3208 else if (code == PRE_INC)
3210 rtx reg = XEXP (XEXP (operands[0], 0), 0);
3211 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
3214 else if (code == POST_DEC)
3215 operands[2] = XEXP (XEXP (operands[0], 0), 0);
3217 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
3218 XEXP (XEXP (operands[0], 0), 1)));
3220 emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
3223 if (code == POST_DEC)
3224 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
3230 (define_insn "*movdf_hard_insn"
3231 [(set (match_operand:DF 0 "general_operand" "=r,Q,r,m,r,f,f,f,m,!f,!r")
3232 (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,fG,H,mF,f,r,f"))]
3234 && (GET_CODE (operands[0]) != MEM
3235 || register_operand (operands[1], DFmode))"
3240 switch (which_alternative)
3242 case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
3243 case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
3244 case 2: case 3: case 4: return output_move_double (operands);
3245 case 5: return \"mvf%?d\\t%0, %1\";
3246 case 6: return \"mnf%?d\\t%0, #%N1\";
3247 case 7: return \"ldf%?d\\t%0, %1\";
3248 case 8: return \"stf%?d\\t%1, %0\";
3249 case 9: return output_mov_double_fpu_from_arm (operands);
3250 case 10: return output_mov_double_arm_from_fpu (operands);
3254 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
3256 "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")])
3258 ;; Software floating point version. This is essentially the same as movdi.
3259 ;; Do not use `f' as a constraint to prevent reload from ever trying to use
3262 (define_insn "*movdf_soft_insn"
3263 [(set (match_operand:DF 0 "soft_df_operand" "=r,r,m")
3264 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
3266 "* return output_move_double (operands);"
3267 [(set_attr "length" "8,8,8")
3268 (set_attr "type" "*,load,store2")])
3270 (define_expand "movxf"
3271 [(set (match_operand:XF 0 "general_operand" "")
3272 (match_operand:XF 1 "general_operand" ""))]
3273 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3276 ;; Even when the XFmode patterns aren't enabled, we enable this after
3277 ;; reloading so that we can push floating point registers in the prologue.
3279 (define_insn "*movxf_hard_insn"
3280 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
3281 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
3282 "TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
3284 switch (which_alternative)
3286 case 0: return \"mvf%?e\\t%0, %1\";
3287 case 1: return \"mnf%?e\\t%0, #%N1\";
3288 case 2: return \"ldf%?e\\t%0, %1\";
3289 case 3: return \"stf%?e\\t%1, %0\";
3290 case 4: return output_mov_long_double_fpu_from_arm (operands);
3291 case 5: return output_mov_long_double_arm_from_fpu (operands);
3292 case 6: return output_mov_long_double_arm_from_arm (operands);
3295 [(set_attr "length" "4,4,4,4,8,8,12")
3296 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
3299 ;; load- and store-multiple insns
3300 ;; The arm can load/store any set of registers, provided that they are in
3301 ;; ascending order; but that is beyond GCC so stick with what it knows.
3303 (define_expand "load_multiple"
3304 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3305 (match_operand:SI 1 "" ""))
3306 (use (match_operand:SI 2 "" ""))])]
3309 /* Support only fixed point registers */
3310 if (GET_CODE (operands[2]) != CONST_INT
3311 || INTVAL (operands[2]) > 14
3312 || INTVAL (operands[2]) < 2
3313 || GET_CODE (operands[1]) != MEM
3314 || GET_CODE (operands[0]) != REG
3315 || REGNO (operands[0]) > 14
3316 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
3320 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
3321 force_reg (SImode, XEXP (operands[1], 0)),
3322 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
3323 MEM_IN_STRUCT_P(operands[1]));
3326 ;; Load multiple with write-back
3328 (define_insn "*ldmsi_postinc"
3329 [(match_parallel 0 "load_multiple_operation"
3330 [(set (match_operand:SI 1 "s_register_operand" "+r")
3331 (plus:SI (match_dup 1)
3332 (match_operand:SI 2 "const_int_operand" "n")))
3333 (set (match_operand:SI 3 "s_register_operand" "=r")
3334 (mem:SI (match_dup 1)))])]
3335 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3339 int count = XVECLEN (operands[0], 0);
3341 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3342 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
3343 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
3345 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
3349 [(set_attr "type" "load")])
3351 ;; Ordinary load multiple
3353 (define_insn "*ldmsi"
3354 [(match_parallel 0 "load_multiple_operation"
3355 [(set (match_operand:SI 1 "s_register_operand" "=r")
3356 (mem:SI (match_operand:SI 2 "s_register_operand" "r")))])]
3361 int count = XVECLEN (operands[0], 0);
3363 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3364 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
3365 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
3367 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
3371 [(set_attr "type" "load")])
3373 (define_expand "store_multiple"
3374 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3375 (match_operand:SI 1 "" ""))
3376 (use (match_operand:SI 2 "" ""))])]
3379 /* Support only fixed point registers */
3380 if (GET_CODE (operands[2]) != CONST_INT
3381 || INTVAL (operands[2]) > 14
3382 || INTVAL (operands[2]) < 2
3383 || GET_CODE (operands[1]) != REG
3384 || GET_CODE (operands[0]) != MEM
3385 || REGNO (operands[1]) > 14
3386 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
3390 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
3391 force_reg (SImode, XEXP (operands[0], 0)),
3392 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
3393 MEM_IN_STRUCT_P(operands[0]));
3396 ;; Store multiple with write-back
3398 (define_insn "*stmsi_postinc"
3399 [(match_parallel 0 "store_multiple_operation"
3400 [(set (match_operand:SI 1 "s_register_operand" "+r")
3401 (plus:SI (match_dup 1)
3402 (match_operand:SI 2 "const_int_operand" "n")))
3403 (set (mem:SI (match_dup 1))
3404 (match_operand:SI 3 "s_register_operand" "r"))])]
3405 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3409 int count = XVECLEN (operands[0], 0);
3411 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3412 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
3413 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
3415 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
3420 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3421 (const_string "store2")
3422 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
3423 (const_string "store3")]
3424 (const_string "store4")))])
3426 ;; Ordinary store multiple
3428 (define_insn "*stmsi"
3429 [(match_parallel 0 "store_multiple_operation"
3430 [(set (mem:SI (match_operand:SI 2 "s_register_operand" "r"))
3431 (match_operand:SI 1 "s_register_operand" "r"))])]
3436 int count = XVECLEN (operands[0], 0);
3438 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
3439 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
3440 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
3442 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
3447 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
3448 (const_string "store2")
3449 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3450 (const_string "store3")]
3451 (const_string "store4")))])
3453 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
3454 ;; We could let this apply for blocks of less than this, but it clobbers so
3455 ;; many registers that there is then probably a better way.
3457 (define_expand "movstrqi"
3458 [(match_operand:BLK 0 "general_operand" "")
3459 (match_operand:BLK 1 "general_operand" "")
3460 (match_operand:SI 2 "const_int_operand" "")
3461 (match_operand:SI 3 "const_int_operand" "")]
3464 if (arm_gen_movstrqi (operands))
3470 ;; Comparison and test insns
3472 (define_expand "cmpsi"
3473 [(match_operand:SI 0 "s_register_operand" "")
3474 (match_operand:SI 1 "arm_add_operand" "")]
3478 arm_compare_op0 = operands[0];
3479 arm_compare_op1 = operands[1];
3485 (define_expand "cmpsf"
3486 [(match_operand:SF 0 "s_register_operand" "")
3487 (match_operand:SF 1 "fpu_rhs_operand" "")]
3491 arm_compare_op0 = operands[0];
3492 arm_compare_op1 = operands[1];
3498 (define_expand "cmpdf"
3499 [(match_operand:DF 0 "s_register_operand" "")
3500 (match_operand:DF 1 "fpu_rhs_operand" "")]
3504 arm_compare_op0 = operands[0];
3505 arm_compare_op1 = operands[1];
3511 (define_expand "cmpxf"
3512 [(match_operand:XF 0 "s_register_operand" "")
3513 (match_operand:XF 1 "fpu_rhs_operand" "")]
3514 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3517 arm_compare_op0 = operands[0];
3518 arm_compare_op1 = operands[1];
3524 (define_insn "*cmpsi_insn"
3526 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
3527 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
3532 [(set_attr "conds" "set")])
3534 (define_insn "*cmpsi_shiftsi"
3536 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3537 (match_operator:SI 3 "shift_operator"
3538 [(match_operand:SI 1 "s_register_operand" "r")
3539 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
3542 [(set_attr "conds" "set")])
3544 (define_insn "*cmpsi_shiftsi_swp"
3545 [(set (reg:CC_SWP 24)
3546 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
3547 [(match_operand:SI 1 "s_register_operand" "r")
3548 (match_operand:SI 2 "reg_or_int_operand" "rM")])
3549 (match_operand:SI 0 "s_register_operand" "r")))]
3552 [(set_attr "conds" "set")])
3554 (define_insn "*cmpsi_neg_shiftsi"
3556 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3557 (neg:SI (match_operator:SI 3 "shift_operator"
3558 [(match_operand:SI 1 "s_register_operand" "r")
3559 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
3562 [(set_attr "conds" "set")])
3564 (define_insn "*cmpsf_insn"
3566 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
3567 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3572 [(set_attr "conds" "set")
3573 (set_attr "type" "f_2_r")])
3575 (define_insn "*cmpdf_insn"
3577 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
3578 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3583 [(set_attr "conds" "set")
3584 (set_attr "type" "f_2_r")])
3586 (define_insn "*cmpesfdf_df"
3588 (compare:CCFP (float_extend:DF
3589 (match_operand:SF 0 "s_register_operand" "f,f"))
3590 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3595 [(set_attr "conds" "set")
3596 (set_attr "type" "f_2_r")])
3598 (define_insn "*cmpdf_esfdf"
3600 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
3602 (match_operand:SF 1 "s_register_operand" "f"))))]
3605 [(set_attr "conds" "set")
3606 (set_attr "type" "f_2_r")])
3608 (define_insn "*cmpxf_insn"
3610 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
3611 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3612 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3616 [(set_attr "conds" "set")
3617 (set_attr "type" "f_2_r")])
3619 (define_insn "*cmpsf_trap"
3620 [(set (reg:CCFPE 24)
3621 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
3622 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3627 [(set_attr "conds" "set")
3628 (set_attr "type" "f_2_r")])
3630 (define_insn "*cmpdf_trap"
3631 [(set (reg:CCFPE 24)
3632 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
3633 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3638 [(set_attr "conds" "set")
3639 (set_attr "type" "f_2_r")])
3641 (define_insn "*cmp_esfdf_df_trap"
3642 [(set (reg:CCFPE 24)
3643 (compare:CCFPE (float_extend:DF
3644 (match_operand:SF 0 "s_register_operand" "f,f"))
3645 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3650 [(set_attr "conds" "set")
3651 (set_attr "type" "f_2_r")])
3653 (define_insn "*cmp_df_esfdf_trap"
3654 [(set (reg:CCFPE 24)
3655 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
3657 (match_operand:SF 1 "s_register_operand" "f"))))]
3660 [(set_attr "conds" "set")
3661 (set_attr "type" "f_2_r")])
3663 (define_insn "*cmpxf_trap"
3664 [(set (reg:CCFPE 24)
3665 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
3666 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3667 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3671 [(set_attr "conds" "set")
3672 (set_attr "type" "f_2_r")])
3674 ; This insn allows redundant compares to be removed by cse, nothing should
3675 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
3676 ; is deleted later on. The match_dup will match the mode here, so that
3677 ; mode changes of the condition codes aren't lost by this even though we don't
3678 ; specify what they are.
3680 (define_insn "*deleted_compare"
3681 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
3683 "\\t%@ deleted compare"
3684 [(set_attr "conds" "set")
3685 (set_attr "length" "0")])
3688 ;; Conditional branch insns
3690 (define_expand "beq"
3692 (if_then_else (eq (match_dup 1) (const_int 0))
3693 (label_ref (match_operand 0 "" ""))
3698 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3703 (define_expand "bne"
3705 (if_then_else (ne (match_dup 1) (const_int 0))
3706 (label_ref (match_operand 0 "" ""))
3711 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3716 (define_expand "bgt"
3718 (if_then_else (gt (match_dup 1) (const_int 0))
3719 (label_ref (match_operand 0 "" ""))
3724 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3729 (define_expand "ble"
3731 (if_then_else (le (match_dup 1) (const_int 0))
3732 (label_ref (match_operand 0 "" ""))
3737 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3742 (define_expand "bge"
3744 (if_then_else (ge (match_dup 1) (const_int 0))
3745 (label_ref (match_operand 0 "" ""))
3750 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3755 (define_expand "blt"
3757 (if_then_else (lt (match_dup 1) (const_int 0))
3758 (label_ref (match_operand 0 "" ""))
3763 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3768 (define_expand "bgtu"
3770 (if_then_else (gtu (match_dup 1) (const_int 0))
3771 (label_ref (match_operand 0 "" ""))
3776 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3781 (define_expand "bleu"
3783 (if_then_else (leu (match_dup 1) (const_int 0))
3784 (label_ref (match_operand 0 "" ""))
3789 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3794 (define_expand "bgeu"
3796 (if_then_else (geu (match_dup 1) (const_int 0))
3797 (label_ref (match_operand 0 "" ""))
3802 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3807 (define_expand "bltu"
3809 (if_then_else (ltu (match_dup 1) (const_int 0))
3810 (label_ref (match_operand 0 "" ""))
3815 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3820 ;; patterns to match conditional branch insns
3822 (define_insn "*condbranch"
3824 (if_then_else (match_operator 1 "comparison_operator"
3825 [(match_operand 2 "cc_register" "") (const_int 0)])
3826 (label_ref (match_operand 0 "" ""))
3831 extern int arm_ccfsm_state;
3833 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3835 arm_ccfsm_state += 2;
3838 return \"b%d1\\t%l0\";
3840 [(set_attr "conds" "use")])
3842 (define_insn "*condbranch_reversed"
3844 (if_then_else (match_operator 1 "comparison_operator"
3845 [(match_operand 2 "cc_register" "") (const_int 0)])
3847 (label_ref (match_operand 0 "" ""))))]
3851 extern int arm_ccfsm_state;
3853 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3855 arm_ccfsm_state += 2;
3858 return \"b%D1\\t%l0\";
3860 [(set_attr "conds" "use")])
3865 (define_expand "seq"
3866 [(set (match_operand:SI 0 "s_register_operand" "=r")
3867 (eq:SI (match_dup 1) (const_int 0)))]
3871 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3876 (define_expand "sne"
3877 [(set (match_operand:SI 0 "s_register_operand" "=r")
3878 (ne:SI (match_dup 1) (const_int 0)))]
3882 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3887 (define_expand "sgt"
3888 [(set (match_operand:SI 0 "s_register_operand" "=r")
3889 (gt:SI (match_dup 1) (const_int 0)))]
3893 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3898 (define_expand "sle"
3899 [(set (match_operand:SI 0 "s_register_operand" "=r")
3900 (le:SI (match_dup 1) (const_int 0)))]
3904 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3909 (define_expand "sge"
3910 [(set (match_operand:SI 0 "s_register_operand" "=r")
3911 (ge:SI (match_dup 1) (const_int 0)))]
3915 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3920 (define_expand "slt"
3921 [(set (match_operand:SI 0 "s_register_operand" "=r")
3922 (lt:SI (match_dup 1) (const_int 0)))]
3926 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3931 (define_expand "sgtu"
3932 [(set (match_operand:SI 0 "s_register_operand" "=r")
3933 (gtu:SI (match_dup 1) (const_int 0)))]
3937 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3942 (define_expand "sleu"
3943 [(set (match_operand:SI 0 "s_register_operand" "=r")
3944 (leu:SI (match_dup 1) (const_int 0)))]
3948 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3953 (define_expand "sgeu"
3954 [(set (match_operand:SI 0 "s_register_operand" "=r")
3955 (geu:SI (match_dup 1) (const_int 0)))]
3959 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3964 (define_expand "sltu"
3965 [(set (match_operand:SI 0 "s_register_operand" "=r")
3966 (ltu:SI (match_dup 1) (const_int 0)))]
3970 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3975 (define_insn "*mov_scc"
3976 [(set (match_operand:SI 0 "s_register_operand" "=r")
3977 (match_operator:SI 1 "comparison_operator"
3978 [(match_operand 2 "cc_register" "") (const_int 0)]))]
3980 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
3981 [(set_attr "conds" "use")
3982 (set_attr "length" "8")])
3984 (define_insn "*mov_negscc"
3985 [(set (match_operand:SI 0 "s_register_operand" "=r")
3986 (neg:SI (match_operator:SI 1 "comparison_operator"
3987 [(match_operand 2 "cc_register" "") (const_int 0)])))]
3989 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
3990 [(set_attr "conds" "use")
3991 (set_attr "length" "8")])
3993 (define_insn "*mov_notscc"
3994 [(set (match_operand:SI 0 "s_register_operand" "=r")
3995 (not:SI (match_operator:SI 1 "comparison_operator"
3996 [(match_operand 2 "cc_register" "") (const_int 0)])))]
3998 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
3999 [(set_attr "conds" "use")
4000 (set_attr "length" "8")])
4003 ;; Conditional move insns
4005 (define_expand "movsicc"
4006 [(set (match_operand:SI 0 "s_register_operand" "")
4007 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4008 (match_operand:SI 2 "arm_not_operand" "")
4009 (match_operand:SI 3 "arm_not_operand" "")))]
4013 enum rtx_code code = GET_CODE (operands[1]);
4014 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
4017 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
4020 (define_expand "movsfcc"
4021 [(set (match_operand:SF 0 "s_register_operand" "")
4022 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4023 (match_operand:SF 2 "s_register_operand" "")
4024 (match_operand:SF 3 "nonmemory_operand" "")))]
4028 enum rtx_code code = GET_CODE (operands[1]);
4031 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
4032 Otherwise, ensure it is a valid FP add operand */
4033 if ((! TARGET_HARD_FLOAT)
4034 || (! fpu_add_operand (operands[3], SFmode)))
4035 operands[3] = force_reg (SFmode, operands[3]);
4037 ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
4040 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
4043 (define_expand "movdfcc"
4044 [(set (match_operand:DF 0 "s_register_operand" "")
4045 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4046 (match_operand:DF 2 "s_register_operand" "")
4047 (match_operand:DF 3 "fpu_add_operand" "")))]
4051 enum rtx_code code = GET_CODE (operands[1]);
4052 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
4055 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
4058 (define_insn "*movsicc_insn"
4059 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
4061 (match_operator 3 "comparison_operator"
4062 [(match_operand 4 "cc_register" "") (const_int 0)])
4063 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
4064 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
4071 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
4072 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
4073 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
4074 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
4075 [(set_attr "length" "4,4,4,4,8,8,8,8")
4076 (set_attr "conds" "use")])
4078 (define_insn "*movsfcc_hard_insn"
4079 [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
4081 (match_operator 3 "comparison_operator"
4082 [(match_operand 4 "cc_register" "") (const_int 0)])
4083 (match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
4084 (match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
4091 mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
4092 mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
4093 mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
4094 mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
4095 [(set_attr "length" "4,4,4,4,8,8,8,8")
4096 (set_attr "type" "ffarith")
4097 (set_attr "conds" "use")])
4099 (define_insn "*movsfcc_soft_insn"
4100 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
4101 (if_then_else:SF (match_operator 3 "comparison_operator"
4102 [(match_operand 4 "cc_register" "") (const_int 0)])
4103 (match_operand:SF 1 "s_register_operand" "0,r")
4104 (match_operand:SF 2 "s_register_operand" "r,0")))]
4109 [(set_attr "conds" "use")])
4111 (define_insn "*movdfcc_insn"
4112 [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
4114 (match_operator 3 "comparison_operator"
4115 [(match_operand 4 "cc_register" "") (const_int 0)])
4116 (match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
4117 (match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
4124 mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
4125 mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
4126 mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
4127 mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
4128 [(set_attr "length" "4,4,4,4,8,8,8,8")
4129 (set_attr "type" "ffarith")
4130 (set_attr "conds" "use")])
4132 ;; Jump and linkage insns
4136 (label_ref (match_operand 0 "" "")))]
4140 extern int arm_ccfsm_state;
4142 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4144 arm_ccfsm_state += 2;
4147 return \"b%?\\t%l0\";
4150 (define_expand "call"
4151 [(parallel [(call (match_operand 0 "memory_operand" "")
4152 (match_operand 1 "general_operand" ""))
4153 (clobber (reg:SI 14))])]
4157 (define_insn "*call_reg"
4158 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
4159 (match_operand 1 "" "g"))
4160 (clobber (reg:SI 14))]
4163 return output_call (operands);
4165 ;; length is worst case, normally it is only two
4166 [(set_attr "length" "12")
4167 (set_attr "type" "call")])
4169 (define_insn "*call_mem"
4170 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
4171 (match_operand 1 "general_operand" "g"))
4172 (clobber (reg:SI 14))]
4175 return output_call_mem (operands);
4177 [(set_attr "length" "12")
4178 (set_attr "type" "call")])
4180 (define_expand "call_value"
4181 [(parallel [(set (match_operand 0 "" "=rf")
4182 (call (match_operand 1 "memory_operand" "m")
4183 (match_operand 2 "general_operand" "g")))
4184 (clobber (reg:SI 14))])]
4188 (define_insn "*call_value_reg"
4189 [(set (match_operand 0 "" "=rf")
4190 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
4191 (match_operand 2 "general_operand" "g")))
4192 (clobber (reg:SI 14))]
4195 return output_call (&operands[1]);
4197 [(set_attr "length" "12")
4198 (set_attr "type" "call")])
4200 (define_insn "*call_value_mem"
4201 [(set (match_operand 0 "" "=rf")
4202 (call (mem:SI (match_operand 1 "memory_operand" "m"))
4203 (match_operand 2 "general_operand" "g")))
4204 (clobber (reg:SI 14))]
4205 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
4207 return output_call_mem (&operands[1]);
4209 [(set_attr "length" "12")
4210 (set_attr "type" "call")])
4212 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
4213 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
4215 (define_insn "*call_symbol"
4216 [(call (mem:SI (match_operand:SI 0 "" "X"))
4217 (match_operand:SI 1 "general_operand" "g"))
4218 (clobber (reg:SI 14))]
4219 "GET_CODE (operands[0]) == SYMBOL_REF"
4221 [(set_attr "type" "call")])
4223 (define_insn "*call_value_symbol"
4224 [(set (match_operand 0 "s_register_operand" "=rf")
4225 (call (mem:SI (match_operand:SI 1 "" "X"))
4226 (match_operand:SI 2 "general_operand" "g")))
4227 (clobber (reg:SI 14))]
4228 "GET_CODE(operands[1]) == SYMBOL_REF"
4230 [(set_attr "type" "call")])
4232 ;; Often the return insn will be the same as loading from memory, so set attr
4233 (define_insn "return"
4238 extern int arm_ccfsm_state;
4240 if (arm_ccfsm_state == 2)
4242 arm_ccfsm_state += 2;
4245 return output_return_instruction (NULL, TRUE, FALSE);
4247 [(set_attr "type" "load")])
4249 (define_insn "*cond_return"
4251 (if_then_else (match_operator 0 "comparison_operator"
4252 [(match_operand 1 "cc_register" "") (const_int 0)])
4258 extern int arm_ccfsm_state;
4260 if (arm_ccfsm_state == 2)
4262 arm_ccfsm_state += 2;
4265 return output_return_instruction (operands[0], TRUE, FALSE);
4267 [(set_attr "conds" "use")
4268 (set_attr "type" "load")])
4270 (define_insn "*cond_return_inverted"
4272 (if_then_else (match_operator 0 "comparison_operator"
4273 [(match_operand 1 "cc_register" "") (const_int 0)])
4279 extern int arm_ccfsm_state;
4281 if (arm_ccfsm_state == 2)
4283 arm_ccfsm_state += 2;
4286 return output_return_instruction (operands[0], TRUE, TRUE);
4288 [(set_attr "conds" "use")
4289 (set_attr "type" "load")])
4291 ;; Call subroutine returning any type.
4293 (define_expand "untyped_call"
4294 [(parallel [(call (match_operand 0 "" "")
4296 (match_operand 1 "" "")
4297 (match_operand 2 "" "")])]
4303 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4305 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4307 rtx set = XVECEXP (operands[2], 0, i);
4308 emit_move_insn (SET_DEST (set), SET_SRC (set));
4311 /* The optimizer does not know that the call sets the function value
4312 registers we stored in the result block. We avoid problems by
4313 claiming that all hard registers are used and clobbered at this
4315 emit_insn (gen_blockage ());
4320 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4321 ;; all of memory. This blocks insns from being moved across this point.
4323 (define_insn "blockage"
4324 [(unspec_volatile [(const_int 0)] 0)]
4327 [(set_attr "length" "0")
4328 (set_attr "type" "block")])
4330 (define_expand "casesi"
4331 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
4332 (match_operand:SI 1 "const_int_operand" "") ; lower bound
4333 (match_operand:SI 2 "const_int_operand" "") ; total range
4334 (match_operand:SI 3 "" "") ; table label
4335 (match_operand:SI 4 "" "")] ; Out of range label
4340 if (operands[1] != const0_rtx)
4342 reg = gen_reg_rtx (SImode);
4343 emit_insn (gen_addsi3 (reg, operands[0],
4344 GEN_INT (-INTVAL (operands[1]))));
4348 if (! const_ok_for_arm (INTVAL (operands[2])))
4349 operands[2] = force_reg (SImode, operands[2]);
4351 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
4356 ;; The USE in this pattern is needed to tell flow analysis that this is
4357 ;; a CASESI insn. It has no other purpose.
4358 (define_insn "casesi_internal"
4359 [(parallel [(set (pc)
4361 (leu (match_operand:SI 0 "s_register_operand" "r")
4362 (match_operand:SI 1 "arm_rhs_operand" "rI"))
4363 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
4364 (label_ref (match_operand 2 "" ""))))
4365 (label_ref (match_operand 3 "" ""))))
4366 (use (label_ref (match_dup 2)))])]
4370 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
4371 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
4373 [(set_attr "conds" "clob")
4374 (set_attr "length" "12")])
4376 (define_insn "indirect_jump"
4378 (match_operand:SI 0 "s_register_operand" "r"))]
4380 "mov%?\\t%|pc, %0\\t%@ indirect jump")
4382 (define_insn "*load_indirect_jump"
4384 (match_operand:SI 0 "memory_operand" "m"))]
4386 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
4387 [(set_attr "type" "load")])
4394 "mov%?\\tr0, r0\\t%@ nop")
4396 ;; Patterns to allow combination of arithmetic, cond code and shifts
4398 (define_insn "*arith_shiftsi"
4399 [(set (match_operand:SI 0 "s_register_operand" "=r")
4400 (match_operator:SI 1 "shiftable_operator"
4401 [(match_operator:SI 3 "shift_operator"
4402 [(match_operand:SI 4 "s_register_operand" "r")
4403 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4404 (match_operand:SI 2 "s_register_operand" "r")]))]
4406 "%i1%?\\t%0, %2, %4%S3")
4408 (define_insn "*arith_shiftsi_compare0"
4409 [(set (reg:CC_NOOV 24)
4410 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4411 [(match_operator:SI 3 "shift_operator"
4412 [(match_operand:SI 4 "s_register_operand" "r")
4413 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4414 (match_operand:SI 2 "s_register_operand" "r")])
4416 (set (match_operand:SI 0 "s_register_operand" "=r")
4417 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
4420 "%i1%?s\\t%0, %2, %4%S3"
4421 [(set_attr "conds" "set")])
4423 (define_insn "*arith_shiftsi_compare0_scratch"
4424 [(set (reg:CC_NOOV 24)
4425 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4426 [(match_operator:SI 3 "shift_operator"
4427 [(match_operand:SI 4 "s_register_operand" "r")
4428 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4429 (match_operand:SI 2 "s_register_operand" "r")])
4431 (clobber (match_scratch:SI 0 "=r"))]
4433 "%i1%?s\\t%0, %2, %4%S3"
4434 [(set_attr "conds" "set")])
4436 (define_insn "*sub_shiftsi"
4437 [(set (match_operand:SI 0 "s_register_operand" "=r")
4438 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4439 (match_operator:SI 2 "shift_operator"
4440 [(match_operand:SI 3 "s_register_operand" "r")
4441 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
4443 "sub%?\\t%0, %1, %3%S2")
4445 (define_insn "*sub_shiftsi_compare0"
4446 [(set (reg:CC_NOOV 24)
4448 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4449 (match_operator:SI 2 "shift_operator"
4450 [(match_operand:SI 3 "s_register_operand" "r")
4451 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4453 (set (match_operand:SI 0 "s_register_operand" "=r")
4454 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4457 "sub%?s\\t%0, %1, %3%S2"
4458 [(set_attr "conds" "set")])
4460 (define_insn "*sub_shiftsi_compare0_scratch"
4461 [(set (reg:CC_NOOV 24)
4463 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4464 (match_operator:SI 2 "shift_operator"
4465 [(match_operand:SI 3 "s_register_operand" "r")
4466 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4468 (clobber (match_scratch:SI 0 "=r"))]
4470 "sub%?s\\t%0, %1, %3%S2"
4471 [(set_attr "conds" "set")])
4473 ;; These variants of the above insns can occur if the first operand is the
4474 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
4475 ;; seem to be a way around it. Most of the predicates have to be null
4476 ;; because the format can be generated part way through reload, so
4477 ;; if we don't match it as soon as it becomes available, reload doesn't know
4478 ;; how to reload pseudos that haven't got hard registers; the constraints will
4479 ;; sort everything out.
4481 (define_insn "*reload_mulsi3"
4482 [(set (match_operand:SI 0 "" "=&r")
4483 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
4484 [(match_operand:SI 3 "" "r")
4485 (match_operand:SI 4 "" "rM")])
4486 (match_operand:SI 2 "" "r"))
4487 (match_operand:SI 1 "const_int_operand" "n")))]
4488 "reload_in_progress"
4490 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
4491 operands[2] = operands[1];
4492 operands[1] = operands[0];
4493 return output_add_immediate (operands);
4495 ; we have no idea how long the add_immediate is, it could be up to 4.
4496 [(set_attr "length" "20")])
4498 (define_insn "*reload_mulsi_compare0"
4499 [(set (reg:CC_NOOV 24)
4500 (compare:CC_NOOV (plus:SI
4502 (match_operator:SI 5 "shift_operator"
4503 [(match_operand:SI 3 "" "r")
4504 (match_operand:SI 4 "" "rM")])
4505 (match_operand:SI 1 "" "r"))
4506 (match_operand:SI 2 "const_int_operand" "n"))
4508 (set (match_operand:SI 0 "" "=&r")
4509 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
4512 "reload_in_progress"
4514 output_add_immediate (operands);
4515 return \"add%?s\\t%0, %0, %3%S5\";
4517 [(set_attr "conds" "set")
4518 (set_attr "length" "20")])
4520 (define_insn "*reload_mulsi_compare0_scratch"
4521 [(set (reg:CC_NOOV 24)
4522 (compare:CC_NOOV (plus:SI
4524 (match_operator:SI 5 "shift_operator"
4525 [(match_operand:SI 3 "" "r")
4526 (match_operand:SI 4 "" "rM")])
4527 (match_operand:SI 1 "" "r"))
4528 (match_operand:SI 2 "const_int_operand" "n"))
4530 (clobber (match_scratch:SI 0 "=&r"))]
4531 "reload_in_progress"
4533 output_add_immediate (operands);
4534 return \"add%?s\\t%0, %0, %3%S5\";
4536 [(set_attr "conds" "set")
4537 (set_attr "length" "20")])
4539 ;; These are similar, but are needed when the mla pattern contains the
4540 ;; eliminated register as operand 3.
4542 (define_insn "*reload_muladdsi"
4543 [(set (match_operand:SI 0 "" "=&r,&r")
4544 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
4545 (match_operand:SI 2 "" "r,r"))
4546 (match_operand:SI 3 "" "r,r"))
4547 (match_operand:SI 4 "const_int_operand" "n,n")))]
4548 "reload_in_progress"
4550 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
4551 operands[2] = operands[4];
4552 operands[1] = operands[0];
4553 return output_add_immediate (operands);
4555 [(set_attr "length" "20")
4556 (set_attr "type" "mult")])
4558 (define_insn "*reload_muladdsi_compare0"
4559 [(set (reg:CC_NOOV 24)
4560 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4561 (match_operand:SI 3 "" "r")
4562 (match_operand:SI 4 "" "r"))
4563 (match_operand:SI 1 "" "r"))
4564 (match_operand:SI 2 "const_int_operand" "n"))
4566 (set (match_operand:SI 0 "" "=&r")
4567 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
4569 "reload_in_progress"
4571 output_add_immediate (operands);
4572 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
4575 [(set_attr "length" "20")
4576 (set_attr "conds" "set")
4577 (set_attr "type" "mult")])
4579 (define_insn "*reload_muladdsi_compare0_scratch"
4580 [(set (reg:CC_NOOV 24)
4581 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4582 (match_operand:SI 3 "" "r")
4583 (match_operand:SI 4 "" "r"))
4584 (match_operand:SI 1 "" "r"))
4585 (match_operand:SI 2 "const_int_operand" "n"))
4587 (clobber (match_scratch:SI 0 "=&r"))]
4588 "reload_in_progress"
4590 output_add_immediate (operands);
4591 return \"mla%?s\\t%0, %3, %4, %0\";
4593 [(set_attr "length" "20")
4594 (set_attr "conds" "set")
4595 (set_attr "type" "mult")])
4599 (define_insn "*and_scc"
4600 [(set (match_operand:SI 0 "s_register_operand" "=r")
4601 (and:SI (match_operator 1 "comparison_operator"
4602 [(match_operand 3 "cc_register" "") (const_int 0)])
4603 (match_operand:SI 2 "s_register_operand" "r")))]
4605 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
4606 [(set_attr "conds" "use")
4607 (set_attr "length" "8")])
4609 (define_insn "*ior_scc"
4610 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4611 (ior:SI (match_operator 2 "comparison_operator"
4612 [(match_operand 3 "cc_register" "") (const_int 0)])
4613 (match_operand:SI 1 "s_register_operand" "0,?r")))]
4617 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
4618 [(set_attr "conds" "use")
4619 (set_attr "length" "4,8")])
4621 (define_insn "*compare_scc"
4622 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4623 (match_operator 1 "comparison_operator"
4624 [(match_operand:SI 2 "s_register_operand" "r,r")
4625 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
4629 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
4630 return \"mov\\t%0, %2, lsr #31\";
4632 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
4633 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
4635 if (GET_CODE (operands[1]) == NE)
4637 if (which_alternative == 1)
4638 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
4639 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
4641 if (which_alternative == 1)
4642 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4644 output_asm_insn (\"cmp\\t%2, %3\", operands);
4645 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
4647 [(set_attr "conds" "clob")
4648 (set_attr "length" "12")])
4650 (define_insn "*cond_move"
4651 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4652 (if_then_else:SI (match_operator 3 "equality_operator"
4653 [(match_operator 4 "comparison_operator"
4654 [(match_operand 5 "cc_register" "") (const_int 0)])
4656 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4657 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
4660 if (GET_CODE (operands[3]) == NE)
4662 if (which_alternative != 1)
4663 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4664 if (which_alternative != 0)
4665 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
4668 if (which_alternative != 0)
4669 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4670 if (which_alternative != 1)
4671 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
4674 [(set_attr "conds" "use")
4675 (set_attr "length" "4,4,8")])
4677 (define_insn "*cond_arith"
4678 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4679 (match_operator:SI 5 "shiftable_operator"
4680 [(match_operator:SI 4 "comparison_operator"
4681 [(match_operand:SI 2 "s_register_operand" "r,r")
4682 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4683 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4687 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4688 return \"%i5\\t%0, %1, %2, lsr #31\";
4690 output_asm_insn (\"cmp\\t%2, %3\", operands);
4691 if (GET_CODE (operands[5]) == AND)
4692 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4693 else if (GET_CODE (operands[5]) == MINUS)
4694 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
4695 else if (which_alternative != 0)
4696 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4697 return \"%i5%d4\\t%0, %1, #1\";
4699 [(set_attr "conds" "clob")
4700 (set_attr "length" "12")])
4702 (define_insn "*cond_sub"
4703 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4704 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4705 (match_operator:SI 4 "comparison_operator"
4706 [(match_operand:SI 2 "s_register_operand" "r,r")
4707 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4711 output_asm_insn (\"cmp\\t%2, %3\", operands);
4712 if (which_alternative != 0)
4713 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4714 return \"sub%d4\\t%0, %1, #1\";
4716 [(set_attr "conds" "clob")
4717 (set_attr "length" "8,12")])
4719 (define_insn "*cmp_ite0"
4720 [(set (match_operand 6 "dominant_cc_register" "")
4723 (match_operator 4 "comparison_operator"
4724 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4725 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4726 (match_operator:SI 5 "comparison_operator"
4727 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4728 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4734 char* opcodes[4][2] =
4736 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
4737 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
4738 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
4739 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
4740 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
4743 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
4745 return opcodes[which_alternative][swap];
4748 [(set_attr "conds" "set")
4749 (set_attr "length" "8")])
4751 (define_insn "*cmp_ite1"
4752 [(set (match_operand 6 "dominant_cc_register" "")
4755 (match_operator 4 "comparison_operator"
4756 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4757 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4758 (match_operator:SI 5 "comparison_operator"
4759 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4760 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4766 char* opcodes[4][2] =
4768 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
4769 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
4770 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
4771 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
4772 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
4775 comparison_dominates_p (GET_CODE (operands[5]),
4776 reverse_condition (GET_CODE (operands[4])));
4778 return opcodes[which_alternative][swap];
4781 [(set_attr "conds" "set")
4782 (set_attr "length" "8")])
4784 (define_insn "*negscc"
4785 [(set (match_operand:SI 0 "s_register_operand" "=r")
4786 (neg:SI (match_operator 3 "comparison_operator"
4787 [(match_operand:SI 1 "s_register_operand" "r")
4788 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4792 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4793 return \"mov\\t%0, %1, asr #31\";
4795 if (GET_CODE (operands[3]) == NE)
4796 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4798 if (GET_CODE (operands[3]) == GT)
4799 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4801 output_asm_insn (\"cmp\\t%1, %2\", operands);
4802 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4803 return \"mvn%d3\\t%0, #0\";
4805 [(set_attr "conds" "clob")
4806 (set_attr "length" "12")])
4808 (define_insn "movcond"
4809 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4811 (match_operator 5 "comparison_operator"
4812 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4813 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4814 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4815 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4819 if (GET_CODE (operands[5]) == LT
4820 && (operands[4] == const0_rtx))
4822 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4824 if (operands[2] == const0_rtx)
4825 return \"and\\t%0, %1, %3, asr #31\";
4826 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4828 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4830 if (operands[1] == const0_rtx)
4831 return \"bic\\t%0, %2, %3, asr #31\";
4832 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4834 /* The only case that falls through to here is when both ops 1 & 2
4838 if (GET_CODE (operands[5]) == GE
4839 && (operands[4] == const0_rtx))
4841 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4843 if (operands[2] == const0_rtx)
4844 return \"bic\\t%0, %1, %3, asr #31\";
4845 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4847 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4849 if (operands[1] == const0_rtx)
4850 return \"and\\t%0, %2, %3, asr #31\";
4851 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4853 /* The only case that falls through to here is when both ops 1 & 2
4856 if (GET_CODE (operands[4]) == CONST_INT
4857 && !const_ok_for_arm (INTVAL (operands[4])))
4858 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4860 output_asm_insn (\"cmp\\t%3, %4\", operands);
4861 if (which_alternative != 0)
4862 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4863 if (which_alternative != 1)
4864 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4867 [(set_attr "conds" "clob")
4868 (set_attr "length" "8,8,12")])
4870 (define_insn "*ifcompare_plus_move"
4871 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4872 (if_then_else:SI (match_operator 6 "comparison_operator"
4873 [(match_operand:SI 4 "s_register_operand" "r,r")
4874 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4876 (match_operand:SI 2 "s_register_operand" "r,r")
4877 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
4878 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4882 [(set_attr "conds" "clob")
4883 (set_attr "length" "8,12")])
4885 (define_insn "*if_plus_move"
4886 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
4888 (match_operator 4 "comparison_operator"
4889 [(match_operand 5 "cc_register" "") (const_int 0)])
4891 (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
4892 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))
4893 (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")))]
4897 sub%d4\\t%0, %2, #%n3
4898 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
4899 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1
4900 add%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1
4901 sub%d4\\t%0, %2, #%n3\;ldr%D4\\t%0, %1"
4902 [(set_attr "conds" "use")
4903 (set_attr "length" "4,4,8,8,8,8")
4904 (set_attr "type" "*,*,*,*,load,load")])
4906 (define_insn "*ifcompare_move_plus"
4907 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4908 (if_then_else:SI (match_operator 6 "comparison_operator"
4909 [(match_operand:SI 4 "s_register_operand" "r,r")
4910 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4911 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
4913 (match_operand:SI 2 "s_register_operand" "r,r")
4914 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4918 [(set_attr "conds" "clob")
4919 (set_attr "length" "8,12")])
4921 (define_insn "*if_move_plus"
4922 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
4924 (match_operator 4 "comparison_operator"
4925 [(match_operand 5 "cc_register" "") (const_int 0)])
4926 (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")
4928 (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
4929 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))))]
4933 sub%D4\\t%0, %2, #%n3
4934 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
4935 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1
4936 add%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1
4937 sub%D4\\t%0, %2, #%n3\;ldr%d4\\t%0, %1"
4938 [(set_attr "conds" "use")
4939 (set_attr "length" "4,4,8,8,8,8")
4940 (set_attr "type" "*,*,*,*,load,load")])
4942 (define_insn "*ifcompare_arith_arith"
4943 [(set (match_operand:SI 0 "s_register_operand" "=r")
4944 (if_then_else:SI (match_operator 9 "comparison_operator"
4945 [(match_operand:SI 5 "s_register_operand" "r")
4946 (match_operand:SI 6 "arm_add_operand" "rIL")])
4947 (match_operator:SI 8 "shiftable_operator"
4948 [(match_operand:SI 1 "s_register_operand" "r")
4949 (match_operand:SI 2 "arm_rhs_operand" "rI")])
4950 (match_operator:SI 7 "shiftable_operator"
4951 [(match_operand:SI 3 "s_register_operand" "r")
4952 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4956 [(set_attr "conds" "clob")
4957 (set_attr "length" "12")])
4959 (define_insn "*if_arith_arith"
4960 [(set (match_operand:SI 0 "s_register_operand" "=r")
4961 (if_then_else:SI (match_operator 5 "comparison_operator"
4962 [(match_operand 8 "cc_register" "") (const_int 0)])
4963 (match_operator:SI 6 "shiftable_operator"
4964 [(match_operand:SI 1 "s_register_operand" "r")
4965 (match_operand:SI 2 "arm_rhs_operand" "rI")])
4966 (match_operator:SI 7 "shiftable_operator"
4967 [(match_operand:SI 3 "s_register_operand" "r")
4968 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
4970 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
4971 [(set_attr "conds" "use")
4972 (set_attr "length" "8")])
4974 (define_insn "*ifcompare_arith_move"
4975 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4976 (if_then_else:SI (match_operator 6 "comparison_operator"
4977 [(match_operand:SI 2 "s_register_operand" "r,r")
4978 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
4979 (match_operator:SI 7 "shiftable_operator"
4980 [(match_operand:SI 4 "s_register_operand" "r,r")
4981 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
4982 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
4986 /* If we have an operation where (op x 0) is the identity operation and
4987 the conditional operator is LT or GE and we are comparing against zero and
4988 everything is in registers then we can do this in two instructions */
4989 if (operands[3] == const0_rtx
4990 && GET_CODE (operands[7]) != AND
4991 && GET_CODE (operands[5]) == REG
4992 && GET_CODE (operands[1]) == REG
4993 && REGNO (operands[1]) == REGNO (operands[4])
4994 && REGNO (operands[4]) != REGNO (operands[0]))
4996 if (GET_CODE (operands[6]) == LT)
4997 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
4998 else if (GET_CODE (operands[6]) == GE)
4999 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
5001 if (GET_CODE (operands[3]) == CONST_INT
5002 && !const_ok_for_arm (INTVAL (operands[3])))
5003 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
5005 output_asm_insn (\"cmp\\t%2, %3\", operands);
5006 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
5007 if (which_alternative != 0)
5009 if (GET_CODE (operands[1]) == MEM)
5010 return \"ldr%D6\\t%0, %1\";
5012 return \"mov%D6\\t%0, %1\";
5016 [(set_attr "conds" "clob")
5017 (set_attr "length" "8,12")])
5019 (define_insn "*if_arith_move"
5020 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5021 (if_then_else:SI (match_operator 4 "comparison_operator"
5022 [(match_operand 6 "cc_register" "") (const_int 0)])
5023 (match_operator:SI 5 "shiftable_operator"
5024 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5025 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])
5026 (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")))]
5030 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
5031 %I5%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1"
5032 [(set_attr "conds" "use")
5033 (set_attr "length" "4,8,8")
5034 (set_attr "type" "*,*,load")])
5036 (define_insn "*ifcompare_move_arith"
5037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5038 (if_then_else:SI (match_operator 6 "comparison_operator"
5039 [(match_operand:SI 4 "s_register_operand" "r,r")
5040 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5041 (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
5042 (match_operator:SI 7 "shiftable_operator"
5043 [(match_operand:SI 2 "s_register_operand" "r,r")
5044 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
5048 /* If we have an operation where (op x 0) is the identity operation and
5049 the conditional operator is LT or GE and we are comparing against zero and
5050 everything is in registers then we can do this in two instructions */
5051 if (operands[5] == const0_rtx
5052 && GET_CODE (operands[7]) != AND
5053 && GET_CODE (operands[3]) == REG
5054 && GET_CODE (operands[1]) == REG
5055 && REGNO (operands[1]) == REGNO (operands[2])
5056 && REGNO (operands[2]) != REGNO (operands[0]))
5058 if (GET_CODE (operands[6]) == GE)
5059 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
5060 else if (GET_CODE (operands[6]) == LT)
5061 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
5064 if (GET_CODE (operands[5]) == CONST_INT
5065 && !const_ok_for_arm (INTVAL (operands[5])))
5066 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
5068 output_asm_insn (\"cmp\\t%4, %5\", operands);
5070 if (which_alternative != 0)
5072 if (GET_CODE (operands[1]) == MEM)
5073 output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
5075 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
5077 return \"%I7%D6\\t%0, %2, %3\";
5079 [(set_attr "conds" "clob")
5080 (set_attr "length" "8,12")])
5082 (define_insn "*if_move_arith"
5083 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5085 (match_operator 4 "comparison_operator"
5086 [(match_operand 6 "cc_register" "") (const_int 0)])
5087 (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")
5088 (match_operator:SI 5 "shiftable_operator"
5089 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5090 (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])))]
5094 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
5095 %I5%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1"
5096 [(set_attr "conds" "use")
5097 (set_attr "length" "4,8,8")
5098 (set_attr "type" "*,*,load")])
5100 (define_insn "*ifcompare_move_not"
5101 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5103 (match_operator 5 "comparison_operator"
5104 [(match_operand:SI 3 "s_register_operand" "r,r")
5105 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5106 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5108 (match_operand:SI 2 "s_register_operand" "r,r"))))
5112 [(set_attr "conds" "clob")
5113 (set_attr "length" "8,12")])
5115 (define_insn "*if_move_not"
5116 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5118 (match_operator 4 "comparison_operator"
5119 [(match_operand 3 "cc_register" "") (const_int 0)])
5120 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5121 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
5125 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
5126 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
5127 [(set_attr "conds" "use")
5128 (set_attr "length" "4,8,8")])
5130 (define_insn "*ifcompare_not_move"
5131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5133 (match_operator 5 "comparison_operator"
5134 [(match_operand:SI 3 "s_register_operand" "r,r")
5135 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5137 (match_operand:SI 2 "s_register_operand" "r,r"))
5138 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5142 [(set_attr "conds" "clob")
5143 (set_attr "length" "8,12")])
5145 (define_insn "*if_not_move"
5146 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5148 (match_operator 4 "comparison_operator"
5149 [(match_operand 3 "cc_register" "") (const_int 0)])
5150 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
5151 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5155 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
5156 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
5157 [(set_attr "conds" "use")
5158 (set_attr "length" "4,8,8")])
5160 (define_insn "*ifcompare_shift_move"
5161 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5163 (match_operator 6 "comparison_operator"
5164 [(match_operand:SI 4 "s_register_operand" "r,r")
5165 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5166 (match_operator:SI 7 "shift_operator"
5167 [(match_operand:SI 2 "s_register_operand" "r,r")
5168 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
5169 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5173 [(set_attr "conds" "clob")
5174 (set_attr "length" "8,12")])
5176 (define_insn "*if_shift_move"
5177 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5179 (match_operator 5 "comparison_operator"
5180 [(match_operand 6 "cc_register" "") (const_int 0)])
5181 (match_operator:SI 4 "shift_operator"
5182 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5183 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
5184 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5188 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
5189 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
5190 [(set_attr "conds" "use")
5191 (set_attr "length" "4,8,8")])
5193 (define_insn "*ifcompare_move_shift"
5194 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5196 (match_operator 6 "comparison_operator"
5197 [(match_operand:SI 4 "s_register_operand" "r,r")
5198 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5199 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5200 (match_operator:SI 7 "shift_operator"
5201 [(match_operand:SI 2 "s_register_operand" "r,r")
5202 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
5206 [(set_attr "conds" "clob")
5207 (set_attr "length" "8,12")])
5209 (define_insn "*if_move_shift"
5210 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5212 (match_operator 5 "comparison_operator"
5213 [(match_operand 6 "cc_register" "") (const_int 0)])
5214 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5215 (match_operator:SI 4 "shift_operator"
5216 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5217 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
5221 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
5222 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
5223 [(set_attr "conds" "use")
5224 (set_attr "length" "4,8,8")])
5226 (define_insn "*ifcompare_shift_shift"
5227 [(set (match_operand:SI 0 "s_register_operand" "=r")
5229 (match_operator 7 "comparison_operator"
5230 [(match_operand:SI 5 "s_register_operand" "r")
5231 (match_operand:SI 6 "arm_add_operand" "rIL")])
5232 (match_operator:SI 8 "shift_operator"
5233 [(match_operand:SI 1 "s_register_operand" "r")
5234 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5235 (match_operator:SI 9 "shift_operator"
5236 [(match_operand:SI 3 "s_register_operand" "r")
5237 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
5241 [(set_attr "conds" "clob")
5242 (set_attr "length" "12")])
5244 (define_insn "*if_shift_shift"
5245 [(set (match_operand:SI 0 "s_register_operand" "=r")
5247 (match_operator 5 "comparison_operator"
5248 [(match_operand 8 "cc_register" "") (const_int 0)])
5249 (match_operator:SI 6 "shift_operator"
5250 [(match_operand:SI 1 "s_register_operand" "r")
5251 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5252 (match_operator:SI 7 "shift_operator"
5253 [(match_operand:SI 3 "s_register_operand" "r")
5254 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
5256 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
5257 [(set_attr "conds" "use")
5258 (set_attr "length" "8")])
5260 (define_insn "*ifcompare_not_arith"
5261 [(set (match_operand:SI 0 "s_register_operand" "=r")
5263 (match_operator 6 "comparison_operator"
5264 [(match_operand:SI 4 "s_register_operand" "r")
5265 (match_operand:SI 5 "arm_add_operand" "rIL")])
5266 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5267 (match_operator:SI 7 "shiftable_operator"
5268 [(match_operand:SI 2 "s_register_operand" "r")
5269 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
5273 [(set_attr "conds" "clob")
5274 (set_attr "length" "12")])
5276 (define_insn "*if_not_arith"
5277 [(set (match_operand:SI 0 "s_register_operand" "=r")
5279 (match_operator 5 "comparison_operator"
5280 [(match_operand 4 "cc_register" "") (const_int 0)])
5281 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5282 (match_operator:SI 6 "shiftable_operator"
5283 [(match_operand:SI 2 "s_register_operand" "r")
5284 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
5286 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
5287 [(set_attr "conds" "use")
5288 (set_attr "length" "8")])
5290 (define_insn "*ifcompare_arith_not"
5291 [(set (match_operand:SI 0 "s_register_operand" "=r")
5293 (match_operator 6 "comparison_operator"
5294 [(match_operand:SI 4 "s_register_operand" "r")
5295 (match_operand:SI 5 "arm_add_operand" "rIL")])
5296 (match_operator:SI 7 "shiftable_operator"
5297 [(match_operand:SI 2 "s_register_operand" "r")
5298 (match_operand:SI 3 "arm_rhs_operand" "rI")])
5299 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
5303 [(set_attr "conds" "clob")
5304 (set_attr "length" "12")])
5306 (define_insn "*if_arith_not"
5307 [(set (match_operand:SI 0 "s_register_operand" "=r")
5309 (match_operator 5 "comparison_operator"
5310 [(match_operand 4 "cc_register" "") (const_int 0)])
5311 (match_operator:SI 6 "shiftable_operator"
5312 [(match_operand:SI 2 "s_register_operand" "r")
5313 (match_operand:SI 3 "arm_rhs_operand" "rI")])
5314 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
5316 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
5317 [(set_attr "conds" "use")
5318 (set_attr "length" "8")])
5320 (define_insn "*ifcompare_neg_move"
5321 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5323 (match_operator 5 "comparison_operator"
5324 [(match_operand:SI 3 "s_register_operand" "r,r")
5325 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5326 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
5327 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5328 (clobber (reg:CC 24))]
5331 [(set_attr "conds" "clob")
5332 (set_attr "length" "8,12")])
5334 (define_insn "*if_neg_move"
5335 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5337 (match_operator 4 "comparison_operator"
5338 [(match_operand 3 "cc_register" "") (const_int 0)])
5339 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
5340 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5344 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
5345 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
5346 [(set_attr "conds" "use")
5347 (set_attr "length" "4,8,8")])
5349 (define_insn "*ifcompare_move_neg"
5350 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5352 (match_operator 5 "comparison_operator"
5353 [(match_operand:SI 3 "s_register_operand" "r,r")
5354 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5355 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5356 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
5357 (clobber (reg:CC 24))]
5360 [(set_attr "conds" "clob")
5361 (set_attr "length" "8,12")])
5363 (define_insn "*if_move_neg"
5364 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5366 (match_operator 4 "comparison_operator"
5367 [(match_operand 3 "cc_register" "") (const_int 0)])
5368 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5369 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
5373 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
5374 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
5375 [(set_attr "conds" "use")
5376 (set_attr "length" "4,8,8")])
5378 (define_insn "*arith_adjacentmem"
5379 [(set (match_operand:SI 0 "s_register_operand" "=r")
5380 (match_operator:SI 1 "shiftable_operator"
5381 [(match_operand:SI 2 "memory_operand" "m")
5382 (match_operand:SI 3 "memory_operand" "m")]))
5383 (clobber (match_scratch:SI 4 "=r"))]
5384 "adjacent_mem_locations (operands[2], operands[3])"
5389 int val1 = 0, val2 = 0;
5391 if (REGNO (operands[0]) > REGNO (operands[4]))
5393 ldm[1] = operands[4];
5394 ldm[2] = operands[0];
5398 ldm[1] = operands[0];
5399 ldm[2] = operands[4];
5401 if (GET_CODE (XEXP (operands[2], 0)) != REG)
5402 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
5403 if (GET_CODE (XEXP (operands[3], 0)) != REG)
5404 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
5405 arith[0] = operands[0];
5406 arith[3] = operands[1];
5420 ldm[0] = ops[0] = operands[4];
5421 ops[1] = XEXP (XEXP (operands[2], 0), 0);
5422 ops[2] = XEXP (XEXP (operands[2], 0), 1);
5423 output_add_immediate (ops);
5425 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5427 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5431 ldm[0] = XEXP (operands[3], 0);
5433 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5435 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5439 ldm[0] = XEXP (operands[2], 0);
5441 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5443 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5445 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
5449 [(set_attr "length" "12")
5450 (set_attr "type" "load")])
5452 ;; the arm can support extended pre-inc instructions
5454 ;; In all these cases, we use operands 0 and 1 for the register being
5455 ;; incremented because those are the operands that local-alloc will
5456 ;; tie and these are the pair most likely to be tieable (and the ones
5457 ;; that will benefit the most).
5459 ;; We reject the frame pointer if it occurs anywhere in these patterns since
5460 ;; elimination will cause too many headaches.
5462 (define_insn "*strqi_preinc"
5463 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5464 (match_operand:SI 2 "index_operand" "rJ")))
5465 (match_operand:QI 3 "s_register_operand" "r"))
5466 (set (match_operand:SI 0 "s_register_operand" "=r")
5467 (plus:SI (match_dup 1) (match_dup 2)))]
5468 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5469 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5470 && (GET_CODE (operands[2]) != REG
5471 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5472 "str%?b\\t%3, [%0, %2]!"
5473 [(set_attr "type" "store1")])
5475 (define_insn "*strqi_predec"
5476 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5477 (match_operand:SI 2 "s_register_operand" "r")))
5478 (match_operand:QI 3 "s_register_operand" "r"))
5479 (set (match_operand:SI 0 "s_register_operand" "=r")
5480 (minus:SI (match_dup 1) (match_dup 2)))]
5481 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5482 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5483 && (GET_CODE (operands[2]) != REG
5484 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5485 "str%?b\\t%3, [%0, -%2]!"
5486 [(set_attr "type" "store1")])
5488 (define_insn "*loadqi_preinc"
5489 [(set (match_operand:QI 3 "s_register_operand" "=r")
5490 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5491 (match_operand:SI 2 "index_operand" "rJ"))))
5492 (set (match_operand:SI 0 "s_register_operand" "=r")
5493 (plus:SI (match_dup 1) (match_dup 2)))]
5494 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5495 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5496 && (GET_CODE (operands[2]) != REG
5497 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5498 "ldr%?b\\t%3, [%0, %2]!"
5499 [(set_attr "type" "load")])
5501 (define_insn "*loadqi_predec"
5502 [(set (match_operand:QI 3 "s_register_operand" "=r")
5503 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5504 (match_operand:SI 2 "s_register_operand" "r"))))
5505 (set (match_operand:SI 0 "s_register_operand" "=r")
5506 (minus:SI (match_dup 1) (match_dup 2)))]
5507 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5508 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5509 && (GET_CODE (operands[2]) != REG
5510 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5511 "ldr%?b\\t%3, [%0, -%2]!"
5512 [(set_attr "type" "load")])
5514 (define_insn "*loadqisi_preinc"
5515 [(set (match_operand:SI 3 "s_register_operand" "=r")
5517 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5518 (match_operand:SI 2 "index_operand" "rJ")))))
5519 (set (match_operand:SI 0 "s_register_operand" "=r")
5520 (plus:SI (match_dup 1) (match_dup 2)))]
5521 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5522 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5523 && (GET_CODE (operands[2]) != REG
5524 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5525 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
5526 [(set_attr "type" "load")])
5528 (define_insn "*loadqisi_predec"
5529 [(set (match_operand:SI 3 "s_register_operand" "=r")
5531 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5532 (match_operand:SI 2 "s_register_operand" "r")))))
5533 (set (match_operand:SI 0 "s_register_operand" "=r")
5534 (minus:SI (match_dup 1) (match_dup 2)))]
5535 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5536 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5537 && (GET_CODE (operands[2]) != REG
5538 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5539 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
5540 [(set_attr "type" "load")])
5542 (define_insn "*strsi_preinc"
5543 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5544 (match_operand:SI 2 "index_operand" "rJ")))
5545 (match_operand:SI 3 "s_register_operand" "r"))
5546 (set (match_operand:SI 0 "s_register_operand" "=r")
5547 (plus:SI (match_dup 1) (match_dup 2)))]
5548 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5549 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5550 && (GET_CODE (operands[2]) != REG
5551 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5552 "str%?\\t%3, [%0, %2]!"
5553 [(set_attr "type" "store1")])
5555 (define_insn "*strqi_predec"
5556 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5557 (match_operand:SI 2 "s_register_operand" "r")))
5558 (match_operand:SI 3 "s_register_operand" "r"))
5559 (set (match_operand:SI 0 "s_register_operand" "=r")
5560 (minus:SI (match_dup 1) (match_dup 2)))]
5561 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5562 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5563 && (GET_CODE (operands[2]) != REG
5564 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5565 "str%?\\t%3, [%0, -%2]!"
5566 [(set_attr "type" "store1")])
5568 (define_insn "*loadsi_preinc"
5569 [(set (match_operand:SI 3 "s_register_operand" "=r")
5570 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5571 (match_operand:SI 2 "index_operand" "rJ"))))
5572 (set (match_operand:SI 0 "s_register_operand" "=r")
5573 (plus:SI (match_dup 1) (match_dup 2)))]
5574 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5575 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5576 && (GET_CODE (operands[2]) != REG
5577 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5578 "ldr%?\\t%3, [%0, %2]!"
5579 [(set_attr "type" "load")])
5581 (define_insn "*loadsi_predec"
5582 [(set (match_operand:SI 3 "s_register_operand" "=r")
5583 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5584 (match_operand:SI 2 "s_register_operand" "r"))))
5585 (set (match_operand:SI 0 "s_register_operand" "=r")
5586 (minus:SI (match_dup 1) (match_dup 2)))]
5587 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5588 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5589 && (GET_CODE (operands[2]) != REG
5590 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5591 "ldr%?\\t%3, [%0, -%2]!"
5592 [(set_attr "type" "load")])
5594 (define_insn "*loadhi_preinc"
5595 [(set (match_operand:HI 3 "s_register_operand" "=r")
5596 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5597 (match_operand:SI 2 "index_operand" "rJ"))))
5598 (set (match_operand:SI 0 "s_register_operand" "=r")
5599 (plus:SI (match_dup 1) (match_dup 2)))]
5600 "(! BYTES_BIG_ENDIAN)
5601 && ! TARGET_SHORT_BY_BYTES
5602 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5603 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5604 && (GET_CODE (operands[2]) != REG
5605 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5606 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
5607 [(set_attr "type" "load")])
5609 (define_insn "*loadhi_predec"
5610 [(set (match_operand:HI 3 "s_register_operand" "=r")
5611 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5612 (match_operand:SI 2 "s_register_operand" "r"))))
5613 (set (match_operand:SI 0 "s_register_operand" "=r")
5614 (minus:SI (match_dup 1) (match_dup 2)))]
5615 "(!BYTES_BIG_ENDIAN)
5616 && ! TARGET_SHORT_BY_BYTES
5617 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5618 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5619 && (GET_CODE (operands[2]) != REG
5620 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5621 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
5622 [(set_attr "type" "load")])
5624 (define_insn "*strqi_shiftpreinc"
5625 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5626 [(match_operand:SI 3 "s_register_operand" "r")
5627 (match_operand:SI 4 "const_shift_operand" "n")])
5628 (match_operand:SI 1 "s_register_operand" "0")))
5629 (match_operand:QI 5 "s_register_operand" "r"))
5630 (set (match_operand:SI 0 "s_register_operand" "=r")
5631 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5633 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5634 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5635 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5636 "str%?b\\t%5, [%0, %3%S2]!"
5637 [(set_attr "type" "store1")])
5639 (define_insn "*strqi_shiftpredec"
5640 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5641 (match_operator:SI 2 "shift_operator"
5642 [(match_operand:SI 3 "s_register_operand" "r")
5643 (match_operand:SI 4 "const_shift_operand" "n")])))
5644 (match_operand:QI 5 "s_register_operand" "r"))
5645 (set (match_operand:SI 0 "s_register_operand" "=r")
5646 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5648 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5649 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5650 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5651 "str%?b\\t%5, [%0, -%3%S2]!"
5652 [(set_attr "type" "store1")])
5654 (define_insn "*loadqi_shiftpreinc"
5655 [(set (match_operand:QI 5 "s_register_operand" "=r")
5656 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5657 [(match_operand:SI 3 "s_register_operand" "r")
5658 (match_operand:SI 4 "const_shift_operand" "n")])
5659 (match_operand:SI 1 "s_register_operand" "0"))))
5660 (set (match_operand:SI 0 "s_register_operand" "=r")
5661 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5663 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5664 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5665 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5666 "ldr%?b\\t%5, [%0, %3%S2]!"
5667 [(set_attr "type" "load")])
5669 (define_insn "*loadqi_shiftpredec"
5670 [(set (match_operand:QI 5 "s_register_operand" "=r")
5671 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5672 (match_operator:SI 2 "shift_operator"
5673 [(match_operand:SI 3 "s_register_operand" "r")
5674 (match_operand:SI 4 "const_shift_operand" "n")]))))
5675 (set (match_operand:SI 0 "s_register_operand" "=r")
5676 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5678 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5679 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5680 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5681 "ldr%?b\\t%5, [%0, -%3%S2]!"
5682 [(set_attr "type" "load")])
5684 (define_insn "*strsi_shiftpreinc"
5685 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5686 [(match_operand:SI 3 "s_register_operand" "r")
5687 (match_operand:SI 4 "const_shift_operand" "n")])
5688 (match_operand:SI 1 "s_register_operand" "0")))
5689 (match_operand:SI 5 "s_register_operand" "r"))
5690 (set (match_operand:SI 0 "s_register_operand" "=r")
5691 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5693 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5694 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5695 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5696 "str%?\\t%5, [%0, %3%S2]!"
5697 [(set_attr "type" "store1")])
5699 (define_insn "*strsi_shiftpredec"
5700 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5701 (match_operator:SI 2 "shift_operator"
5702 [(match_operand:SI 3 "s_register_operand" "r")
5703 (match_operand:SI 4 "const_shift_operand" "n")])))
5704 (match_operand:SI 5 "s_register_operand" "r"))
5705 (set (match_operand:SI 0 "s_register_operand" "=r")
5706 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5708 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5709 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5710 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5711 "str%?\\t%5, [%0, -%3%S2]!"
5712 [(set_attr "type" "store1")])
5714 (define_insn "*loadqi_shiftpreinc"
5715 [(set (match_operand:SI 5 "s_register_operand" "=r")
5716 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5717 [(match_operand:SI 3 "s_register_operand" "r")
5718 (match_operand:SI 4 "const_shift_operand" "n")])
5719 (match_operand:SI 1 "s_register_operand" "0"))))
5720 (set (match_operand:SI 0 "s_register_operand" "=r")
5721 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5723 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5724 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5725 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5726 "ldr%?\\t%5, [%0, %3%S2]!"
5727 [(set_attr "type" "load")])
5729 (define_insn "*loadqi_shiftpredec"
5730 [(set (match_operand:SI 5 "s_register_operand" "=r")
5731 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5732 (match_operator:SI 2 "shift_operator"
5733 [(match_operand:SI 3 "s_register_operand" "r")
5734 (match_operand:SI 4 "const_shift_operand" "n")]))))
5735 (set (match_operand:SI 0 "s_register_operand" "=r")
5736 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5738 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5739 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5740 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5741 "ldr%?\\t%5, [%0, -%3%S2]!"
5742 [(set_attr "type" "load")])
5744 (define_insn "*loadhi_shiftpreinc"
5745 [(set (match_operand:HI 5 "s_register_operand" "=r")
5746 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5747 [(match_operand:SI 3 "s_register_operand" "r")
5748 (match_operand:SI 4 "const_shift_operand" "n")])
5749 (match_operand:SI 1 "s_register_operand" "0"))))
5750 (set (match_operand:SI 0 "s_register_operand" "=r")
5751 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5753 "(! BYTES_BIG_ENDIAN)
5754 && ! TARGET_SHORT_BY_BYTES
5755 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5756 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5757 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5758 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
5759 [(set_attr "type" "load")])
5761 (define_insn "*loadhi_shiftpredec"
5762 [(set (match_operand:HI 5 "s_register_operand" "=r")
5763 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5764 (match_operator:SI 2 "shift_operator"
5765 [(match_operand:SI 3 "s_register_operand" "r")
5766 (match_operand:SI 4 "const_shift_operand" "n")]))))
5767 (set (match_operand:SI 0 "s_register_operand" "=r")
5768 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5770 "(! BYTES_BIG_ENDIAN)
5771 && ! TARGET_SHORT_BY_BYTES
5772 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5773 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5774 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5775 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
5776 [(set_attr "type" "load")])
5778 ; It can also support extended post-inc expressions, but combine doesn't
5780 ; It doesn't seem worth adding peepholes for anything but the most common
5781 ; cases since, unlike combine, the increment must immediately follow the load
5782 ; for this pattern to match.
5783 ; When loading we must watch to see that the base register isn't trampled by
5784 ; the load. In such cases this isn't a post-inc expression.
5787 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5788 (match_operand:QI 2 "s_register_operand" "r"))
5790 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5792 "str%?b\\t%2, [%0], %1")
5795 [(set (match_operand:QI 0 "s_register_operand" "=r")
5796 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
5798 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5799 "REGNO(operands[0]) != REGNO(operands[1])
5800 && (GET_CODE (operands[2]) != REG
5801 || REGNO(operands[0]) != REGNO (operands[2]))"
5802 "ldr%?b\\t%0, [%1], %2")
5805 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5806 (match_operand:SI 2 "s_register_operand" "r"))
5808 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5810 "str%?\\t%2, [%0], %1")
5813 [(set (match_operand:HI 0 "s_register_operand" "=r")
5814 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5816 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5817 "(! BYTES_BIG_ENDIAN)
5818 && ! TARGET_SHORT_BY_BYTES
5819 && REGNO(operands[0]) != REGNO(operands[1])
5820 && (GET_CODE (operands[2]) != REG
5821 || REGNO(operands[0]) != REGNO (operands[2]))"
5822 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5825 [(set (match_operand:SI 0 "s_register_operand" "=r")
5826 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5828 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5829 "REGNO(operands[0]) != REGNO(operands[1])
5830 && (GET_CODE (operands[2]) != REG
5831 || REGNO(operands[0]) != REGNO (operands[2]))"
5832 "ldr%?\\t%0, [%1], %2")
5835 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5836 (match_operand:SI 1 "index_operand" "rJ")))
5837 (match_operand:QI 2 "s_register_operand" "r"))
5838 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5840 "str%?b\\t%2, [%0, %1]!")
5843 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5844 [(match_operand:SI 0 "s_register_operand" "r")
5845 (match_operand:SI 1 "const_int_operand" "n")])
5846 (match_operand:SI 2 "s_register_operand" "+r")))
5847 (match_operand:QI 3 "s_register_operand" "r"))
5848 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5851 "str%?b\\t%3, [%2, %0%S4]!")
5853 ; This pattern is never tried by combine, so do it as a peephole
5856 [(set (match_operand:SI 0 "s_register_operand" "=r")
5857 (match_operand:SI 1 "s_register_operand" "r"))
5859 (compare:CC (match_dup 1) (const_int 0)))]
5861 "sub%?s\\t%0, %1, #0"
5862 [(set_attr "conds" "set")])
5864 ; Peepholes to spot possible load- and store-multiples.
5867 [(set (match_operand:SI 0 "s_register_operand" "=r")
5868 (match_operand:SI 4 "memory_operand" "m"))
5869 (set (match_operand:SI 1 "s_register_operand" "=r")
5870 (match_operand:SI 5 "memory_operand" "m"))
5871 (set (match_operand:SI 2 "s_register_operand" "=r")
5872 (match_operand:SI 6 "memory_operand" "m"))
5873 (set (match_operand:SI 3 "s_register_operand" "=r")
5874 (match_operand:SI 7 "memory_operand" "m"))]
5875 "load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5877 return emit_ldm_seq (operands, 4);
5881 [(set (match_operand:SI 0 "s_register_operand" "=r")
5882 (match_operand:SI 3 "memory_operand" "m"))
5883 (set (match_operand:SI 1 "s_register_operand" "=r")
5884 (match_operand:SI 4 "memory_operand" "m"))
5885 (set (match_operand:SI 2 "s_register_operand" "=r")
5886 (match_operand:SI 5 "memory_operand" "m"))]
5887 "load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5889 return emit_ldm_seq (operands, 3);
5893 [(set (match_operand:SI 0 "s_register_operand" "=r")
5894 (match_operand:SI 2 "memory_operand" "m"))
5895 (set (match_operand:SI 1 "s_register_operand" "=r")
5896 (match_operand:SI 3 "memory_operand" "m"))]
5897 "load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5899 return emit_ldm_seq (operands, 2);
5903 [(set (match_operand:SI 4 "memory_operand" "=m")
5904 (match_operand:SI 0 "s_register_operand" "r"))
5905 (set (match_operand:SI 5 "memory_operand" "=m")
5906 (match_operand:SI 1 "s_register_operand" "r"))
5907 (set (match_operand:SI 6 "memory_operand" "=m")
5908 (match_operand:SI 2 "s_register_operand" "r"))
5909 (set (match_operand:SI 7 "memory_operand" "=m")
5910 (match_operand:SI 3 "s_register_operand" "r"))]
5911 "store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5913 return emit_stm_seq (operands, 4);
5917 [(set (match_operand:SI 3 "memory_operand" "=m")
5918 (match_operand:SI 0 "s_register_operand" "r"))
5919 (set (match_operand:SI 4 "memory_operand" "=m")
5920 (match_operand:SI 1 "s_register_operand" "r"))
5921 (set (match_operand:SI 5 "memory_operand" "=m")
5922 (match_operand:SI 2 "s_register_operand" "r"))]
5923 "store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5925 return emit_stm_seq (operands, 3);
5929 [(set (match_operand:SI 2 "memory_operand" "=m")
5930 (match_operand:SI 0 "s_register_operand" "r"))
5931 (set (match_operand:SI 3 "memory_operand" "=m")
5932 (match_operand:SI 1 "s_register_operand" "r"))]
5933 "store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5935 return emit_stm_seq (operands, 2);
5938 ;; A call followed by return can be replaced by restoring the regs and
5939 ;; jumping to the subroutine, provided we aren't passing the address of
5940 ;; any of our local variables. If we call alloca then this is unsafe
5941 ;; since restoring the frame frees the memory, which is not what we want.
5942 ;; Sometimes the return might have been targeted by the final prescan:
5943 ;; if so then emit a proper return insn as well.
5944 ;; Unfortunately, if the frame pointer is required, we don't know if the
5945 ;; current function has any implicit stack pointer adjustments that will
5946 ;; be restored by the return: we can't therefore do a tail call.
5947 ;; Another unfortunate that we can't handle is if current_function_args_size
5948 ;; is non-zero: in this case elimination of the argument pointer assumed
5949 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5953 [(parallel [(call (mem:SI (match_operand:SI 0 "" "X"))
5954 (match_operand:SI 1 "general_operand" "g"))
5955 (clobber (reg:SI 14))])
5957 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
5958 && !get_frame_size () && !current_function_calls_alloca
5959 && !frame_pointer_needed && !current_function_args_size)"
5962 extern rtx arm_target_insn;
5963 extern int arm_ccfsm_state;
5965 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5967 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5968 output_return_instruction (NULL, TRUE, FALSE);
5969 arm_ccfsm_state = 0;
5970 arm_target_insn = NULL;
5973 output_return_instruction (NULL, FALSE, FALSE);
5974 return \"b%?\\t%a0\";
5976 [(set_attr "type" "call")
5977 (set_attr "length" "8")])
5980 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
5981 (call (mem:SI (match_operand:SI 1 "" "X"))
5982 (match_operand:SI 2 "general_operand" "g")))
5983 (clobber (reg:SI 14))])
5985 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
5986 && !get_frame_size () && !current_function_calls_alloca
5987 && !frame_pointer_needed && !current_function_args_size)"
5990 extern rtx arm_target_insn;
5991 extern int arm_ccfsm_state;
5993 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5995 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5996 output_return_instruction (NULL, TRUE, FALSE);
5997 arm_ccfsm_state = 0;
5998 arm_target_insn = NULL;
6001 output_return_instruction (NULL, FALSE, FALSE);
6002 return \"b%?\\t%a1\";
6004 [(set_attr "type" "call")
6005 (set_attr "length" "8")])
6007 ;; As above but when this function is not void, we must be returning the
6008 ;; result of the called subroutine.
6011 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
6012 (call (mem:SI (match_operand:SI 1 "" "X"))
6013 (match_operand:SI 2 "general_operand" "g")))
6014 (clobber (reg:SI 14))])
6017 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
6018 && !get_frame_size () && !current_function_calls_alloca
6019 && !frame_pointer_needed && !current_function_args_size)"
6022 extern rtx arm_target_insn;
6023 extern int arm_ccfsm_state;
6025 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
6027 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6028 output_return_instruction (NULL, TRUE, FALSE);
6029 arm_ccfsm_state = 0;
6030 arm_target_insn = NULL;
6033 output_return_instruction (NULL, FALSE, FALSE);
6034 return \"b%?\\t%a1\";
6036 [(set_attr "type" "call")
6037 (set_attr "length" "8")])
6040 [(set (match_operand:SI 0 "s_register_operand" "")
6041 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
6043 (neg:SI (match_operator:SI 2 "comparison_operator"
6044 [(match_operand:SI 3 "s_register_operand" "")
6045 (match_operand:SI 4 "arm_rhs_operand" "")]))))
6046 (clobber (match_operand:SI 5 "s_register_operand" ""))]
6048 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
6049 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
6053 ;; This split can be used because CC_Z mode implies that the following
6054 ;; branch will be an equality, or an unsigned inequality, so the sign
6055 ;; extension is not needed.
6060 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
6062 (match_operand 1 "const_int_operand" "")))
6063 (clobber (match_scratch:SI 2 ""))]
6064 "((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
6065 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24"
6066 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
6067 (set (reg:CC 24) (compare:CC (match_dup 2) (match_dup 1)))]
6069 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
6072 (define_expand "prologue"
6073 [(clobber (const_int 0))]
6076 arm_expand_prologue ();
6080 ;; This split is only used during output to reduce the number of patterns
6081 ;; that need assembler instructions adding to them. We allowed the setting
6082 ;; of the conditions to be implicit during rtl generation so that
6083 ;; the conditional compare patterns would work. However this conflicts to
6084 ;; some extent with the conditional data operations, so we have to split them
6088 [(set (match_operand:SI 0 "s_register_operand" "")
6089 (if_then_else:SI (match_operator 1 "comparison_operator"
6090 [(match_operand 2 "" "") (match_operand 3 "" "")])
6091 (match_operand 4 "" "")
6092 (match_operand 5 "" "")))
6095 [(set (match_dup 6) (match_dup 7))
6097 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
6102 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
6105 operands[6] = gen_rtx (REG, mode, 24);
6106 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
6111 ;; The next two patterns occur when an AND operation is followed by a
6112 ;; scc insn sequence
6114 (define_insn "*sign_extract_onebit"
6115 [(set (match_operand:SI 0 "s_register_operand" "=r")
6116 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
6118 (match_operand:SI 2 "const_int_operand" "n")))]
6121 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6122 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
6123 return \"mvnne\\t%0, #0\";
6125 [(set_attr "conds" "clob")
6126 (set_attr "length" "8")])
6128 (define_insn "*not_signextract_onebit"
6129 [(set (match_operand:SI 0 "s_register_operand" "=r")
6131 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
6133 (match_operand:SI 2 "const_int_operand" "n"))))]
6136 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6137 output_asm_insn (\"tst\\t%1, %2\", operands);
6138 output_asm_insn (\"mvneq\\t%0, #0\", operands);
6139 return \"movne\\t%0, #0\";
6141 [(set_attr "conds" "clob")
6142 (set_attr "length" "12")])
6144 ;; Push multiple registers to the stack. The first register is in the
6145 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
6147 (define_insn "*push_multi"
6148 [(match_parallel 2 "multi_register_push"
6149 [(set (match_operand:BLK 0 "memory_operand" "=m")
6150 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
6156 extern int lr_save_eliminated;
6158 if (lr_save_eliminated)
6160 if (XVECLEN (operands[2], 0) > 1)
6164 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
6165 for (i = 1; i < XVECLEN (operands[2], 0); i++)
6167 strcat (pattern, \", %|\");
6168 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
6171 strcat (pattern, \"}\");
6172 output_asm_insn (pattern, operands);
6175 [(set_attr "type" "store4")])
6177 ;; Similarly for the floating point registers
6178 (define_insn "*push_fp_multi"
6179 [(match_parallel 2 "multi_register_push"
6180 [(set (match_operand:BLK 0 "memory_operand" "=m")
6181 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")] 2))])]
6188 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
6189 output_asm_insn (pattern, operands);
6192 [(set_attr "type" "f_store")])
6194 ;; Special patterns for dealing with the constant pool
6196 (define_insn "consttable_4"
6197 [(unspec_volatile [(match_operand 0 "" "")] 2)]
6201 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
6205 union real_extract u;
6206 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
6207 assemble_real (u.d, GET_MODE (operands[0]));
6211 assemble_integer (operands[0], 4, 1);
6216 [(set_attr "length" "4")])
6218 (define_insn "consttable_8"
6219 [(unspec_volatile [(match_operand 0 "" "")] 3)]
6223 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
6227 union real_extract u;
6228 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
6229 assemble_real (u.d, GET_MODE (operands[0]));
6233 assemble_integer (operands[0], 8, 1);
6238 [(set_attr "length" "8")])
6240 (define_insn "consttable_end"
6241 [(unspec_volatile [(const_int 0)] 4)]
6244 /* Nothing to do (currently). */
6248 (define_insn "align_4"
6249 [(unspec_volatile [(const_int 0)] 5)]
6252 assemble_align (32);