1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991, 93-98, 1999 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 (rearnsha@arm.com).
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 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
50 ; Floating Point Unit. If we only have floating point emulation, then there
51 ; is no point in scheduling the floating point insns. (Well, for best
52 ; performance we should try and group them together).
54 (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
56 ; LENGTH of an instruction (in bytes)
57 (define_attr "length" "" (const_int 4))
59 ; An assembler sequence may clobber the condition codes without us knowing
60 (define_asm_attributes
61 [(set_attr "conds" "clob")
62 (set_attr "length" "4")])
64 ; TYPE attribute is used to detect floating point instructions which, if
65 ; running on a co-processor can run in parallel with other, basic instructions
66 ; If write-buffer scheduling is enabled then it can also be used in the
67 ; scheduling of writes.
69 ; Classification of each insn
70 ; normal any data instruction that doesn't hit memory or fp regs
71 ; mult a multiply instruction
72 ; block blockage insn, this blocks all functional units
73 ; float a floating point arithmetic operation (subject to expansion)
74 ; fdivx XFmode floating point division
75 ; fdivd DFmode floating point division
76 ; fdivs SFmode floating point division
77 ; fmul Floating point multiply
78 ; ffmul Fast floating point multiply
79 ; farith Floating point arithmetic (4 cycle)
80 ; ffarith Fast floating point arithmetic (2 cycle)
81 ; float_em a floating point arithmetic operation that is normally emulated
82 ; even on a machine with an fpa.
83 ; f_load a floating point load from memory
84 ; f_store a floating point store to memory
85 ; f_mem_r a transfer of a floating point register to a real reg via mem
86 ; r_mem_f the reverse of f_mem_r
87 ; f_2_r fast transfer float to arm (no memory needed)
88 ; r_2_f fast transfer arm to float
89 ; call a subroutine call
90 ; load any load from memory
91 ; store1 store 1 word to memory from arm registers
92 ; store2 store 2 words
93 ; store3 store 3 words
94 ; store4 store 4 words
97 "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"
98 (const_string "normal"))
100 ; Load scheduling, set from the arm_ld_sched variable
101 ; initialised by arm_override_options()
102 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
104 ; condition codes: this one is used by final_prescan_insn to speed up
105 ; conditionalizing instructions. It saves having to scan the rtl to see if
106 ; it uses or alters the condition codes.
108 ; USE means that the condition codes are used by the insn in the process of
109 ; outputting code, this means (at present) that we can't use the insn in
112 ; SET means that the purpose of the insn is to set the condition codes in a
113 ; well defined manner.
115 ; CLOB means that the condition codes are altered in an undefined manner, if
116 ; they are altered at all
118 ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
119 ; but are if the branch wasn't taken; the effect is to limit the branch
120 ; elimination scanning.
122 ; NOCOND means that the condition codes are neither altered nor affect the
123 ; output of this insn
125 (define_attr "conds" "use,set,clob,jump_clob,nocond"
126 (if_then_else (eq_attr "type" "call")
127 (if_then_else (eq_attr "prog_mode" "prog32")
128 (const_string "clob") (const_string "nocond"))
129 (const_string "nocond")))
131 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
132 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
133 ; suffer blockages enough to warrent modelling this (and it can adversely
134 ; affect the schedule).
135 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
137 (define_attr "write_conflict" "no,yes"
138 (if_then_else (eq_attr "type"
139 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
141 (const_string "no")))
143 (define_attr "core_cycles" "single,multi"
144 (if_then_else (eq_attr "type"
145 "normal,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
146 (const_string "single")
147 (const_string "multi")))
149 ; The write buffer on some of the arm6 processors is hard to model exactly.
150 ; There is room in the buffer for up to two addresses and up to eight words
151 ; of memory, but the two needn't be split evenly. When writing the two
152 ; addresses are fully pipelined. However, a read from memory that is not
153 ; currently in the cache will block until the writes have completed.
154 ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
155 ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
156 ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
157 ; cycle to add as well.
159 ;; (define_function_unit {name} {num-units} {n-users} {test}
160 ;; {ready-delay} {issue-delay} [{conflict-list}])
161 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
162 (eq_attr "type" "fdivx")) 71 69)
164 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
165 (eq_attr "type" "fdivd")) 59 57)
167 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
168 (eq_attr "type" "fdivs")) 31 29)
170 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
171 (eq_attr "type" "fmul")) 9 7)
173 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
174 (eq_attr "type" "ffmul")) 6 4)
176 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
177 (eq_attr "type" "farith")) 4 2)
179 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
180 (eq_attr "type" "ffarith")) 2 2)
182 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
183 (eq_attr "type" "r_2_f")) 5 3)
185 (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
186 (eq_attr "type" "f_2_r")) 1 2)
188 ;; The fpa10 doesn't really have a memory read unit, but it can start to
189 ;; speculatively execute the instruction in the pipeline, provided the data
190 ;; is already loaded, so pretend reads have a delay of 2 (and that the
191 ;; pipeline is infinite.
193 (define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
194 (eq_attr "type" "f_load")) 3 1)
196 ;;--------------------------------------------------------------------
198 ;;--------------------------------------------------------------------
199 ;; Strictly we should model a 4-deep write buffer for ARM7xx based chips
200 (define_function_unit "write_buf" 1 2
201 (and (eq_attr "model_wbuf" "yes")
202 (eq_attr "type" "store1,r_mem_f")) 5 3)
203 (define_function_unit "write_buf" 1 2
204 (and (eq_attr "model_wbuf" "yes")
205 (eq_attr "type" "store2")) 7 4)
206 (define_function_unit "write_buf" 1 2
207 (and (eq_attr "model_wbuf" "yes")
208 (eq_attr "type" "store3")) 9 5)
209 (define_function_unit "write_buf" 1 2
210 (and (eq_attr "model_wbuf" "yes")
211 (eq_attr "type" "store4")) 11 6)
213 ;;--------------------------------------------------------------------
214 ;; Write blockage unit
215 ;;--------------------------------------------------------------------
216 ;; The write_blockage unit models (partially), the fact that reads will stall
217 ;; until the write buffer empties.
218 ;; The f_mem_r and r_mem_f could also block, but they are to the stack,
219 ;; so we don't model them here
220 (define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
221 (eq_attr "type" "store1")) 5 5
222 [(eq_attr "write_conflict" "yes")])
223 (define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
224 (eq_attr "type" "store2")) 7 7
225 [(eq_attr "write_conflict" "yes")])
226 (define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
227 (eq_attr "type" "store3")) 9 9
228 [(eq_attr "write_conflict" "yes")])
229 (define_function_unit "write_blockage" 1 0
230 (and (eq_attr "model_wbuf" "yes") (eq_attr "type" "store4")) 11 11
231 [(eq_attr "write_conflict" "yes")])
232 (define_function_unit "write_blockage" 1 0
233 (and (eq_attr "model_wbuf" "yes")
234 (eq_attr "write_conflict" "yes")) 1 1)
236 ;;--------------------------------------------------------------------
238 ;;--------------------------------------------------------------------
239 ;; Everything must spend at least one cycle in the core unit
240 (define_function_unit "core" 1 0
241 (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
243 (define_function_unit "core" 1 0
244 (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
246 (define_function_unit "core" 1 0
247 (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1")) 2 2)
249 (define_function_unit "core" 1 0
250 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load")) 3 3)
252 (define_function_unit "core" 1 0
253 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store")) 4 4)
255 (define_function_unit "core" 1 0
256 (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")) 6 6)
258 (define_function_unit "core" 1 0
259 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
261 (define_function_unit "core" 1 0
262 (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")) 16 16)
264 (define_function_unit "core" 1 0
265 (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
266 (eq_attr "type" "mult")) 4 4)
268 (define_function_unit "core" 1 0
269 (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
270 (eq_attr "type" "mult")) 3 2)
272 (define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
274 (define_function_unit "core" 1 0 (eq_attr "type" "store3") 4 4)
276 (define_function_unit "core" 1 0 (eq_attr "type" "store4") 5 5)
278 ;; Note: For DImode insns, there is normally no reason why operands should
279 ;; not be in the same register, what we don't want is for something being
280 ;; written to partially overlap something that is an input.
284 (define_insn "adddi3"
285 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
286 (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
287 (match_operand:DI 2 "s_register_operand" "r,0")))
288 (clobber (reg:CC 24))]
290 "adds\\t%Q0, %Q1, %Q2\;adc\\t%R0, %R1, %R2"
291 [(set_attr "conds" "clob")
292 (set_attr "length" "8")])
294 (define_insn "*adddi_sesidi_di"
295 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
296 (plus:DI (sign_extend:DI
297 (match_operand:SI 2 "s_register_operand" "r,r"))
298 (match_operand:DI 1 "s_register_operand" "r,0")))
299 (clobber (reg:CC 24))]
301 "adds\\t%Q0, %Q1, %2\;adc\\t%R0, %R1, %2, asr #31"
302 [(set_attr "conds" "clob")
303 (set_attr "length" "8")])
305 (define_insn "*adddi_zesidi_di"
306 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
307 (plus:DI (zero_extend:DI
308 (match_operand:SI 2 "s_register_operand" "r,r"))
309 (match_operand:DI 1 "s_register_operand" "r,0")))
310 (clobber (reg:CC 24))]
312 "adds\\t%Q0, %Q1, %2\;adc\\t%R0, %R1, #0"
313 [(set_attr "conds" "clob")
314 (set_attr "length" "8")])
316 (define_expand "addsi3"
317 [(set (match_operand:SI 0 "s_register_operand" "")
318 (plus:SI (match_operand:SI 1 "s_register_operand" "")
319 (match_operand:SI 2 "reg_or_int_operand" "")))]
322 if (GET_CODE (operands[2]) == CONST_INT)
324 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
326 (reload_in_progress || reload_completed ? 0
327 : preserve_subexpressions_p ()));
333 [(set (match_operand:SI 0 "s_register_operand" "")
334 (plus:SI (match_operand:SI 1 "s_register_operand" "")
335 (match_operand:SI 2 "const_int_operand" "")))]
336 "! (const_ok_for_arm (INTVAL (operands[2]))
337 || const_ok_for_arm (-INTVAL (operands[2])))"
338 [(clobber (const_int 0))]
340 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
345 (define_insn "*addsi3_insn"
346 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
347 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
348 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
354 [(set_attr "length" "4,4,16")])
356 (define_insn "*addsi3_compare0"
357 [(set (reg:CC_NOOV 24)
359 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
360 (match_operand:SI 2 "arm_add_operand" "rI,L"))
362 (set (match_operand:SI 0 "s_register_operand" "=r,r")
363 (plus:SI (match_dup 1) (match_dup 2)))]
367 sub%?s\\t%0, %1, #%n2"
368 [(set_attr "conds" "set")])
370 (define_insn "*addsi3_compare0_scratch"
371 [(set (reg:CC_NOOV 24)
373 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
374 (match_operand:SI 1 "arm_add_operand" "rI,L"))
380 [(set_attr "conds" "set")])
382 ;; The next four insns work because they compare the result with one of
383 ;; the operands, and we know that the use of the condition code is
384 ;; either GEU or LTU, so we can use the carry flag from the addition
385 ;; instead of doing the compare a second time.
386 (define_insn "*addsi3_compare_op1"
389 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
390 (match_operand:SI 2 "arm_add_operand" "rI,L"))
392 (set (match_operand:SI 0 "s_register_operand" "=r,r")
393 (plus:SI (match_dup 1) (match_dup 2)))]
397 sub%?s\\t%0, %1, #%n2"
398 [(set_attr "conds" "set")])
400 (define_insn "*addsi3_compare_op2"
403 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
404 (match_operand:SI 2 "arm_add_operand" "rI,L"))
406 (set (match_operand:SI 0 "s_register_operand" "=r,r")
407 (plus:SI (match_dup 1) (match_dup 2)))]
411 sub%?s\\t%0, %1, #%n2"
412 [(set_attr "conds" "set")])
414 (define_insn "*compare_addsi2_op0"
417 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
418 (match_operand:SI 1 "arm_add_operand" "rI,L"))
424 [(set_attr "conds" "set")])
426 (define_insn "*compare_addsi2_op1"
429 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
430 (match_operand:SI 1 "arm_add_operand" "rI,L"))
436 [(set_attr "conds" "set")])
438 (define_insn "*addsi3_carryin"
439 [(set (match_operand:SI 0 "s_register_operand" "=r")
440 (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
441 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
442 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
445 [(set_attr "conds" "use")])
447 (define_insn "*addsi3_carryin_alt1"
448 [(set (match_operand:SI 0 "s_register_operand" "=r")
449 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
450 (match_operand:SI 2 "arm_rhs_operand" "rI"))
451 (ltu:SI (reg:CC_C 24) (const_int 0))))]
454 [(set_attr "conds" "use")])
456 (define_insn "*addsi3_carryin_alt2"
457 [(set (match_operand:SI 0 "s_register_operand" "=r")
458 (plus:SI (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
459 (match_operand:SI 1 "s_register_operand" "r"))
460 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
463 [(set_attr "conds" "use")])
465 (define_insn "*addsi3_carryin_alt3"
466 [(set (match_operand:SI 0 "s_register_operand" "=r")
467 (plus:SI (plus:SI (ltu:SI (reg:CC_C 24) (const_int 0))
468 (match_operand:SI 2 "arm_rhs_operand" "rI"))
469 (match_operand:SI 1 "s_register_operand" "r")))]
472 [(set_attr "conds" "use")])
474 (define_insn "incscc"
475 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
476 (plus:SI (match_operator:SI 2 "comparison_operator"
477 [(match_operand 3 "cc_register" "") (const_int 0)])
478 (match_operand:SI 1 "s_register_operand" "0,?r")))]
482 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
483 [(set_attr "conds" "use")
484 (set_attr "length" "4,8")])
486 ; If a constant is too big to fit in a single instruction then the constant
487 ; will be pre-loaded into a register taking at least two insns, we might be
488 ; able to merge it with an add, but it depends on the exact value.
491 [(set (match_operand:SI 0 "s_register_operand" "=r")
492 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
493 (match_operand:SI 2 "const_int_operand" "n")))]
494 "!(const_ok_for_arm (INTVAL (operands[2]))
495 || const_ok_for_arm (-INTVAL (operands[2])))"
496 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
497 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
500 unsigned int val = (unsigned) INTVAL (operands[2]);
504 /* this code is similar to the approach followed in movsi, but it must
505 generate exactly two insns */
507 for (i = 30; i >= 0; i -= 2)
513 if (const_ok_for_arm (temp = (val & ~(255 << i))))
518 /* we might be able to do this as (larger number - small number) */
519 temp = ((val >> i) & 255) + 1;
520 if (temp > 255 && i < 24)
523 temp = ((val >> i) & 255) + 1;
525 if (const_ok_for_arm ((temp << i) - val))
528 temp = (unsigned) - (int) (i - val);
535 /* if we got here, we have found a way of doing it in two instructions.
536 the two constants are in val and temp */
537 operands[2] = GEN_INT ((int)val);
538 operands[3] = GEN_INT ((int)temp);
542 (define_insn "addsf3"
543 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
544 (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
545 (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
549 suf%?s\\t%0, %1, #%N2"
550 [(set_attr "type" "farith")])
552 (define_insn "adddf3"
553 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
554 (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
555 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
559 suf%?d\\t%0, %1, #%N2"
560 [(set_attr "type" "farith")])
562 (define_insn "*adddf_df_esfdf"
563 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
564 (plus:DF (float_extend:DF
565 (match_operand:SF 1 "s_register_operand" "f,f"))
566 (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
570 suf%?d\\t%0, %1, #%N2"
571 [(set_attr "type" "farith")])
573 (define_insn "*adddf_df_esfdf"
574 [(set (match_operand:DF 0 "s_register_operand" "=f")
575 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
577 (match_operand:SF 2 "s_register_operand" "f"))))]
579 "adf%?d\\t%0, %1, %2"
580 [(set_attr "type" "farith")])
582 (define_insn "*adddf_esfdf_esfdf"
583 [(set (match_operand:DF 0 "s_register_operand" "=f")
584 (plus:DF (float_extend:DF
585 (match_operand:SF 1 "s_register_operand" "f"))
587 (match_operand:SF 2 "s_register_operand" "f"))))]
589 "adf%?d\\t%0, %1, %2"
590 [(set_attr "type" "farith")])
592 (define_insn "addxf3"
593 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
594 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
595 (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
596 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
599 suf%?e\\t%0, %1, #%N2"
600 [(set_attr "type" "farith")])
602 (define_insn "subdi3"
603 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
604 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
605 (match_operand:DI 2 "s_register_operand" "r,0,0")))
606 (clobber (reg:CC 24))]
608 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
609 [(set_attr "conds" "clob")
610 (set_attr "length" "8")])
612 (define_insn "*subdi_di_zesidi"
613 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
614 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
616 (match_operand:SI 2 "s_register_operand" "r,r"))))
617 (clobber (reg:CC 24))]
619 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
620 [(set_attr "conds" "clob")
621 (set_attr "length" "8")])
623 (define_insn "*subdi_di_sesidi"
624 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
625 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
627 (match_operand:SI 2 "s_register_operand" "r,r"))))
628 (clobber (reg:CC 24))]
630 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
631 [(set_attr "conds" "clob")
632 (set_attr "length" "8")])
634 (define_insn "*subdi_zesidi_di"
635 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
636 (minus:DI (zero_extend:DI
637 (match_operand:SI 2 "s_register_operand" "r,r"))
638 (match_operand:DI 1 "s_register_operand" "?r,0")))
639 (clobber (reg:CC 24))]
641 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
642 [(set_attr "conds" "clob")
643 (set_attr "length" "8")])
645 (define_insn "*subdi_sesidi_di"
646 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
647 (minus:DI (sign_extend:DI
648 (match_operand:SI 2 "s_register_operand" "r,r"))
649 (match_operand:DI 1 "s_register_operand" "?r,0")))
650 (clobber (reg:CC 24))]
652 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
653 [(set_attr "conds" "clob")
654 (set_attr "length" "8")])
656 (define_insn "*subdi_zesidi_zesidi"
657 [(set (match_operand:DI 0 "s_register_operand" "=r")
658 (minus:DI (zero_extend:DI
659 (match_operand:SI 1 "s_register_operand" "r"))
661 (match_operand:SI 2 "s_register_operand" "r"))))
662 (clobber (reg:CC 24))]
664 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
665 [(set_attr "conds" "clob")
666 (set_attr "length" "8")])
668 (define_expand "subsi3"
669 [(set (match_operand:SI 0 "s_register_operand" "")
670 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
671 (match_operand:SI 2 "s_register_operand" "")))]
674 if (GET_CODE (operands[1]) == CONST_INT)
676 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
678 (reload_in_progress || reload_completed ? 0
679 : preserve_subexpressions_p ()));
684 (define_insn "*subsi3_insn"
685 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
686 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
687 (match_operand:SI 2 "s_register_operand" "r,r")))]
692 [(set_attr "length" "4,16")])
695 [(set (match_operand:SI 0 "s_register_operand" "")
696 (minus:SI (match_operand:SI 1 "const_int_operand" "")
697 (match_operand:SI 2 "s_register_operand" "")))]
698 "! const_ok_for_arm (INTVAL (operands[1]))"
699 [(clobber (const_int 0))]
701 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
706 (define_insn "*subsi3_compare0"
707 [(set (reg:CC_NOOV 24)
708 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
709 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
711 (set (match_operand:SI 0 "s_register_operand" "=r,r")
712 (minus:SI (match_dup 1) (match_dup 2)))]
717 [(set_attr "conds" "set")])
719 (define_insn "decscc"
720 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
721 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
722 (match_operator:SI 2 "comparison_operator"
723 [(match_operand 3 "cc_register" "") (const_int 0)])))]
727 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
728 [(set_attr "conds" "use")
729 (set_attr "length" "*,8")])
731 (define_insn "subsf3"
732 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
733 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
734 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
739 [(set_attr "type" "farith")])
741 (define_insn "subdf3"
742 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
743 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
744 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
749 [(set_attr "type" "farith")])
751 (define_insn "*subdf_esfdf_df"
752 [(set (match_operand:DF 0 "s_register_operand" "=f")
753 (minus:DF (float_extend:DF
754 (match_operand:SF 1 "s_register_operand" "f"))
755 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
757 "suf%?d\\t%0, %1, %2"
758 [(set_attr "type" "farith")])
760 (define_insn "*subdf_df_esfdf"
761 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
762 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
764 (match_operand:SF 2 "s_register_operand" "f,f"))))]
769 [(set_attr "type" "farith")])
771 (define_insn "*subdf_esfdf_esfdf"
772 [(set (match_operand:DF 0 "s_register_operand" "=f")
773 (minus:DF (float_extend:DF
774 (match_operand:SF 1 "s_register_operand" "f"))
776 (match_operand:SF 2 "s_register_operand" "f"))))]
778 "suf%?d\\t%0, %1, %2"
779 [(set_attr "type" "farith")])
781 (define_insn "subxf3"
782 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
783 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
784 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
785 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
789 [(set_attr "type" "farith")])
791 ;; Multiplication insns
793 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
794 (define_insn "mulsi3"
795 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
796 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
797 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
800 [(set_attr "type" "mult")])
802 (define_insn "*mulsi3_compare0"
803 [(set (reg:CC_NOOV 24)
804 (compare:CC_NOOV (mult:SI
805 (match_operand:SI 2 "s_register_operand" "r,r")
806 (match_operand:SI 1 "s_register_operand" "%?r,0"))
808 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
809 (mult:SI (match_dup 2) (match_dup 1)))]
811 "mul%?s\\t%0, %2, %1"
812 [(set_attr "conds" "set")
813 (set_attr "type" "mult")])
815 (define_insn "*mulsi_compare0_scratch"
816 [(set (reg:CC_NOOV 24)
817 (compare:CC_NOOV (mult:SI
818 (match_operand:SI 2 "s_register_operand" "r,r")
819 (match_operand:SI 1 "s_register_operand" "%?r,0"))
821 (clobber (match_scratch:SI 0 "=&r,&r"))]
823 "mul%?s\\t%0, %2, %1"
824 [(set_attr "conds" "set")
825 (set_attr "type" "mult")])
827 ;; Unnamed templates to match MLA instruction.
829 (define_insn "*mulsi3addsi"
830 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
832 (mult:SI (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 "mla%?\\t%0, %2, %1, %3"
837 [(set_attr "type" "mult")])
839 (define_insn "*mulsi3addsi_compare0"
840 [(set (reg:CC_NOOV 24)
841 (compare:CC_NOOV (plus:SI
843 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
844 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
845 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
847 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
848 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
851 "mla%?s\\t%0, %2, %1, %3"
852 [(set_attr "conds" "set")
853 (set_attr "type" "mult")])
855 (define_insn "*mulsi3addsi_compare0_scratch"
856 [(set (reg:CC_NOOV 24)
857 (compare:CC_NOOV (plus:SI
859 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
860 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
861 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
863 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
865 "mla%?s\\t%0, %2, %1, %3"
866 [(set_attr "conds" "set")
867 (set_attr "type" "mult")])
869 (define_insn "mulsidi3"
870 [(set (match_operand:DI 0 "s_register_operand" "=&r")
871 (mult:DI (sign_extend:DI
872 (match_operand:SI 1 "s_register_operand" "%r"))
874 (match_operand:SI 2 "s_register_operand" "r"))))]
876 "smull%?\\t%Q0, %R0, %1, %2"
877 [(set_attr "type" "mult")])
879 (define_insn "umulsidi3"
880 [(set (match_operand:DI 0 "s_register_operand" "=&r")
881 (mult:DI (zero_extend:DI
882 (match_operand:SI 1 "s_register_operand" "%r"))
884 (match_operand:SI 2 "s_register_operand" "r"))))]
886 "umull%?\\t%Q0, %R0, %1, %2"
887 [(set_attr "type" "mult")])
889 (define_insn "smulsi3_highpart"
890 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
893 (mult:DI (sign_extend:DI
894 (match_operand:SI 1 "s_register_operand" "%r,0"))
896 (match_operand:SI 2 "s_register_operand" "r,r")))
898 (clobber (match_scratch:SI 3 "=&r,&r"))]
900 "smull%?\\t%3, %0, %2, %1"
901 [(set_attr "type" "mult")])
903 (define_insn "umulsi3_highpart"
904 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
907 (mult:DI (zero_extend:DI
908 (match_operand:SI 1 "s_register_operand" "%r,0"))
910 (match_operand:SI 2 "s_register_operand" "r,r")))
912 (clobber (match_scratch:SI 3 "=&r,&r"))]
914 "umull%?\\t%3, %0, %2, %1"
915 [(set_attr "type" "mult")])
917 (define_insn "mulsf3"
918 [(set (match_operand:SF 0 "s_register_operand" "=f")
919 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
920 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
922 "fml%?s\\t%0, %1, %2"
923 [(set_attr "type" "ffmul")])
925 (define_insn "muldf3"
926 [(set (match_operand:DF 0 "s_register_operand" "=f")
927 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
928 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
930 "muf%?d\\t%0, %1, %2"
931 [(set_attr "type" "fmul")])
933 (define_insn "*muldf_esfdf_df"
934 [(set (match_operand:DF 0 "s_register_operand" "=f")
935 (mult:DF (float_extend:DF
936 (match_operand:SF 1 "s_register_operand" "f"))
937 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
939 "muf%?d\\t%0, %1, %2"
940 [(set_attr "type" "fmul")])
942 (define_insn "*muldf_df_esfdf"
943 [(set (match_operand:DF 0 "s_register_operand" "=f")
944 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
946 (match_operand:SF 2 "s_register_operand" "f"))))]
948 "muf%?d\\t%0, %1, %2"
949 [(set_attr "type" "fmul")])
951 (define_insn "*muldf_esfdf_esfdf"
952 [(set (match_operand:DF 0 "s_register_operand" "=f")
953 (mult:DF (float_extend:DF
954 (match_operand:SF 1 "s_register_operand" "f"))
956 (match_operand:SF 2 "s_register_operand" "f"))))]
958 "muf%?d\\t%0, %1, %2"
959 [(set_attr "type" "fmul")])
961 (define_insn "mulxf3"
962 [(set (match_operand:XF 0 "s_register_operand" "=f")
963 (mult:XF (match_operand:XF 1 "s_register_operand" "f")
964 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
965 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
966 "muf%?e\\t%0, %1, %2"
967 [(set_attr "type" "fmul")])
971 (define_insn "divsf3"
972 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
973 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
974 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
979 [(set_attr "type" "fdivs")])
981 (define_insn "divdf3"
982 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
983 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
984 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
989 [(set_attr "type" "fdivd")])
991 (define_insn "*divdf_esfdf_df"
992 [(set (match_operand:DF 0 "s_register_operand" "=f")
993 (div:DF (float_extend:DF
994 (match_operand:SF 1 "s_register_operand" "f"))
995 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
997 "dvf%?d\\t%0, %1, %2"
998 [(set_attr "type" "fdivd")])
1000 (define_insn "*divdf_df_esfdf"
1001 [(set (match_operand:DF 0 "s_register_operand" "=f")
1002 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
1004 (match_operand:SF 2 "s_register_operand" "f"))))]
1006 "rdf%?d\\t%0, %2, %1"
1007 [(set_attr "type" "fdivd")])
1009 (define_insn "*divdf_esfdf_esfdf"
1010 [(set (match_operand:DF 0 "s_register_operand" "=f")
1011 (div:DF (float_extend:DF
1012 (match_operand:SF 1 "s_register_operand" "f"))
1014 (match_operand:SF 2 "s_register_operand" "f"))))]
1016 "dvf%?d\\t%0, %1, %2"
1017 [(set_attr "type" "fdivd")])
1019 (define_insn "divxf3"
1020 [(set (match_operand:XF 0 "s_register_operand" "=f,f")
1021 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
1022 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
1023 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1026 rdf%?e\\t%0, %2, %1"
1027 [(set_attr "type" "fdivx")])
1031 (define_insn "modsf3"
1032 [(set (match_operand:SF 0 "s_register_operand" "=f")
1033 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
1034 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
1036 "rmf%?s\\t%0, %1, %2"
1037 [(set_attr "type" "fdivs")])
1039 (define_insn "moddf3"
1040 [(set (match_operand:DF 0 "s_register_operand" "=f")
1041 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
1042 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1044 "rmf%?d\\t%0, %1, %2"
1045 [(set_attr "type" "fdivd")])
1047 (define_insn "*moddf_esfdf_df"
1048 [(set (match_operand:DF 0 "s_register_operand" "=f")
1049 (mod:DF (float_extend:DF
1050 (match_operand:SF 1 "s_register_operand" "f"))
1051 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
1053 "rmf%?d\\t%0, %1, %2"
1054 [(set_attr "type" "fdivd")])
1056 (define_insn "*moddf_df_esfdf"
1057 [(set (match_operand:DF 0 "s_register_operand" "=f")
1058 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
1060 (match_operand:SF 2 "s_register_operand" "f"))))]
1062 "rmf%?d\\t%0, %1, %2"
1063 [(set_attr "type" "fdivd")])
1065 (define_insn "*moddf_esfdf_esfdf"
1066 [(set (match_operand:DF 0 "s_register_operand" "=f")
1067 (mod:DF (float_extend:DF
1068 (match_operand:SF 1 "s_register_operand" "f"))
1070 (match_operand:SF 2 "s_register_operand" "f"))))]
1072 "rmf%?d\\t%0, %1, %2"
1073 [(set_attr "type" "fdivd")])
1075 (define_insn "modxf3"
1076 [(set (match_operand:XF 0 "s_register_operand" "=f")
1077 (mod:XF (match_operand:XF 1 "s_register_operand" "f")
1078 (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
1079 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1080 "rmf%?e\\t%0, %1, %2"
1081 [(set_attr "type" "fdivx")])
1083 ;; Boolean and,ior,xor insns
1085 (define_insn "anddi3"
1086 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1087 (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1088 (match_operand:DI 2 "s_register_operand" "r,0")))]
1090 "and%?\\t%Q0, %Q1, %Q2\;and%?\\t%R0, %R1, %R2"
1091 [(set_attr "length" "8")])
1093 (define_insn "*anddi_zesidi_di"
1094 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1095 (and:DI (zero_extend:DI
1096 (match_operand:SI 2 "s_register_operand" "r,r"))
1097 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1099 "and%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, #0"
1100 [(set_attr "length" "8")])
1102 (define_insn "*anddi_sesdi_di"
1103 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1104 (and:DI (sign_extend:DI
1105 (match_operand:SI 2 "s_register_operand" "r,r"))
1106 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1108 "and%?\\t%Q0, %Q1, %2\;and%?\\t%R0, %R1, %2, asr #31"
1109 [(set_attr "length" "8")])
1111 (define_expand "andsi3"
1112 [(set (match_operand:SI 0 "s_register_operand" "")
1113 (and:SI (match_operand:SI 1 "s_register_operand" "")
1114 (match_operand:SI 2 "reg_or_int_operand" "")))]
1117 if (GET_CODE (operands[2]) == CONST_INT)
1119 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1121 (reload_in_progress || reload_completed
1122 ? 0 : preserve_subexpressions_p ()));
1127 (define_insn "*andsi3_insn"
1128 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1129 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1130 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1134 bic%?\\t%0, %1, #%B2
1136 [(set_attr "length" "4,4,16")])
1139 [(set (match_operand:SI 0 "s_register_operand" "")
1140 (and:SI (match_operand:SI 1 "s_register_operand" "")
1141 (match_operand:SI 2 "const_int_operand" "")))]
1142 "! (const_ok_for_arm (INTVAL (operands[2]))
1143 || const_ok_for_arm (~ INTVAL (operands[2])))"
1144 [(clobber (const_int 0))]
1146 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1151 (define_insn "*andsi3_compare0"
1152 [(set (reg:CC_NOOV 24)
1154 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1155 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1157 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1158 (and:SI (match_dup 1) (match_dup 2)))]
1162 bic%?s\\t%0, %1, #%B2"
1163 [(set_attr "conds" "set")])
1165 (define_insn "*andsi3_compare0_scratch"
1166 [(set (reg:CC_NOOV 24)
1168 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1169 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1171 (clobber (match_scratch:SI 3 "=X,r"))]
1175 bic%?s\\t%3, %0, #%B1"
1176 [(set_attr "conds" "set")])
1178 (define_insn "*zeroextractsi_compare0_scratch"
1179 [(set (reg:CC_NOOV 24)
1180 (compare:CC_NOOV (zero_extract:SI
1181 (match_operand:SI 0 "s_register_operand" "r")
1182 (match_operand 1 "const_int_operand" "n")
1183 (match_operand 2 "const_int_operand" "n"))
1185 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1186 && INTVAL (operands[1]) > 0
1187 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1188 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
1190 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1191 << INTVAL (operands[2]));
1192 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1195 [(set_attr "conds" "set")])
1197 (define_insn "*zeroextractqi_compare0_scratch"
1198 [(set (reg:CC_NOOV 24)
1199 (compare:CC_NOOV (zero_extract:SI
1200 (match_operand:QI 0 "memory_operand" "m")
1201 (match_operand 1 "const_int_operand" "n")
1202 (match_operand 2 "const_int_operand" "n"))
1204 (clobber (match_scratch:QI 3 "=r"))]
1205 "INTVAL (operands[2]) >= 0 && INTVAL (operands[1]) > 0
1206 && ((INTVAL (operands[2]) + INTVAL (operands[1])) <= 8)"
1208 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1209 << INTVAL (operands[2]));
1210 output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
1211 output_asm_insn (\"tst%?\\t%3, %1\", operands);
1214 [(set_attr "conds" "set")
1215 (set_attr "length" "8")])
1217 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1218 ;;; represented by the bitfield, then this will produce incorrect results.
1219 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1220 ;;; which have a real bitfield insert instruction, the truncation happens
1221 ;;; in the bitfield insert instruction itself. Since arm does not have a
1222 ;;; bitfield insert instruction, we would have to emit code here to truncate
1223 ;;; the value before we insert. This loses some of the advantage of having
1224 ;;; this insv pattern, so this pattern needs to be reevalutated.
1226 (define_expand "insv"
1227 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1228 (match_operand:SI 1 "general_operand" "")
1229 (match_operand:SI 2 "general_operand" ""))
1230 (match_operand:SI 3 "nonmemory_operand" ""))]
1234 int start_bit = INTVAL (operands[2]);
1235 int width = INTVAL (operands[1]);
1236 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1237 rtx target, subtarget;
1239 target = operands[0];
1240 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1241 subreg as the final target. */
1242 if (GET_CODE (target) == SUBREG)
1244 subtarget = gen_reg_rtx (SImode);
1245 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1246 < GET_MODE_SIZE (SImode))
1247 target = SUBREG_REG (target);
1252 if (GET_CODE (operands[3]) == CONST_INT)
1254 /* Since we are inserting a known constant, we may be able to
1255 reduce the number of bits that we have to clear so that
1256 the mask becomes simple. */
1257 /* ??? This code does not check to see if the new mask is actually
1258 simpler. It may not be. */
1259 rtx op1 = gen_reg_rtx (SImode);
1260 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1261 start of this pattern. */
1262 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1263 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1265 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1266 emit_insn (gen_iorsi3 (subtarget, op1,
1267 GEN_INT (op3_value << start_bit)));
1269 else if (start_bit == 0
1270 && ! (const_ok_for_arm (mask)
1271 || const_ok_for_arm (~mask)))
1273 /* A Trick, since we are setting the bottom bits in the word,
1274 we can shift operand[3] up, operand[0] down, OR them together
1275 and rotate the result back again. This takes 3 insns, and
1276 the third might be mergable into another op. */
1277 /* The shift up copes with the possibility that operand[3] is
1278 wider than the bitfield. */
1279 rtx op0 = gen_reg_rtx (SImode);
1280 rtx op1 = gen_reg_rtx (SImode);
1282 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1283 emit_insn (gen_iorsi3 (op1, gen_rtx_LSHIFTRT (SImode, operands[0],
1286 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1288 else if ((width + start_bit == 32)
1289 && ! (const_ok_for_arm (mask)
1290 || const_ok_for_arm (~mask)))
1292 /* Similar trick, but slightly less efficient. */
1294 rtx op0 = gen_reg_rtx (SImode);
1295 rtx op1 = gen_reg_rtx (SImode);
1297 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1298 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1299 emit_insn (gen_iorsi3 (subtarget,
1300 gen_rtx_LSHIFTRT (SImode, op1, operands[1]),
1305 rtx op0 = GEN_INT (mask);
1306 rtx op1 = gen_reg_rtx (SImode);
1307 rtx op2 = gen_reg_rtx (SImode);
1309 if (! (const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1311 rtx tmp = gen_reg_rtx (SImode);
1313 emit_insn (gen_movsi (tmp, op0));
1317 /* Mask out any bits in operand[3] that are not needed. */
1318 emit_insn (gen_andsi3 (op1, operands[3], op0));
1320 if (GET_CODE (op0) == CONST_INT
1321 && (const_ok_for_arm (mask << start_bit)
1322 || const_ok_for_arm (~ (mask << start_bit))))
1324 op0 = GEN_INT (~(mask << start_bit));
1325 emit_insn (gen_andsi3 (op2, operands[0], op0));
1329 if (GET_CODE (op0) == CONST_INT)
1331 rtx tmp = gen_reg_rtx (SImode);
1333 emit_insn (gen_movsi (tmp, op0));
1338 op0 = gen_rtx_ASHIFT (SImode, op0, operands[2]);
1340 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1344 op1 = gen_rtx_ASHIFT (SImode, op1, operands[2]);
1346 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1349 if (subtarget != target)
1351 /* If TARGET is still a SUBREG, then it must be wider than a word,
1352 so we must be careful only to set the subword we were asked to. */
1353 if (GET_CODE (target) == SUBREG)
1354 emit_move_insn (target, subtarget);
1356 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1363 ;; constants for op 2 will never be given to these patterns.
1364 (define_insn "*anddi_notdi_di"
1365 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1366 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
1367 (match_operand:DI 1 "s_register_operand" "0,r")))]
1369 "bic%?\\t%Q0, %Q1, %Q2\;bic%?\\t%R0, %R1, %R2"
1370 [(set_attr "length" "8")])
1372 (define_insn "*anddi_notzesidi_di"
1373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1374 (and:DI (not:DI (zero_extend:DI
1375 (match_operand:SI 2 "s_register_operand" "r,r")))
1376 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1379 bic%?\\t%Q0, %Q1, %2
1380 bic%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1381 [(set_attr "length" "4,8")])
1383 (define_insn "*anddi_notsesidi_di"
1384 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1385 (and:DI (not:DI (sign_extend:DI
1386 (match_operand:SI 2 "s_register_operand" "r,r")))
1387 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1389 "bic%?\\t%Q0, %Q1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
1390 [(set_attr "length" "8")])
1392 (define_insn "andsi_notsi_si"
1393 [(set (match_operand:SI 0 "s_register_operand" "=r")
1394 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1395 (match_operand:SI 1 "s_register_operand" "r")))]
1397 "bic%?\\t%0, %1, %2")
1399 (define_insn "andsi_not_shiftsi_si"
1400 [(set (match_operand:SI 0 "s_register_operand" "=r")
1401 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
1402 [(match_operand:SI 2 "s_register_operand" "r")
1403 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
1404 (match_operand:SI 1 "s_register_operand" "r")))]
1406 "bic%?\\t%0, %1, %2%S4")
1408 (define_insn "*andsi_notsi_si_compare0"
1409 [(set (reg:CC_NOOV 24)
1411 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1412 (match_operand:SI 1 "s_register_operand" "r"))
1414 (set (match_operand:SI 0 "s_register_operand" "=r")
1415 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
1417 "bic%?s\\t%0, %1, %2"
1418 [(set_attr "conds" "set")])
1420 (define_insn "*andsi_notsi_si_compare0_scratch"
1421 [(set (reg:CC_NOOV 24)
1423 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1424 (match_operand:SI 1 "s_register_operand" "r"))
1426 (clobber (match_scratch:SI 0 "=r"))]
1428 "bic%?s\\t%0, %1, %2"
1429 [(set_attr "conds" "set")])
1431 (define_insn "iordi3"
1432 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1433 (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
1434 (match_operand:DI 2 "s_register_operand" "r")))]
1436 "orr%?\\t%Q0, %Q1, %Q2\;orr%?\\t%R0, %R1, %R2"
1437 [(set_attr "length" "8")])
1439 (define_insn "*iordi_zesidi_di"
1440 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1441 (ior:DI (zero_extend:DI
1442 (match_operand:SI 2 "s_register_operand" "r,r"))
1443 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1446 orr%?\\t%Q0, %Q1, %2
1447 orr%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1448 [(set_attr "length" "4,8")])
1450 (define_insn "*iordi_sesidi_di"
1451 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1452 (ior:DI (sign_extend:DI
1453 (match_operand:SI 2 "s_register_operand" "r,r"))
1454 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1456 "orr%?\\t%Q0, %Q1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
1457 [(set_attr "length" "8")])
1459 (define_expand "iorsi3"
1460 [(set (match_operand:SI 0 "s_register_operand" "")
1461 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1462 (match_operand:SI 2 "reg_or_int_operand" "")))]
1465 if (GET_CODE (operands[2]) == CONST_INT)
1467 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1469 (reload_in_progress || reload_completed
1470 ? 0 : preserve_subexpressions_p ()));
1475 (define_insn "*iorsi3_insn"
1476 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1477 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
1478 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
1483 [(set_attr "length" "4,16")])
1486 [(set (match_operand:SI 0 "s_register_operand" "")
1487 (ior:SI (match_operand:SI 1 "s_register_operand" "")
1488 (match_operand:SI 2 "const_int_operand" "")))]
1489 "! const_ok_for_arm (INTVAL (operands[2]))"
1490 [(clobber (const_int 0))]
1492 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
1497 (define_insn "*iorsi3_compare0"
1498 [(set (reg:CC_NOOV 24)
1499 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1500 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1502 (set (match_operand:SI 0 "s_register_operand" "=r")
1503 (ior:SI (match_dup 1) (match_dup 2)))]
1505 "orr%?s\\t%0, %1, %2"
1506 [(set_attr "conds" "set")])
1508 (define_insn "*iorsi3_compare0_scratch"
1509 [(set (reg:CC_NOOV 24)
1510 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
1511 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1513 (clobber (match_scratch:SI 0 "=r"))]
1515 "orr%?s\\t%0, %1, %2"
1516 [(set_attr "conds" "set")])
1518 (define_insn "xordi3"
1519 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1520 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
1521 (match_operand:DI 2 "s_register_operand" "r,0")))]
1523 "eor%?\\t%Q0, %Q1, %Q2\;eor%?\\t%R0, %R1, %R2"
1524 [(set_attr "length" "8")])
1526 (define_insn "*xordi_zesidi_di"
1527 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1528 (xor:DI (zero_extend:DI
1529 (match_operand:SI 2 "s_register_operand" "r,r"))
1530 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1533 eor%?\\t%Q0, %Q1, %2
1534 eor%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
1535 [(set_attr "length" "4,8")])
1537 (define_insn "*xordi_sesidi_di"
1538 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1539 (xor:DI (sign_extend:DI
1540 (match_operand:SI 2 "s_register_operand" "r,r"))
1541 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1543 "eor%?\\t%Q0, %Q1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
1544 [(set_attr "length" "8")])
1546 (define_insn "xorsi3"
1547 [(set (match_operand:SI 0 "s_register_operand" "=r")
1548 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1549 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
1551 "eor%?\\t%0, %1, %2")
1553 (define_insn "*xorsi3_compare0"
1554 [(set (reg:CC_NOOV 24)
1555 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
1556 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1558 (set (match_operand:SI 0 "s_register_operand" "=r")
1559 (xor:SI (match_dup 1) (match_dup 2)))]
1561 "eor%?s\\t%0, %1, %2"
1562 [(set_attr "conds" "set")])
1564 (define_insn "*xorsi3_compare0_scratch"
1565 [(set (reg:CC_NOOV 24)
1566 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
1567 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1571 [(set_attr "conds" "set")])
1573 ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
1574 ;; (NOT D) we can sometimes merge the final NOT into one of the following
1578 [(set (match_operand:SI 0 "s_register_operand" "=r")
1579 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
1580 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
1581 (match_operand:SI 3 "arm_rhs_operand" "rI")))
1582 (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
1584 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
1585 (not:SI (match_dup 3))))
1586 (set (match_dup 0) (not:SI (match_dup 4)))]
1590 (define_insn "*andsi_iorsi3_notsi"
1591 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
1592 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
1593 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
1594 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
1596 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
1597 [(set_attr "length" "8")])
1601 ;; Minimum and maximum insns
1603 (define_insn "smaxsi3"
1604 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1605 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1606 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1607 (clobber (reg:CC 24))]
1610 cmp\\t%1, %2\;movlt\\t%0, %2
1611 cmp\\t%1, %2\;movge\\t%0, %1
1612 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
1613 [(set_attr "conds" "clob")
1614 (set_attr "length" "8,8,12")])
1616 (define_insn "sminsi3"
1617 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1618 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1619 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1620 (clobber (reg:CC 24))]
1623 cmp\\t%1, %2\;movge\\t%0, %2
1624 cmp\\t%1, %2\;movlt\\t%0, %1
1625 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
1626 [(set_attr "conds" "clob")
1627 (set_attr "length" "8,8,12")])
1629 (define_insn "umaxsi3"
1630 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1631 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1632 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1633 (clobber (reg:CC 24))]
1636 cmp\\t%1, %2\;movcc\\t%0, %2
1637 cmp\\t%1, %2\;movcs\\t%0, %1
1638 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
1639 [(set_attr "conds" "clob")
1640 (set_attr "length" "8,8,12")])
1642 (define_insn "uminsi3"
1643 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1644 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
1645 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
1646 (clobber (reg:CC 24))]
1649 cmp\\t%1, %2\;movcs\\t%0, %2
1650 cmp\\t%1, %2\;movcc\\t%0, %1
1651 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
1652 [(set_attr "conds" "clob")
1653 (set_attr "length" "8,8,12")])
1655 (define_insn "*store_minmaxsi"
1656 [(set (match_operand:SI 0 "memory_operand" "=m")
1657 (match_operator:SI 3 "minmax_operator"
1658 [(match_operand:SI 1 "s_register_operand" "r")
1659 (match_operand:SI 2 "s_register_operand" "r")]))
1660 (clobber (reg:CC 24))]
1663 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
1665 output_asm_insn (\"cmp\\t%1, %2\", operands);
1666 output_asm_insn (\"str%d3\\t%1, %0\", operands);
1667 output_asm_insn (\"str%D3\\t%2, %0\", operands);
1670 [(set_attr "conds" "clob")
1671 (set_attr "length" "12")
1672 (set_attr "type" "store1")])
1674 ; Reject the frame pointer in operand[1], since reloading this after
1675 ; it has been eliminated can cause carnage.
1676 (define_insn "*minmax_arithsi"
1677 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1678 (match_operator:SI 4 "shiftable_operator"
1679 [(match_operator:SI 5 "minmax_operator"
1680 [(match_operand:SI 2 "s_register_operand" "r,r")
1681 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
1682 (match_operand:SI 1 "s_register_operand" "0,?r")]))
1683 (clobber (reg:CC 24))]
1684 "GET_CODE (operands[1]) != REG
1685 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
1686 && REGNO(operands[1]) != ARG_POINTER_REGNUM)"
1689 enum rtx_code code = GET_CODE (operands[4]);
1691 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
1693 output_asm_insn (\"cmp\\t%2, %3\", operands);
1694 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
1695 if (which_alternative != 0 || operands[3] != const0_rtx
1696 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
1697 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
1701 [(set_attr "conds" "clob")
1702 (set_attr "length" "12")])
1705 ;; Shift and rotation insns
1707 (define_expand "ashlsi3"
1708 [(set (match_operand:SI 0 "s_register_operand" "")
1709 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
1710 (match_operand:SI 2 "arm_rhs_operand" "")))]
1713 if (GET_CODE (operands[2]) == CONST_INT
1714 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1716 emit_insn (gen_movsi (operands[0], const0_rtx));
1721 (define_expand "ashrsi3"
1722 [(set (match_operand:SI 0 "s_register_operand" "")
1723 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
1724 (match_operand:SI 2 "arm_rhs_operand" "")))]
1727 if (GET_CODE (operands[2]) == CONST_INT
1728 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1729 operands[2] = GEN_INT (31);
1732 (define_expand "lshrsi3"
1733 [(set (match_operand:SI 0 "s_register_operand" "")
1734 (lshiftrt: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)
1741 emit_insn (gen_movsi (operands[0], const0_rtx));
1746 (define_expand "rotlsi3"
1747 [(set (match_operand:SI 0 "s_register_operand" "")
1748 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1749 (match_operand:SI 2 "reg_or_int_operand" "")))]
1752 if (GET_CODE (operands[2]) == CONST_INT)
1753 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
1756 rtx reg = gen_reg_rtx (SImode);
1757 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
1762 (define_expand "rotrsi3"
1763 [(set (match_operand:SI 0 "s_register_operand" "")
1764 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
1765 (match_operand:SI 2 "arm_rhs_operand" "")))]
1768 if (GET_CODE (operands[2]) == CONST_INT
1769 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
1770 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
1773 (define_insn "*shiftsi3"
1774 [(set (match_operand:SI 0 "s_register_operand" "=r")
1775 (match_operator:SI 3 "shift_operator"
1776 [(match_operand:SI 1 "s_register_operand" "r")
1777 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
1779 "mov%?\\t%0, %1%S3")
1781 (define_insn "*shiftsi3_compare0"
1782 [(set (reg:CC_NOOV 24)
1783 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1784 [(match_operand:SI 1 "s_register_operand" "r")
1785 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1787 (set (match_operand:SI 0 "s_register_operand" "=r")
1788 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
1790 "mov%?s\\t%0, %1%S3"
1791 [(set_attr "conds" "set")])
1793 (define_insn "*shiftsi3_compare0_scratch"
1794 [(set (reg:CC_NOOV 24)
1795 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
1796 [(match_operand:SI 1 "s_register_operand" "r")
1797 (match_operand:SI 2 "arm_rhs_operand" "rM")])
1799 (clobber (match_scratch:SI 0 "=r"))]
1801 "mov%?s\\t%0, %1%S3"
1802 [(set_attr "conds" "set")])
1804 (define_insn "*notsi_shiftsi"
1805 [(set (match_operand:SI 0 "s_register_operand" "=r")
1806 (not:SI (match_operator:SI 3 "shift_operator"
1807 [(match_operand:SI 1 "s_register_operand" "r")
1808 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
1810 "mvn%?\\t%0, %1%S3")
1812 (define_insn "*notsi_shiftsi_compare0"
1813 [(set (reg:CC_NOOV 24)
1814 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1815 [(match_operand:SI 1 "s_register_operand" "r")
1816 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1818 (set (match_operand:SI 0 "s_register_operand" "=r")
1819 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
1821 "mvn%?s\\t%0, %1%S3"
1822 [(set_attr "conds" "set")])
1824 (define_insn "*not_shiftsi_compare0_scratch"
1825 [(set (reg:CC_NOOV 24)
1826 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
1827 [(match_operand:SI 1 "s_register_operand" "r")
1828 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
1830 (clobber (match_scratch:SI 0 "=r"))]
1832 "mvn%?s\\t%0, %1%S3"
1833 [(set_attr "conds" "set")])
1836 ;; Unary arithmetic insns
1838 (define_insn "negdi2"
1839 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1840 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
1842 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
1843 [(set_attr "conds" "clob")
1844 (set_attr "length" "8")])
1846 (define_insn "negsi2"
1847 [(set (match_operand:SI 0 "s_register_operand" "=r")
1848 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
1850 "rsb%?\\t%0, %1, #0")
1852 (define_insn "negsf2"
1853 [(set (match_operand:SF 0 "s_register_operand" "=f")
1854 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
1857 [(set_attr "type" "ffarith")])
1859 (define_insn "negdf2"
1860 [(set (match_operand:DF 0 "s_register_operand" "=f")
1861 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
1864 [(set_attr "type" "ffarith")])
1866 (define_insn "*negdf_esfdf"
1867 [(set (match_operand:DF 0 "s_register_operand" "=f")
1868 (neg:DF (float_extend:DF
1869 (match_operand:SF 1 "s_register_operand" "f"))))]
1872 [(set_attr "type" "ffarith")])
1874 (define_insn "negxf2"
1875 [(set (match_operand:XF 0 "s_register_operand" "=f")
1876 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
1877 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1879 [(set_attr "type" "ffarith")])
1881 ;; abssi2 doesn't really clobber the condition codes if a different register
1882 ;; is being set. To keep things simple, assume during rtl manipulations that
1883 ;; it does, but tell the final scan operator the truth. Similarly for
1886 (define_insn "abssi2"
1887 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1888 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
1889 (clobber (reg:CC 24))]
1892 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
1893 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
1894 [(set_attr "conds" "clob,*")
1895 (set_attr "length" "8")])
1897 (define_insn "*neg_abssi2"
1898 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1899 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
1900 (clobber (reg:CC 24))]
1903 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
1904 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
1905 [(set_attr "conds" "clob,*")
1906 (set_attr "length" "8")])
1908 (define_insn "abssf2"
1909 [(set (match_operand:SF 0 "s_register_operand" "=f")
1910 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
1913 [(set_attr "type" "ffarith")])
1915 (define_insn "absdf2"
1916 [(set (match_operand:DF 0 "s_register_operand" "=f")
1917 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
1920 [(set_attr "type" "ffarith")])
1922 (define_insn "*absdf_esfdf"
1923 [(set (match_operand:DF 0 "s_register_operand" "=f")
1924 (abs:DF (float_extend:DF
1925 (match_operand:SF 1 "s_register_operand" "f"))))]
1928 [(set_attr "type" "ffarith")])
1930 (define_insn "absxf2"
1931 [(set (match_operand:XF 0 "s_register_operand" "=f")
1932 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
1933 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1935 [(set_attr "type" "ffarith")])
1937 (define_insn "sqrtsf2"
1938 [(set (match_operand:SF 0 "s_register_operand" "=f")
1939 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
1942 [(set_attr "type" "float_em")])
1944 (define_insn "sqrtdf2"
1945 [(set (match_operand:DF 0 "s_register_operand" "=f")
1946 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
1949 [(set_attr "type" "float_em")])
1951 (define_insn "*sqrtdf_esfdf"
1952 [(set (match_operand:DF 0 "s_register_operand" "=f")
1953 (sqrt:DF (float_extend:DF
1954 (match_operand:SF 1 "s_register_operand" "f"))))]
1957 [(set_attr "type" "float_em")])
1959 (define_insn "sqrtxf2"
1960 [(set (match_operand:XF 0 "s_register_operand" "=f")
1961 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
1962 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1964 [(set_attr "type" "float_em")])
1966 ;; SIN COS TAN and family are always emulated, so it's probably better
1967 ;; to always call a library function.
1968 ;(define_insn "sinsf2"
1969 ; [(set (match_operand:SF 0 "s_register_operand" "=f")
1970 ; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
1971 ; "TARGET_HARD_FLOAT"
1973 ;[(set_attr "type" "float_em")])
1975 ;(define_insn "sindf2"
1976 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1977 ; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
1978 ; "TARGET_HARD_FLOAT"
1980 ;[(set_attr "type" "float_em")])
1982 ;(define_insn "*sindf_esfdf"
1983 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
1984 ; (unspec:DF [(float_extend:DF
1985 ; (match_operand:SF 1 "s_register_operand" "f"))] 0))]
1986 ; "TARGET_HARD_FLOAT"
1988 ;[(set_attr "type" "float_em")])
1990 ;(define_insn "sinxf2"
1991 ; [(set (match_operand:XF 0 "s_register_operand" "=f")
1992 ; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
1993 ; "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
1995 ;[(set_attr "type" "float_em")])
1997 ;(define_insn "cossf2"
1998 ; [(set (match_operand:SF 0 "s_register_operand" "=f")
1999 ; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
2000 ; "TARGET_HARD_FLOAT"
2002 ;[(set_attr "type" "float_em")])
2004 ;(define_insn "cosdf2"
2005 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
2006 ; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
2007 ; "TARGET_HARD_FLOAT"
2009 ;[(set_attr "type" "float_em")])
2011 ;(define_insn "*cosdf_esfdf"
2012 ; [(set (match_operand:DF 0 "s_register_operand" "=f")
2013 ; (unspec:DF [(float_extend:DF
2014 ; (match_operand:SF 1 "s_register_operand" "f"))] 1))]
2015 ; "TARGET_HARD_FLOAT"
2017 ;[(set_attr "type" "float_em")])
2019 ;(define_insn "cosxf2"
2020 ; [(set (match_operand:XF 0 "s_register_operand" "=f")
2021 ; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
2022 ; "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2024 ;[(set_attr "type" "float_em")])
2026 (define_insn "one_cmpldi2"
2027 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2028 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
2030 "mvn%?\\t%Q0, %Q1\;mvn%?\\t%R0, %R1"
2031 [(set_attr "length" "8")])
2033 (define_insn "one_cmplsi2"
2034 [(set (match_operand:SI 0 "s_register_operand" "=r")
2035 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
2039 (define_insn "*notsi_compare0"
2040 [(set (reg:CC_NOOV 24)
2041 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
2043 (set (match_operand:SI 0 "s_register_operand" "=r")
2044 (not:SI (match_dup 1)))]
2047 [(set_attr "conds" "set")])
2049 (define_insn "*notsi_compare0_scratch"
2050 [(set (reg:CC_NOOV 24)
2051 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
2053 (clobber (match_scratch:SI 0 "=r"))]
2056 [(set_attr "conds" "set")])
2058 ;; Fixed <--> Floating conversion insns
2060 (define_insn "floatsisf2"
2061 [(set (match_operand:SF 0 "s_register_operand" "=f")
2062 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
2065 [(set_attr "type" "r_2_f")])
2067 (define_insn "floatsidf2"
2068 [(set (match_operand:DF 0 "s_register_operand" "=f")
2069 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
2072 [(set_attr "type" "r_2_f")])
2074 (define_insn "floatsixf2"
2075 [(set (match_operand:XF 0 "s_register_operand" "=f")
2076 (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
2077 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2079 [(set_attr "type" "r_2_f")])
2081 (define_insn "fix_truncsfsi2"
2082 [(set (match_operand:SI 0 "s_register_operand" "=r")
2083 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
2086 [(set_attr "type" "f_2_r")])
2088 (define_insn "fix_truncdfsi2"
2089 [(set (match_operand:SI 0 "s_register_operand" "=r")
2090 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
2093 [(set_attr "type" "f_2_r")])
2095 (define_insn "fix_truncxfsi2"
2096 [(set (match_operand:SI 0 "s_register_operand" "=r")
2097 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
2098 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2100 [(set_attr "type" "f_2_r")])
2104 (define_insn "truncdfsf2"
2105 [(set (match_operand:SF 0 "s_register_operand" "=f")
2107 (match_operand:DF 1 "s_register_operand" "f")))]
2110 [(set_attr "type" "ffarith")])
2112 (define_insn "truncxfsf2"
2113 [(set (match_operand:SF 0 "s_register_operand" "=f")
2115 (match_operand:XF 1 "s_register_operand" "f")))]
2116 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2118 [(set_attr "type" "ffarith")])
2120 (define_insn "truncxfdf2"
2121 [(set (match_operand:DF 0 "s_register_operand" "=f")
2123 (match_operand:XF 1 "s_register_operand" "f")))]
2124 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2126 [(set_attr "type" "ffarith")])
2128 ;; Zero and sign extension instructions.
2130 (define_insn "zero_extendsidi2"
2131 [(set (match_operand:DI 0 "s_register_operand" "=r")
2132 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
2135 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
2136 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
2137 return \"mov%?\\t%R0, #0\";
2139 [(set_attr "length" "8")])
2141 (define_insn "zero_extendqidi2"
2142 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
2143 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2146 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
2147 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
2148 [(set_attr "length" "8")
2149 (set_attr "type" "*,load")])
2151 (define_insn "extendsidi2"
2152 [(set (match_operand:DI 0 "s_register_operand" "=r")
2153 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
2156 if (REGNO (operands[1]) != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
2157 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
2158 return \"mov%?\\t%R0, %Q0, asr #31\";
2160 [(set_attr "length" "8")])
2162 (define_expand "zero_extendhisi2"
2163 [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2165 (set (match_operand:SI 0 "s_register_operand" "")
2166 (lshiftrt:SI (match_dup 2) (const_int 16)))]
2170 if (GET_CODE (operands[1]) == MEM)
2172 if (TARGET_SHORT_BY_BYTES)
2174 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
2179 emit_insn (gen_rtx_SET (VOIDmode,
2181 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
2185 if (! s_register_operand (operands[1], HImode))
2186 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2187 operands[1] = gen_lowpart (SImode, operands[1]);
2188 operands[2] = gen_reg_rtx (SImode);
2191 (define_insn "*zero_extendhisi_insn"
2192 [(set (match_operand:SI 0 "s_register_operand" "=r")
2193 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2196 [(set_attr "type" "load")])
2199 [(set (match_operand:SI 0 "s_register_operand" "")
2200 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2201 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2203 [(set (match_dup 2) (match_dup 1))
2204 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
2207 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2212 [(set (match_operand:SI 0 "s_register_operand" "")
2213 (match_operator:SI 3 "shiftable_operator"
2214 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2215 (match_operand:SI 4 "s_register_operand" "")]))
2216 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2218 [(set (match_dup 2) (match_dup 1))
2221 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2224 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2228 (define_expand "zero_extendqisi2"
2229 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2231 (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2234 if (GET_CODE (operands[1]) != MEM)
2236 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
2242 (define_insn "*load_extendqisi"
2243 [(set (match_operand:SI 0 "s_register_operand" "=r")
2244 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2246 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
2247 [(set_attr "type" "load")])
2250 [(set (match_operand:SI 0 "s_register_operand" "")
2251 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
2252 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2253 "GET_CODE (operands[1]) != MEM"
2254 [(set (match_dup 2) (match_dup 1))
2255 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
2258 (define_insn "*compareqi_eq0"
2260 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
2264 [(set_attr "conds" "set")])
2266 (define_expand "extendhisi2"
2268 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
2270 (set (match_operand:SI 0 "s_register_operand" "")
2271 (ashiftrt:SI (match_dup 2)
2276 if (GET_CODE (operands[1]) == MEM)
2278 if (TARGET_SHORT_BY_BYTES)
2280 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
2285 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2286 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
2290 if (! s_register_operand (operands[1], HImode))
2291 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2292 operands[1] = gen_lowpart (SImode, operands[1]);
2293 operands[2] = gen_reg_rtx (SImode);
2296 (define_expand "extendhisi2_mem"
2297 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
2299 (zero_extend:SI (match_dup 7)))
2300 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
2301 (set (match_operand:SI 0 "" "")
2302 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
2307 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2309 mem1 = gen_rtx_MEM (QImode, addr);
2310 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
2311 RTX_UNCHANGING_P (mem1) = RTX_UNCHANGING_P (operands[1]);
2312 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
2313 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
2314 RTX_UNCHANGING_P (mem2) = RTX_UNCHANGING_P (operands[1]);
2315 operands[0] = gen_lowpart (SImode, operands[0]);
2317 operands[2] = gen_reg_rtx (SImode);
2318 operands[3] = gen_reg_rtx (SImode);
2319 operands[6] = gen_reg_rtx (SImode);
2322 if (BYTES_BIG_ENDIAN)
2324 operands[4] = operands[2];
2325 operands[5] = operands[3];
2329 operands[4] = operands[3];
2330 operands[5] = operands[2];
2335 (define_insn "*extendhisi_insn"
2336 [(set (match_operand:SI 0 "s_register_operand" "=r")
2337 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2340 [(set_attr "type" "load")])
2343 [(set (match_operand:SI 0 "s_register_operand" "")
2344 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
2345 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2347 [(set (match_dup 2) (match_dup 1))
2348 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
2351 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2356 [(set (match_operand:SI 0 "s_register_operand" "")
2357 (match_operator:SI 3 "shiftable_operator"
2358 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
2359 (match_operand:SI 4 "s_register_operand" "")]))
2360 (clobber (match_operand:SI 2 "s_register_operand" ""))]
2362 [(set (match_dup 2) (match_dup 1))
2365 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
2368 if ((operands[1] = gen_rotated_half_load (operands[1])) == NULL)
2372 (define_expand "extendqihi2"
2374 (ashift:SI (match_operand:QI 1 "general_operand" "")
2376 (set (match_operand:HI 0 "s_register_operand" "")
2377 (ashiftrt:SI (match_dup 2)
2382 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2384 emit_insn (gen_rtx_SET (VOIDmode,
2386 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
2389 if (! s_register_operand (operands[1], QImode))
2390 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2391 operands[0] = gen_lowpart (SImode, operands[0]);
2392 operands[1] = gen_lowpart (SImode, operands[1]);
2393 operands[2] = gen_reg_rtx (SImode);
2396 ; Rather than restricting all byte accesses to memory addresses that ldrsb
2397 ; can handle, we fix up the ones that ldrsb can't grok with a split.
2398 (define_insn "*extendqihi_insn"
2399 [(set (match_operand:HI 0 "s_register_operand" "=r")
2400 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2403 /* If the address is invalid, this will split the instruction into two. */
2404 if (bad_signed_byte_operand(operands[1], QImode))
2406 return \"ldr%?sb\\t%0, %1\";
2408 [(set_attr "type" "load")
2409 (set_attr "length" "8")])
2412 [(set (match_operand:HI 0 "s_register_operand" "")
2413 (sign_extend:HI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
2414 "arm_arch4 && reload_completed"
2415 [(set (match_dup 3) (match_dup 1))
2416 (set (match_dup 0) (sign_extend:HI (match_dup 2)))]
2419 HOST_WIDE_INT offset;
2421 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
2422 operands[2] = gen_rtx_MEM (QImode, operands[3]);
2423 MEM_COPY_ATTRIBUTES (operands[2], operands[1]);
2424 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
2425 operands[1] = XEXP (operands[1], 0);
2426 if (GET_CODE (operands[1]) == PLUS
2427 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2428 && ! (const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1)))
2429 || const_ok_for_arm (-offset)))
2431 HOST_WIDE_INT low = (offset > 0
2432 ? (offset & 0xff) : -((-offset) & 0xff));
2433 XEXP (operands[2], 0) = plus_constant (operands[3], low);
2434 operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
2436 /* Ensure the sum is in correct canonical form */
2437 else if (GET_CODE (operands[1]) == PLUS
2438 && GET_CODE (XEXP (operands[1], 1)) != CONST_INT
2439 && ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
2440 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
2441 XEXP (operands[1], 1),
2442 XEXP (operands[1], 0));
2446 (define_expand "extendqisi2"
2448 (ashift:SI (match_operand:QI 1 "general_operand" "")
2450 (set (match_operand:SI 0 "s_register_operand" "")
2451 (ashiftrt:SI (match_dup 2)
2456 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
2458 emit_insn (gen_rtx_SET (VOIDmode,
2460 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
2463 if (! s_register_operand (operands[1], QImode))
2464 operands[1] = copy_to_mode_reg (QImode, operands[1]);
2465 operands[1] = gen_lowpart (SImode, operands[1]);
2466 operands[2] = gen_reg_rtx (SImode);
2469 ; Rather than restricting all byte accesses to memory addresses that ldrsb
2470 ; can handle, we fix up the ones that ldrsb can't grok with a split.
2471 (define_insn "*extendqisi_insn"
2472 [(set (match_operand:SI 0 "s_register_operand" "=r")
2473 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2476 /* If the address is invalid, this will split the instruction into two. */
2477 if (bad_signed_byte_operand(operands[1], QImode))
2479 return \"ldr%?sb\\t%0, %1\";
2481 [(set_attr "type" "load")
2482 (set_attr "length" "8")])
2485 [(set (match_operand:SI 0 "s_register_operand" "")
2486 (sign_extend:SI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
2487 "arm_arch4 && reload_completed"
2488 [(set (match_dup 0) (match_dup 1))
2489 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2492 HOST_WIDE_INT offset;
2494 operands[2] = gen_rtx_MEM (QImode, operands[0]);
2495 MEM_COPY_ATTRIBUTES (operands[2], operands[1]);
2496 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
2497 operands[1] = XEXP (operands[1], 0);
2498 if (GET_CODE (operands[1]) == PLUS
2499 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2500 && ! (const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1)))
2501 || const_ok_for_arm (-offset)))
2503 HOST_WIDE_INT low = (offset > 0
2504 ? (offset & 0xff) : -((-offset) & 0xff));
2505 XEXP (operands[2], 0) = plus_constant (operands[0], low);
2506 operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
2508 /* Ensure the sum is in correct canonical form */
2509 else if (GET_CODE (operands[1]) == PLUS
2510 && GET_CODE (XEXP (operands[1], 1)) != CONST_INT
2511 && ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
2512 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
2513 XEXP (operands[1], 1),
2514 XEXP (operands[1], 0));
2518 (define_insn "extendsfdf2"
2519 [(set (match_operand:DF 0 "s_register_operand" "=f")
2520 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
2523 [(set_attr "type" "ffarith")])
2525 (define_insn "extendsfxf2"
2526 [(set (match_operand:XF 0 "s_register_operand" "=f")
2527 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
2528 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2530 [(set_attr "type" "ffarith")])
2532 (define_insn "extenddfxf2"
2533 [(set (match_operand:XF 0 "s_register_operand" "=f")
2534 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
2535 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
2537 [(set_attr "type" "ffarith")])
2540 ;; Move insns (including loads and stores)
2542 ;; XXX Just some ideas about movti.
2543 ;; I don't think these are a good idea on the arm, there just aren't enough
2545 ;;(define_expand "loadti"
2546 ;; [(set (match_operand:TI 0 "s_register_operand" "")
2547 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
2550 ;;(define_expand "storeti"
2551 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
2552 ;; (match_operand:TI 1 "s_register_operand" ""))]
2555 ;;(define_expand "movti"
2556 ;; [(set (match_operand:TI 0 "general_operand" "")
2557 ;; (match_operand:TI 1 "general_operand" ""))]
2563 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2564 ;; operands[1] = copy_to_reg (operands[1]);
2565 ;; if (GET_CODE (operands[0]) == MEM)
2566 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
2567 ;; else if (GET_CODE (operands[1]) == MEM)
2568 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
2572 ;; emit_insn (insn);
2576 ;; Recognise garbage generated above.
2579 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
2580 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
2584 ;; register mem = (which_alternative < 3);
2585 ;; register char *template;
2587 ;; operands[mem] = XEXP (operands[mem], 0);
2588 ;; switch (which_alternative)
2590 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
2591 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
2592 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
2593 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
2594 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
2595 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
2597 ;; output_asm_insn (template, operands);
2602 (define_insn "movdi"
2603 [(set (match_operand:DI 0 "di_operand" "=r,r,o<>")
2604 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
2607 return (output_move_double (operands));
2609 [(set_attr "length" "8,8,8")
2610 (set_attr "type" "*,load,store2")])
2612 (define_expand "movsi"
2613 [(set (match_operand:SI 0 "general_operand" "")
2614 (match_operand:SI 1 "general_operand" ""))]
2617 /* Everything except mem = const or mem = mem can be done easily */
2618 if (GET_CODE (operands[0]) == MEM)
2619 operands[1] = force_reg (SImode, operands[1]);
2620 if (GET_CODE (operands[1]) == CONST_INT
2621 && !(const_ok_for_arm (INTVAL (operands[1]))
2622 || const_ok_for_arm (~INTVAL (operands[1]))))
2624 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2626 (reload_in_progress || reload_completed ? 0
2627 : preserve_subexpressions_p ()));
2630 if (CONSTANT_P (operands[1]) && flag_pic)
2631 operands[1] = legitimize_pic_address (operands[1], SImode,
2632 ((reload_in_progress
2633 || reload_completed)
2634 ? operands[0] : 0));
2637 (define_insn "*movsi_insn"
2638 [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
2639 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
2640 "register_operand (operands[0], SImode)
2641 || register_operand (operands[1], SImode)"
2647 [(set_attr "type" "*,*,load,store1")])
2650 [(set (match_operand:SI 0 "s_register_operand" "")
2651 (match_operand:SI 1 "const_int_operand" ""))]
2652 "! (const_ok_for_arm (INTVAL (operands[1]))
2653 || const_ok_for_arm (~INTVAL (operands[1])))"
2654 [(clobber (const_int 0))]
2656 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
2661 (define_expand "movaddr"
2662 [(set (match_operand:SI 0 "s_register_operand" "")
2663 (match_operand:DI 1 "address_operand" ""))]
2667 (define_insn "*movaddr_insn"
2668 [(set (match_operand:SI 0 "s_register_operand" "=r")
2669 (match_operand:DI 1 "address_operand" "p"))]
2671 && (GET_CODE (operands[1]) == LABEL_REF
2672 || (GET_CODE (operands[1]) == CONST
2673 && GET_CODE (XEXP (operands[1], 0)) == PLUS
2674 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2675 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))"
2678 /* When generating pic, we need to load the symbol offset into a register.
2679 So that the optimizer does not confuse this with a normal symbol load
2680 we use an unspec. The offset will be loaded from a constant pool entry,
2681 since that is the only type of relocation we can use. */
2683 (define_insn "pic_load_addr"
2684 [(set (match_operand:SI 0 "s_register_operand" "=r")
2685 (unspec:SI [(match_operand 1 "" "")] 3))]
2688 [(set_attr "type" "load")])
2690 ;; This variant is used for AOF assembly, since it needs to mention the
2691 ;; pic register in the rtl.
2692 (define_expand "pic_load_addr_based"
2693 [(set (match_operand:SI 0 "s_register_operand" "=r")
2694 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] 3))]
2696 "operands[2] = pic_offset_table_rtx;")
2698 (define_insn "*pic_load_addr_based_insn"
2699 [(set (match_operand:SI 0 "s_register_operand" "=r")
2700 (unspec:SI [(match_operand 1 "" "")
2701 (match_operand 2 "s_register_operand" "r")] 3))]
2702 "flag_pic && operands[2] == pic_offset_table_rtx"
2704 #ifdef AOF_ASSEMBLER
2705 operands[1] = aof_pic_entry (operands[1]);
2707 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
2709 " [(set_attr "type" "load")])
2711 (define_insn "pic_add_dot_plus_eight"
2712 [(set (pc) (label_ref (match_operand 0 "" "")))
2713 (set (match_operand 1 "register_operand" "+r")
2714 (plus:SI (match_dup 1) (const (plus:SI (pc) (const_int 8)))))]
2716 "add%?\\t%1, %|pc, %1")
2718 ;; If copying one reg to another we can set the condition codes according to
2719 ;; its value. Such a move is common after a return from subroutine and the
2720 ;; result is being tested against zero.
2722 (define_insn "*movsi_compare0"
2723 [(set (reg:CC 24) (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
2725 (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
2729 sub%?s\\t%0, %1, #0"
2730 [(set_attr "conds" "set")])
2732 ;; Subroutine to store a half word from a register into memory.
2733 ;; Operand 0 is the source register (HImode)
2734 ;; Operand 1 is the destination address in a register (SImode)
2736 ;; In both this routine and the next, we must be careful not to spill
2737 ;; a memory address of reg+large_const into a separate PLUS insn, since this
2738 ;; can generate unrecognizable rtl.
2740 (define_expand "storehi"
2741 [;; store the low byte
2742 (set (match_operand 1 "" "") (match_dup 3))
2743 ;; extract the high byte
2745 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2746 ;; store the high byte
2747 (set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
2751 rtx addr = XEXP (operands[1], 0);
2752 enum rtx_code code = GET_CODE (addr);
2754 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
2756 addr = force_reg (SImode, addr);
2758 operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1));
2759 operands[1] = change_address (operands[1], QImode, NULL_RTX);
2760 operands[3] = gen_lowpart (QImode, operands[0]);
2761 operands[0] = gen_lowpart (SImode, operands[0]);
2762 operands[2] = gen_reg_rtx (SImode);
2766 (define_expand "storehi_bigend"
2767 [(set (match_dup 4) (match_dup 3))
2769 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
2770 (set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))]
2774 rtx addr = XEXP (operands[1], 0);
2775 enum rtx_code code = GET_CODE (addr);
2777 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
2779 addr = force_reg (SImode, addr);
2781 operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1));
2782 operands[1] = change_address (operands[1], QImode, NULL_RTX);
2783 operands[3] = gen_lowpart (QImode, operands[0]);
2784 operands[0] = gen_lowpart (SImode, operands[0]);
2785 operands[2] = gen_reg_rtx (SImode);
2789 ;; Subroutine to store a half word integer constant into memory.
2790 (define_expand "storeinthi"
2791 [(set (match_operand 0 "" "")
2792 (subreg:QI (match_operand 1 "" "") 0))
2793 (set (match_dup 3) (subreg:QI (match_dup 2) 0))]
2797 HOST_WIDE_INT value = INTVAL (operands[1]);
2798 rtx addr = XEXP (operands[0], 0);
2799 enum rtx_code code = GET_CODE (addr);
2801 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
2803 addr = force_reg (SImode, addr);
2805 operands[1] = gen_reg_rtx (SImode);
2806 if (BYTES_BIG_ENDIAN)
2808 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
2809 if ((value & 255) == ((value >> 8) & 255))
2810 operands[2] = operands[1];
2813 operands[2] = gen_reg_rtx (SImode);
2814 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
2819 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
2820 if ((value & 255) == ((value >> 8) & 255))
2821 operands[2] = operands[1];
2824 operands[2] = gen_reg_rtx (SImode);
2825 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
2829 operands[3] = change_address (operands[0], QImode, plus_constant (addr, 1));
2830 operands[0] = change_address (operands[0], QImode, NULL_RTX);
2834 (define_expand "storehi_single_op"
2835 [(set (match_operand:HI 0 "memory_operand" "")
2836 (match_operand:HI 1 "general_operand" ""))]
2839 if (! s_register_operand (operands[1], HImode))
2840 operands[1] = copy_to_mode_reg (HImode, operands[1]);
2843 (define_expand "movhi"
2844 [(set (match_operand:HI 0 "general_operand" "")
2845 (match_operand:HI 1 "general_operand" ""))]
2851 if (! (reload_in_progress || reload_completed))
2853 if (GET_CODE (operands[0]) == MEM)
2857 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
2860 if (GET_CODE (operands[1]) == CONST_INT)
2861 emit_insn (gen_storeinthi (operands[0], operands[1]));
2864 if (GET_CODE (operands[1]) == MEM)
2865 operands[1] = force_reg (HImode, operands[1]);
2866 if (BYTES_BIG_ENDIAN)
2867 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
2869 emit_insn (gen_storehi (operands[1], operands[0]));
2873 /* Sign extend a constant, and keep it in an SImode reg. */
2874 else if (GET_CODE (operands[1]) == CONST_INT)
2876 rtx reg = gen_reg_rtx (SImode);
2877 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
2879 /* If the constant is already valid, leave it alone. */
2880 if (! const_ok_for_arm (val))
2882 /* If setting all the top bits will make the constant
2883 loadable in a single instruction, then set them.
2884 Otherwise, sign extend the number. */
2886 if (const_ok_for_arm (~ (val | ~0xffff)))
2888 else if (val & 0x8000)
2892 emit_insn (gen_movsi (reg, GEN_INT (val)));
2893 operands[1] = gen_rtx_SUBREG (HImode, reg, 0);
2895 else if (! arm_arch4)
2897 if (GET_CODE (operands[1]) == MEM)
2899 if (TARGET_SHORT_BY_BYTES)
2902 rtx offset = const0_rtx;
2903 rtx reg = gen_reg_rtx (SImode);
2905 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2906 || (GET_CODE (base) == PLUS
2907 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2908 && GET_CODE (base = XEXP (base, 0)) == REG))
2909 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2911 HOST_WIDE_INT new_offset = INTVAL (offset) & ~2;
2914 new = gen_rtx_MEM (SImode,
2915 plus_constant (base, new_offset));
2916 MEM_COPY_ATTRIBUTES (new, operands[1]);
2917 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
2918 emit_insn (gen_movsi (reg, new));
2919 if (((INTVAL (offset) & 2) != 0)
2920 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
2922 rtx reg2 = gen_reg_rtx (SImode);
2924 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
2929 emit_insn (gen_movhi_bytes (reg, operands[1]));
2931 operands[1] = gen_lowpart (HImode, reg);
2933 else if (BYTES_BIG_ENDIAN)
2936 rtx offset = const0_rtx;
2938 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
2939 || (GET_CODE (base) == PLUS
2940 && GET_CODE (offset = XEXP (base, 1)) == CONST_INT
2941 && GET_CODE (base = XEXP (base, 0)) == REG))
2942 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4)
2944 rtx reg = gen_reg_rtx (SImode);
2947 if ((INTVAL (offset) & 2) == 2)
2949 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
2950 new = gen_rtx_MEM (SImode,
2951 plus_constant (base, new_offset));
2952 MEM_COPY_ATTRIBUTES (new, operands[1]);
2953 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
2954 emit_insn (gen_movsi (reg, new));
2958 new = gen_rtx_MEM (SImode, XEXP (operands[1], 0));
2959 MEM_COPY_ATTRIBUTES (new, operands[1]);
2960 RTX_UNCHANGING_P (new)
2961 = RTX_UNCHANGING_P (operands[1]);
2962 emit_insn (gen_rotated_loadsi (reg, new));
2965 operands[1] = gen_lowpart (HImode, reg);
2969 emit_insn (gen_movhi_bigend (operands[0], operands[1]));
2976 /* Handle loading a large integer during reload */
2977 else if (GET_CODE (operands[1]) == CONST_INT
2978 && ! const_ok_for_arm (INTVAL (operands[1]))
2979 && ! const_ok_for_arm (~INTVAL (operands[1])))
2981 /* Writing a constant to memory needs a scratch, which should
2982 be handled with SECONDARY_RELOADs. */
2983 if (GET_CODE (operands[0]) != REG)
2986 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
2987 emit_insn (gen_movsi (operands[0], operands[1]));
2993 (define_insn "rotated_loadsi"
2994 [(set (match_operand:SI 0 "s_register_operand" "=r")
2995 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
2997 "! TARGET_SHORT_BY_BYTES"
3002 ops[0] = operands[0];
3003 ops[1] = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[1], 0), 2));
3004 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
3007 [(set_attr "type" "load")])
3009 (define_expand "movhi_bytes"
3010 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3012 (zero_extend:SI (match_dup 6)))
3013 (set (match_operand:SI 0 "" "")
3014 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
3019 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3021 mem1 = gen_rtx_MEM (QImode, addr);
3022 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3023 RTX_UNCHANGING_P (mem1) = RTX_UNCHANGING_P (operands[1]);
3024 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3025 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3026 RTX_UNCHANGING_P (mem2) = RTX_UNCHANGING_P (operands[1]);
3027 operands[0] = gen_lowpart (SImode, operands[0]);
3029 operands[2] = gen_reg_rtx (SImode);
3030 operands[3] = gen_reg_rtx (SImode);
3033 if (BYTES_BIG_ENDIAN)
3035 operands[4] = operands[2];
3036 operands[5] = operands[3];
3040 operands[4] = operands[3];
3041 operands[5] = operands[2];
3046 (define_expand "movhi_bigend"
3048 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
3051 (ashiftrt:SI (match_dup 2) (const_int 16)))
3052 (set (match_operand:HI 0 "s_register_operand" "")
3053 (subreg:HI (match_dup 3) 0))]
3056 operands[2] = gen_reg_rtx (SImode);
3057 operands[3] = gen_reg_rtx (SImode);
3060 ;; Pattern to recognise insn generated default case above
3062 (define_insn "*movhi_insn_arch4"
3063 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
3064 (match_operand:HI 1 "general_operand" "rI,K,m,r"))]
3066 && (GET_CODE (operands[1]) != CONST_INT
3067 || const_ok_for_arm (INTVAL (operands[1]))
3068 || const_ok_for_arm (~INTVAL (operands[1])))"
3070 mov%?\\t%0, %1\\t%@ movhi
3071 mvn%?\\t%0, #%B1\\t%@ movhi
3072 ldr%?h\\t%0, %1\\t%@ movhi
3073 str%?h\\t%1, %0\\t%@ movhi"
3074 [(set_attr "type" "*,*,load,store1")])
3076 (define_insn "*movhi_insn_littleend"
3077 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
3078 (match_operand:HI 1 "general_operand" "rI,K,m"))]
3080 && ! BYTES_BIG_ENDIAN
3081 && ! TARGET_SHORT_BY_BYTES
3082 && (GET_CODE (operands[1]) != CONST_INT
3083 || const_ok_for_arm (INTVAL (operands[1]))
3084 || const_ok_for_arm (~INTVAL (operands[1])))"
3086 mov%?\\t%0, %1\\t%@ movhi
3087 mvn%?\\t%0, #%B1\\t%@ movhi
3088 ldr%?\\t%0, %1\\t%@ movhi"
3089 [(set_attr "type" "*,*,load")])
3091 (define_insn "*movhi_insn_bigend"
3092 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
3093 (match_operand:HI 1 "general_operand" "rI,K,m"))]
3096 && ! TARGET_SHORT_BY_BYTES
3097 && (GET_CODE (operands[1]) != CONST_INT
3098 || const_ok_for_arm (INTVAL (operands[1]))
3099 || const_ok_for_arm (~INTVAL (operands[1])))"
3101 mov%?\\t%0, %1\\t%@ movhi
3102 mvn%?\\t%0, #%B1\\t%@ movhi
3103 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
3104 [(set_attr "type" "*,*,load")
3105 (set_attr "length" "4,4,8")])
3107 (define_insn "*loadhi_si_bigend"
3108 [(set (match_operand:SI 0 "s_register_operand" "=r")
3109 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
3112 && ! TARGET_SHORT_BY_BYTES"
3113 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
3114 [(set_attr "type" "load")])
3116 (define_insn "*movhi_bytes"
3117 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
3118 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
3119 "TARGET_SHORT_BY_BYTES"
3121 mov%?\\t%0, %1\\t%@ movhi
3122 mvn%?\\t%0, #%B1\\t%@ movhi")
3125 (define_expand "reload_outhi"
3126 [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
3127 (match_operand:HI 1 "s_register_operand" "r")
3128 (match_operand:SI 2 "s_register_operand" "=&r")])]
3131 arm_reload_out_hi (operands);
3135 (define_expand "reload_inhi"
3136 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
3137 (match_operand:HI 1 "reload_memory_operand" "o")
3138 (match_operand:SI 2 "s_register_operand" "=&r")])]
3139 "TARGET_SHORT_BY_BYTES"
3141 arm_reload_in_hi (operands);
3145 (define_expand "movqi"
3146 [(set (match_operand:QI 0 "general_operand" "")
3147 (match_operand:QI 1 "general_operand" ""))]
3150 /* Everything except mem = const or mem = mem can be done easily */
3152 if (!(reload_in_progress || reload_completed))
3154 if (GET_CODE (operands[1]) == CONST_INT)
3156 rtx reg = gen_reg_rtx (SImode);
3158 emit_insn (gen_movsi (reg, operands[1]));
3159 operands[1] = gen_rtx_SUBREG (QImode, reg, 0);
3161 if (GET_CODE (operands[0]) == MEM)
3162 operands[1] = force_reg (QImode, operands[1]);
3167 (define_insn "*movqi_insn"
3168 [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
3169 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
3170 "register_operand (operands[0], QImode)
3171 || register_operand (operands[1], QImode)"
3177 [(set_attr "type" "*,*,load,store1")])
3179 (define_expand "movsf"
3180 [(set (match_operand:SF 0 "general_operand" "")
3181 (match_operand:SF 1 "general_operand" ""))]
3184 if (GET_CODE (operands[0]) == MEM)
3185 operands[1] = force_reg (SFmode, operands[1]);
3188 (define_insn "*movsf_hard_insn"
3189 [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
3190 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
3192 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
3198 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
3199 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
3201 ldr%?\\t%0, %1\\t%@ float
3202 str%?\\t%1, %0\\t%@ float"
3203 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
3205 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
3207 ;; Exactly the same as above, except that all `f' cases are deleted.
3208 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3209 ;; when -msoft-float.
3211 (define_insn "*movsf_soft_insn"
3212 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
3213 (match_operand:SF 1 "general_operand" "r,mE,r"))]
3215 && (GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode))"
3218 ldr%?\\t%0, %1\\t%@ float
3219 str%?\\t%1, %0\\t%@ float"
3220 [(set_attr "length" "4,4,4")
3221 (set_attr "type" "*,load,store1")])
3223 (define_expand "movdf"
3224 [(set (match_operand:DF 0 "general_operand" "")
3225 (match_operand:DF 1 "general_operand" ""))]
3228 if (GET_CODE (operands[0]) == MEM)
3229 operands[1] = force_reg (DFmode, operands[1]);
3232 ;; Reloading a df mode value stored in integer regs to memory can require a
3234 (define_expand "reload_outdf"
3235 [(match_operand:DF 0 "reload_memory_operand" "=o")
3236 (match_operand:DF 1 "s_register_operand" "r")
3237 (match_operand:SI 2 "s_register_operand" "=&r")]
3241 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
3244 operands[2] = XEXP (operands[0], 0);
3245 else if (code == POST_INC || code == PRE_DEC)
3247 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
3248 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
3249 emit_insn (gen_movdi (operands[0], operands[1]));
3252 else if (code == PRE_INC)
3254 rtx reg = XEXP (XEXP (operands[0], 0), 0);
3255 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
3258 else if (code == POST_DEC)
3259 operands[2] = XEXP (XEXP (operands[0], 0), 0);
3261 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
3262 XEXP (XEXP (operands[0], 0), 1)));
3264 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
3267 if (code == POST_DEC)
3268 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
3274 (define_insn "*movdf_hard_insn"
3275 [(set (match_operand:DF 0 "general_operand" "=r,Q,r,m,r,f,f,f,m,!f,!r")
3276 (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,fG,H,mF,f,r,f"))]
3278 && (GET_CODE (operands[0]) != MEM
3279 || register_operand (operands[1], DFmode))"
3284 switch (which_alternative)
3286 case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
3287 case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
3288 case 2: case 3: case 4: return output_move_double (operands);
3289 case 5: return \"mvf%?d\\t%0, %1\";
3290 case 6: return \"mnf%?d\\t%0, #%N1\";
3291 case 7: return \"ldf%?d\\t%0, %1\";
3292 case 8: return \"stf%?d\\t%1, %0\";
3293 case 9: return output_mov_double_fpu_from_arm (operands);
3294 case 10: return output_mov_double_arm_from_fpu (operands);
3298 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
3300 "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")])
3302 ;; Software floating point version. This is essentially the same as movdi.
3303 ;; Do not use `f' as a constraint to prevent reload from ever trying to use
3306 (define_insn "*movdf_soft_insn"
3307 [(set (match_operand:DF 0 "soft_df_operand" "=r,r,m")
3308 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
3310 "* return output_move_double (operands);"
3311 [(set_attr "length" "8,8,8")
3312 (set_attr "type" "*,load,store2")])
3314 (define_expand "movxf"
3315 [(set (match_operand:XF 0 "general_operand" "")
3316 (match_operand:XF 1 "general_operand" ""))]
3317 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3320 ;; Even when the XFmode patterns aren't enabled, we enable this after
3321 ;; reloading so that we can push floating point registers in the prologue.
3323 (define_insn "*movxf_hard_insn"
3324 [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
3325 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
3326 "TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
3328 switch (which_alternative)
3330 case 0: return \"mvf%?e\\t%0, %1\";
3331 case 1: return \"mnf%?e\\t%0, #%N1\";
3332 case 2: return \"ldf%?e\\t%0, %1\";
3333 case 3: return \"stf%?e\\t%1, %0\";
3334 case 4: return output_mov_long_double_fpu_from_arm (operands);
3335 case 5: return output_mov_long_double_arm_from_fpu (operands);
3336 case 6: return output_mov_long_double_arm_from_arm (operands);
3339 [(set_attr "length" "4,4,4,4,8,8,12")
3340 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
3343 ;; load- and store-multiple insns
3344 ;; The arm can load/store any set of registers, provided that they are in
3345 ;; ascending order; but that is beyond GCC so stick with what it knows.
3347 (define_expand "load_multiple"
3348 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3349 (match_operand:SI 1 "" ""))
3350 (use (match_operand:SI 2 "" ""))])]
3353 /* Support only fixed point registers */
3354 if (GET_CODE (operands[2]) != CONST_INT
3355 || INTVAL (operands[2]) > 14
3356 || INTVAL (operands[2]) < 2
3357 || GET_CODE (operands[1]) != MEM
3358 || GET_CODE (operands[0]) != REG
3359 || REGNO (operands[0]) > 14
3360 || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
3364 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
3365 force_reg (SImode, XEXP (operands[1], 0)),
3366 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
3367 MEM_IN_STRUCT_P(operands[1]),
3368 MEM_SCALAR_P (operands[1]));
3371 ;; Load multiple with write-back
3373 (define_insn "*ldmsi_postinc"
3374 [(match_parallel 0 "load_multiple_operation"
3375 [(set (match_operand:SI 1 "s_register_operand" "+r")
3376 (plus:SI (match_dup 1)
3377 (match_operand:SI 2 "const_int_operand" "n")))
3378 (set (match_operand:SI 3 "s_register_operand" "=r")
3379 (mem:SI (match_dup 1)))])]
3380 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3384 int count = XVECLEN (operands[0], 0);
3386 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3387 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
3388 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
3390 output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
3394 [(set_attr "type" "load")])
3396 ;; Ordinary load multiple
3398 (define_insn "*ldmsi"
3399 [(match_parallel 0 "load_multiple_operation"
3400 [(set (match_operand:SI 1 "s_register_operand" "=r")
3401 (mem:SI (match_operand:SI 2 "s_register_operand" "r")))])]
3406 int count = XVECLEN (operands[0], 0);
3408 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3409 ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
3410 ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
3412 output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
3416 [(set_attr "type" "load")])
3418 (define_expand "store_multiple"
3419 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
3420 (match_operand:SI 1 "" ""))
3421 (use (match_operand:SI 2 "" ""))])]
3424 /* Support only fixed point registers */
3425 if (GET_CODE (operands[2]) != CONST_INT
3426 || INTVAL (operands[2]) > 14
3427 || INTVAL (operands[2]) < 2
3428 || GET_CODE (operands[1]) != REG
3429 || GET_CODE (operands[0]) != MEM
3430 || REGNO (operands[1]) > 14
3431 || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
3435 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
3436 force_reg (SImode, XEXP (operands[0], 0)),
3437 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
3438 MEM_IN_STRUCT_P(operands[0]),
3439 MEM_SCALAR_P (operands[0]));
3442 ;; Store multiple with write-back
3444 (define_insn "*stmsi_postinc"
3445 [(match_parallel 0 "store_multiple_operation"
3446 [(set (match_operand:SI 1 "s_register_operand" "+r")
3447 (plus:SI (match_dup 1)
3448 (match_operand:SI 2 "const_int_operand" "n")))
3449 (set (mem:SI (match_dup 1))
3450 (match_operand:SI 3 "s_register_operand" "r"))])]
3451 "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
3455 int count = XVECLEN (operands[0], 0);
3457 ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
3458 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
3459 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
3461 output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
3466 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3467 (const_string "store2")
3468 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
3469 (const_string "store3")]
3470 (const_string "store4")))])
3472 ;; Ordinary store multiple
3474 (define_insn "*stmsi"
3475 [(match_parallel 0 "store_multiple_operation"
3476 [(set (mem:SI (match_operand:SI 2 "s_register_operand" "r"))
3477 (match_operand:SI 1 "s_register_operand" "r"))])]
3482 int count = XVECLEN (operands[0], 0);
3484 ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
3485 ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
3486 ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
3488 output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
3493 (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
3494 (const_string "store2")
3495 (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
3496 (const_string "store3")]
3497 (const_string "store4")))])
3499 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
3500 ;; We could let this apply for blocks of less than this, but it clobbers so
3501 ;; many registers that there is then probably a better way.
3503 (define_expand "movstrqi"
3504 [(match_operand:BLK 0 "general_operand" "")
3505 (match_operand:BLK 1 "general_operand" "")
3506 (match_operand:SI 2 "const_int_operand" "")
3507 (match_operand:SI 3 "const_int_operand" "")]
3510 if (arm_gen_movstrqi (operands))
3516 ;; Comparison and test insns
3518 (define_expand "cmpsi"
3519 [(match_operand:SI 0 "s_register_operand" "")
3520 (match_operand:SI 1 "arm_add_operand" "")]
3524 arm_compare_op0 = operands[0];
3525 arm_compare_op1 = operands[1];
3531 (define_expand "cmpsf"
3532 [(match_operand:SF 0 "s_register_operand" "")
3533 (match_operand:SF 1 "fpu_rhs_operand" "")]
3537 arm_compare_op0 = operands[0];
3538 arm_compare_op1 = operands[1];
3544 (define_expand "cmpdf"
3545 [(match_operand:DF 0 "s_register_operand" "")
3546 (match_operand:DF 1 "fpu_rhs_operand" "")]
3550 arm_compare_op0 = operands[0];
3551 arm_compare_op1 = operands[1];
3557 (define_expand "cmpxf"
3558 [(match_operand:XF 0 "s_register_operand" "")
3559 (match_operand:XF 1 "fpu_rhs_operand" "")]
3560 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3563 arm_compare_op0 = operands[0];
3564 arm_compare_op1 = operands[1];
3570 (define_insn "*cmpsi_insn"
3572 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
3573 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
3578 [(set_attr "conds" "set")])
3580 (define_insn "*cmpsi_shiftsi"
3582 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3583 (match_operator:SI 3 "shift_operator"
3584 [(match_operand:SI 1 "s_register_operand" "r")
3585 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
3588 [(set_attr "conds" "set")])
3590 (define_insn "*cmpsi_shiftsi_swp"
3591 [(set (reg:CC_SWP 24)
3592 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
3593 [(match_operand:SI 1 "s_register_operand" "r")
3594 (match_operand:SI 2 "reg_or_int_operand" "rM")])
3595 (match_operand:SI 0 "s_register_operand" "r")))]
3598 [(set_attr "conds" "set")])
3600 (define_insn "*cmpsi_neg_shiftsi"
3602 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
3603 (neg:SI (match_operator:SI 3 "shift_operator"
3604 [(match_operand:SI 1 "s_register_operand" "r")
3605 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
3608 [(set_attr "conds" "set")])
3610 (define_insn "*cmpsf_insn"
3612 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
3613 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3618 [(set_attr "conds" "set")
3619 (set_attr "type" "f_2_r")])
3621 (define_insn "*cmpdf_insn"
3623 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
3624 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3629 [(set_attr "conds" "set")
3630 (set_attr "type" "f_2_r")])
3632 (define_insn "*cmpesfdf_df"
3634 (compare:CCFP (float_extend:DF
3635 (match_operand:SF 0 "s_register_operand" "f,f"))
3636 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3641 [(set_attr "conds" "set")
3642 (set_attr "type" "f_2_r")])
3644 (define_insn "*cmpdf_esfdf"
3646 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
3648 (match_operand:SF 1 "s_register_operand" "f"))))]
3651 [(set_attr "conds" "set")
3652 (set_attr "type" "f_2_r")])
3654 (define_insn "*cmpxf_insn"
3656 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
3657 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3658 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3662 [(set_attr "conds" "set")
3663 (set_attr "type" "f_2_r")])
3665 (define_insn "*cmpsf_trap"
3666 [(set (reg:CCFPE 24)
3667 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
3668 (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
3673 [(set_attr "conds" "set")
3674 (set_attr "type" "f_2_r")])
3676 (define_insn "*cmpdf_trap"
3677 [(set (reg:CCFPE 24)
3678 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
3679 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3684 [(set_attr "conds" "set")
3685 (set_attr "type" "f_2_r")])
3687 (define_insn "*cmp_esfdf_df_trap"
3688 [(set (reg:CCFPE 24)
3689 (compare:CCFPE (float_extend:DF
3690 (match_operand:SF 0 "s_register_operand" "f,f"))
3691 (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
3696 [(set_attr "conds" "set")
3697 (set_attr "type" "f_2_r")])
3699 (define_insn "*cmp_df_esfdf_trap"
3700 [(set (reg:CCFPE 24)
3701 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
3703 (match_operand:SF 1 "s_register_operand" "f"))))]
3706 [(set_attr "conds" "set")
3707 (set_attr "type" "f_2_r")])
3709 (define_insn "*cmpxf_trap"
3710 [(set (reg:CCFPE 24)
3711 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
3712 (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
3713 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
3717 [(set_attr "conds" "set")
3718 (set_attr "type" "f_2_r")])
3720 ; This insn allows redundant compares to be removed by cse, nothing should
3721 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
3722 ; is deleted later on. The match_dup will match the mode here, so that
3723 ; mode changes of the condition codes aren't lost by this even though we don't
3724 ; specify what they are.
3726 (define_insn "*deleted_compare"
3727 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
3729 "\\t%@ deleted compare"
3730 [(set_attr "conds" "set")
3731 (set_attr "length" "0")])
3734 ;; Conditional branch insns
3736 (define_expand "beq"
3738 (if_then_else (eq (match_dup 1) (const_int 0))
3739 (label_ref (match_operand 0 "" ""))
3744 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3749 (define_expand "bne"
3751 (if_then_else (ne (match_dup 1) (const_int 0))
3752 (label_ref (match_operand 0 "" ""))
3757 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3762 (define_expand "bgt"
3764 (if_then_else (gt (match_dup 1) (const_int 0))
3765 (label_ref (match_operand 0 "" ""))
3770 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3775 (define_expand "ble"
3777 (if_then_else (le (match_dup 1) (const_int 0))
3778 (label_ref (match_operand 0 "" ""))
3783 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3788 (define_expand "bge"
3790 (if_then_else (ge (match_dup 1) (const_int 0))
3791 (label_ref (match_operand 0 "" ""))
3796 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3801 (define_expand "blt"
3803 (if_then_else (lt (match_dup 1) (const_int 0))
3804 (label_ref (match_operand 0 "" ""))
3809 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3814 (define_expand "bgtu"
3816 (if_then_else (gtu (match_dup 1) (const_int 0))
3817 (label_ref (match_operand 0 "" ""))
3822 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3827 (define_expand "bleu"
3829 (if_then_else (leu (match_dup 1) (const_int 0))
3830 (label_ref (match_operand 0 "" ""))
3835 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3840 (define_expand "bgeu"
3842 (if_then_else (geu (match_dup 1) (const_int 0))
3843 (label_ref (match_operand 0 "" ""))
3848 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
3853 (define_expand "bltu"
3855 (if_then_else (ltu (match_dup 1) (const_int 0))
3856 (label_ref (match_operand 0 "" ""))
3861 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
3866 ;; patterns to match conditional branch insns
3868 (define_insn "*condbranch"
3870 (if_then_else (match_operator 1 "comparison_operator"
3871 [(match_operand 2 "cc_register" "") (const_int 0)])
3872 (label_ref (match_operand 0 "" ""))
3877 extern int arm_ccfsm_state;
3879 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3881 arm_ccfsm_state += 2;
3884 return \"b%d1\\t%l0\";
3886 [(set_attr "conds" "use")])
3888 (define_insn "*condbranch_reversed"
3890 (if_then_else (match_operator 1 "comparison_operator"
3891 [(match_operand 2 "cc_register" "") (const_int 0)])
3893 (label_ref (match_operand 0 "" ""))))]
3897 extern int arm_ccfsm_state;
3899 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
3901 arm_ccfsm_state += 2;
3904 return \"b%D1\\t%l0\";
3906 [(set_attr "conds" "use")])
3911 (define_expand "seq"
3912 [(set (match_operand:SI 0 "s_register_operand" "=r")
3913 (eq:SI (match_dup 1) (const_int 0)))]
3917 operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
3922 (define_expand "sne"
3923 [(set (match_operand:SI 0 "s_register_operand" "=r")
3924 (ne:SI (match_dup 1) (const_int 0)))]
3928 operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
3933 (define_expand "sgt"
3934 [(set (match_operand:SI 0 "s_register_operand" "=r")
3935 (gt:SI (match_dup 1) (const_int 0)))]
3939 operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
3944 (define_expand "sle"
3945 [(set (match_operand:SI 0 "s_register_operand" "=r")
3946 (le:SI (match_dup 1) (const_int 0)))]
3950 operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
3955 (define_expand "sge"
3956 [(set (match_operand:SI 0 "s_register_operand" "=r")
3957 (ge:SI (match_dup 1) (const_int 0)))]
3961 operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
3966 (define_expand "slt"
3967 [(set (match_operand:SI 0 "s_register_operand" "=r")
3968 (lt:SI (match_dup 1) (const_int 0)))]
3972 operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
3977 (define_expand "sgtu"
3978 [(set (match_operand:SI 0 "s_register_operand" "=r")
3979 (gtu:SI (match_dup 1) (const_int 0)))]
3983 operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
3988 (define_expand "sleu"
3989 [(set (match_operand:SI 0 "s_register_operand" "=r")
3990 (leu:SI (match_dup 1) (const_int 0)))]
3994 operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
3999 (define_expand "sgeu"
4000 [(set (match_operand:SI 0 "s_register_operand" "=r")
4001 (geu:SI (match_dup 1) (const_int 0)))]
4005 operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
4010 (define_expand "sltu"
4011 [(set (match_operand:SI 0 "s_register_operand" "=r")
4012 (ltu:SI (match_dup 1) (const_int 0)))]
4016 operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
4021 (define_insn "*mov_scc"
4022 [(set (match_operand:SI 0 "s_register_operand" "=r")
4023 (match_operator:SI 1 "comparison_operator"
4024 [(match_operand 2 "cc_register" "") (const_int 0)]))]
4026 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
4027 [(set_attr "conds" "use")
4028 (set_attr "length" "8")])
4030 (define_insn "*mov_negscc"
4031 [(set (match_operand:SI 0 "s_register_operand" "=r")
4032 (neg:SI (match_operator:SI 1 "comparison_operator"
4033 [(match_operand 2 "cc_register" "") (const_int 0)])))]
4035 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
4036 [(set_attr "conds" "use")
4037 (set_attr "length" "8")])
4039 (define_insn "*mov_notscc"
4040 [(set (match_operand:SI 0 "s_register_operand" "=r")
4041 (not:SI (match_operator:SI 1 "comparison_operator"
4042 [(match_operand 2 "cc_register" "") (const_int 0)])))]
4044 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
4045 [(set_attr "conds" "use")
4046 (set_attr "length" "8")])
4049 ;; Conditional move insns
4051 (define_expand "movsicc"
4052 [(set (match_operand:SI 0 "s_register_operand" "")
4053 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4054 (match_operand:SI 2 "arm_not_operand" "")
4055 (match_operand:SI 3 "arm_not_operand" "")))]
4059 enum rtx_code code = GET_CODE (operands[1]);
4060 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
4063 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
4066 (define_expand "movsfcc"
4067 [(set (match_operand:SF 0 "s_register_operand" "")
4068 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4069 (match_operand:SF 2 "s_register_operand" "")
4070 (match_operand:SF 3 "nonmemory_operand" "")))]
4074 enum rtx_code code = GET_CODE (operands[1]);
4077 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
4078 Otherwise, ensure it is a valid FP add operand */
4079 if ((! TARGET_HARD_FLOAT)
4080 || (! fpu_add_operand (operands[3], SFmode)))
4081 operands[3] = force_reg (SFmode, operands[3]);
4083 ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
4086 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
4089 (define_expand "movdfcc"
4090 [(set (match_operand:DF 0 "s_register_operand" "")
4091 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4092 (match_operand:DF 2 "s_register_operand" "")
4093 (match_operand:DF 3 "fpu_add_operand" "")))]
4097 enum rtx_code code = GET_CODE (operands[1]);
4098 rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
4101 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
4104 (define_insn "*movsicc_insn"
4105 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
4107 (match_operator 3 "comparison_operator"
4108 [(match_operand 4 "cc_register" "") (const_int 0)])
4109 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
4110 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
4117 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
4118 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
4119 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
4120 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
4121 [(set_attr "length" "4,4,4,4,8,8,8,8")
4122 (set_attr "conds" "use")])
4124 (define_insn "*movsfcc_hard_insn"
4125 [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
4127 (match_operator 3 "comparison_operator"
4128 [(match_operand 4 "cc_register" "") (const_int 0)])
4129 (match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
4130 (match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
4137 mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
4138 mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
4139 mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
4140 mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
4141 [(set_attr "length" "4,4,4,4,8,8,8,8")
4142 (set_attr "type" "ffarith")
4143 (set_attr "conds" "use")])
4145 (define_insn "*movsfcc_soft_insn"
4146 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
4147 (if_then_else:SF (match_operator 3 "comparison_operator"
4148 [(match_operand 4 "cc_register" "") (const_int 0)])
4149 (match_operand:SF 1 "s_register_operand" "0,r")
4150 (match_operand:SF 2 "s_register_operand" "r,0")))]
4155 [(set_attr "conds" "use")])
4157 (define_insn "*movdfcc_insn"
4158 [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
4160 (match_operator 3 "comparison_operator"
4161 [(match_operand 4 "cc_register" "") (const_int 0)])
4162 (match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
4163 (match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
4170 mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
4171 mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
4172 mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
4173 mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
4174 [(set_attr "length" "4,4,4,4,8,8,8,8")
4175 (set_attr "type" "ffarith")
4176 (set_attr "conds" "use")])
4178 ;; Jump and linkage insns
4182 (label_ref (match_operand 0 "" "")))]
4186 extern int arm_ccfsm_state;
4188 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
4190 arm_ccfsm_state += 2;
4193 return \"b%?\\t%l0\";
4196 (define_expand "call"
4197 [(parallel [(call (match_operand 0 "memory_operand" "")
4198 (match_operand 1 "general_operand" ""))
4199 (clobber (reg:SI 14))])]
4203 (define_insn "*call_reg"
4204 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
4205 (match_operand 1 "" "g"))
4206 (clobber (reg:SI 14))]
4209 return output_call (operands);
4211 ;; length is worst case, normally it is only two
4212 [(set_attr "length" "12")
4213 (set_attr "type" "call")])
4215 (define_insn "*call_mem"
4216 [(call (mem:SI (match_operand 0 "memory_operand" "m"))
4217 (match_operand 1 "general_operand" "g"))
4218 (clobber (reg:SI 14))]
4221 return output_call_mem (operands);
4223 [(set_attr "length" "12")
4224 (set_attr "type" "call")])
4226 (define_expand "call_value"
4227 [(parallel [(set (match_operand 0 "" "=rf")
4228 (call (match_operand 1 "memory_operand" "m")
4229 (match_operand 2 "general_operand" "g")))
4230 (clobber (reg:SI 14))])]
4234 (define_insn "*call_value_reg"
4235 [(set (match_operand 0 "" "=rf")
4236 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
4237 (match_operand 2 "general_operand" "g")))
4238 (clobber (reg:SI 14))]
4241 return output_call (&operands[1]);
4243 [(set_attr "length" "12")
4244 (set_attr "type" "call")])
4246 (define_insn "*call_value_mem"
4247 [(set (match_operand 0 "" "=rf")
4248 (call (mem:SI (match_operand 1 "memory_operand" "m"))
4249 (match_operand 2 "general_operand" "g")))
4250 (clobber (reg:SI 14))]
4251 "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
4253 return output_call_mem (&operands[1]);
4255 [(set_attr "length" "12")
4256 (set_attr "type" "call")])
4258 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
4259 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
4261 (define_insn "*call_symbol"
4262 [(call (mem:SI (match_operand:SI 0 "" "X"))
4263 (match_operand:SI 1 "general_operand" "g"))
4264 (clobber (reg:SI 14))]
4265 "GET_CODE (operands[0]) == SYMBOL_REF"
4267 [(set_attr "type" "call")])
4269 (define_insn "*call_value_symbol"
4270 [(set (match_operand 0 "s_register_operand" "=rf")
4271 (call (mem:SI (match_operand:SI 1 "" "X"))
4272 (match_operand:SI 2 "general_operand" "g")))
4273 (clobber (reg:SI 14))]
4274 "GET_CODE(operands[1]) == SYMBOL_REF"
4276 [(set_attr "type" "call")])
4278 ;; Often the return insn will be the same as loading from memory, so set attr
4279 (define_insn "return"
4281 "USE_RETURN_INSN(FALSE)"
4284 extern int arm_ccfsm_state;
4286 if (arm_ccfsm_state == 2)
4288 arm_ccfsm_state += 2;
4291 return output_return_instruction (NULL, TRUE, FALSE);
4293 [(set_attr "type" "load")])
4295 (define_insn "*cond_return"
4297 (if_then_else (match_operator 0 "comparison_operator"
4298 [(match_operand 1 "cc_register" "") (const_int 0)])
4301 "USE_RETURN_INSN(TRUE)"
4304 extern int arm_ccfsm_state;
4306 if (arm_ccfsm_state == 2)
4308 arm_ccfsm_state += 2;
4311 return output_return_instruction (operands[0], TRUE, FALSE);
4313 [(set_attr "conds" "use")
4314 (set_attr "type" "load")])
4316 (define_insn "*cond_return_inverted"
4318 (if_then_else (match_operator 0 "comparison_operator"
4319 [(match_operand 1 "cc_register" "") (const_int 0)])
4322 "USE_RETURN_INSN(TRUE)"
4325 extern int arm_ccfsm_state;
4327 if (arm_ccfsm_state == 2)
4329 arm_ccfsm_state += 2;
4332 return output_return_instruction (operands[0], TRUE, TRUE);
4334 [(set_attr "conds" "use")
4335 (set_attr "type" "load")])
4337 ;; Call subroutine returning any type.
4339 (define_expand "untyped_call"
4340 [(parallel [(call (match_operand 0 "" "")
4342 (match_operand 1 "" "")
4343 (match_operand 2 "" "")])]
4349 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4351 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4353 rtx set = XVECEXP (operands[2], 0, i);
4354 emit_move_insn (SET_DEST (set), SET_SRC (set));
4357 /* The optimizer does not know that the call sets the function value
4358 registers we stored in the result block. We avoid problems by
4359 claiming that all hard registers are used and clobbered at this
4361 emit_insn (gen_blockage ());
4366 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4367 ;; all of memory. This blocks insns from being moved across this point.
4369 (define_insn "blockage"
4370 [(unspec_volatile [(const_int 0)] 0)]
4373 [(set_attr "length" "0")
4374 (set_attr "type" "block")])
4376 (define_expand "casesi"
4377 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
4378 (match_operand:SI 1 "const_int_operand" "") ; lower bound
4379 (match_operand:SI 2 "const_int_operand" "") ; total range
4380 (match_operand:SI 3 "" "") ; table label
4381 (match_operand:SI 4 "" "")] ; Out of range label
4386 if (operands[1] != const0_rtx)
4388 reg = gen_reg_rtx (SImode);
4389 emit_insn (gen_addsi3 (reg, operands[0],
4390 GEN_INT (-INTVAL (operands[1]))));
4394 if (! const_ok_for_arm (INTVAL (operands[2])))
4395 operands[2] = force_reg (SImode, operands[2]);
4397 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
4402 ;; The USE in this pattern is needed to tell flow analysis that this is
4403 ;; a CASESI insn. It has no other purpose.
4404 (define_insn "casesi_internal"
4405 [(parallel [(set (pc)
4407 (leu (match_operand:SI 0 "s_register_operand" "r")
4408 (match_operand:SI 1 "arm_rhs_operand" "rI"))
4409 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
4410 (label_ref (match_operand 2 "" ""))))
4411 (label_ref (match_operand 3 "" ""))))
4412 (use (label_ref (match_dup 2)))])]
4416 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
4417 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
4419 [(set_attr "conds" "clob")
4420 (set_attr "length" "12")])
4422 (define_insn "indirect_jump"
4424 (match_operand:SI 0 "s_register_operand" "r"))]
4426 "mov%?\\t%|pc, %0\\t%@ indirect jump")
4428 (define_insn "*load_indirect_jump"
4430 (match_operand:SI 0 "memory_operand" "m"))]
4432 "ldr%?\\t%|pc, %0\\t%@ indirect jump"
4433 [(set_attr "type" "load")])
4440 "mov%?\\tr0, r0\\t%@ nop")
4442 ;; Patterns to allow combination of arithmetic, cond code and shifts
4444 (define_insn "*arith_shiftsi"
4445 [(set (match_operand:SI 0 "s_register_operand" "=r")
4446 (match_operator:SI 1 "shiftable_operator"
4447 [(match_operator:SI 3 "shift_operator"
4448 [(match_operand:SI 4 "s_register_operand" "r")
4449 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4450 (match_operand:SI 2 "s_register_operand" "r")]))]
4452 "%i1%?\\t%0, %2, %4%S3")
4454 (define_insn "*arith_shiftsi_compare0"
4455 [(set (reg:CC_NOOV 24)
4456 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4457 [(match_operator:SI 3 "shift_operator"
4458 [(match_operand:SI 4 "s_register_operand" "r")
4459 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4460 (match_operand:SI 2 "s_register_operand" "r")])
4462 (set (match_operand:SI 0 "s_register_operand" "=r")
4463 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
4466 "%i1%?s\\t%0, %2, %4%S3"
4467 [(set_attr "conds" "set")])
4469 (define_insn "*arith_shiftsi_compare0_scratch"
4470 [(set (reg:CC_NOOV 24)
4471 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
4472 [(match_operator:SI 3 "shift_operator"
4473 [(match_operand:SI 4 "s_register_operand" "r")
4474 (match_operand:SI 5 "reg_or_int_operand" "rI")])
4475 (match_operand:SI 2 "s_register_operand" "r")])
4477 (clobber (match_scratch:SI 0 "=r"))]
4479 "%i1%?s\\t%0, %2, %4%S3"
4480 [(set_attr "conds" "set")])
4482 (define_insn "*sub_shiftsi"
4483 [(set (match_operand:SI 0 "s_register_operand" "=r")
4484 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4485 (match_operator:SI 2 "shift_operator"
4486 [(match_operand:SI 3 "s_register_operand" "r")
4487 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
4489 "sub%?\\t%0, %1, %3%S2")
4491 (define_insn "*sub_shiftsi_compare0"
4492 [(set (reg:CC_NOOV 24)
4494 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4495 (match_operator:SI 2 "shift_operator"
4496 [(match_operand:SI 3 "s_register_operand" "r")
4497 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4499 (set (match_operand:SI 0 "s_register_operand" "=r")
4500 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
4503 "sub%?s\\t%0, %1, %3%S2"
4504 [(set_attr "conds" "set")])
4506 (define_insn "*sub_shiftsi_compare0_scratch"
4507 [(set (reg:CC_NOOV 24)
4509 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
4510 (match_operator:SI 2 "shift_operator"
4511 [(match_operand:SI 3 "s_register_operand" "r")
4512 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
4514 (clobber (match_scratch:SI 0 "=r"))]
4516 "sub%?s\\t%0, %1, %3%S2"
4517 [(set_attr "conds" "set")])
4519 ;; These variants of the above insns can occur if the first operand is the
4520 ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
4521 ;; seem to be a way around it. Most of the predicates have to be null
4522 ;; because the format can be generated part way through reload, so
4523 ;; if we don't match it as soon as it becomes available, reload doesn't know
4524 ;; how to reload pseudos that haven't got hard registers; the constraints will
4525 ;; sort everything out.
4527 (define_insn "*reload_mulsi3"
4528 [(set (match_operand:SI 0 "" "=&r")
4529 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
4530 [(match_operand:SI 3 "" "r")
4531 (match_operand:SI 4 "" "rM")])
4532 (match_operand:SI 2 "" "r"))
4533 (match_operand:SI 1 "const_int_operand" "n")))]
4534 "reload_in_progress"
4536 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
4537 operands[2] = operands[1];
4538 operands[1] = operands[0];
4539 return output_add_immediate (operands);
4541 ; we have no idea how long the add_immediate is, it could be up to 4.
4542 [(set_attr "length" "20")])
4544 (define_insn "*reload_mulsi_compare0"
4545 [(set (reg:CC_NOOV 24)
4546 (compare:CC_NOOV (plus:SI
4548 (match_operator:SI 5 "shift_operator"
4549 [(match_operand:SI 3 "" "r")
4550 (match_operand:SI 4 "" "rM")])
4551 (match_operand:SI 1 "" "r"))
4552 (match_operand:SI 2 "const_int_operand" "n"))
4554 (set (match_operand:SI 0 "" "=&r")
4555 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
4558 "reload_in_progress"
4560 output_add_immediate (operands);
4561 return \"add%?s\\t%0, %0, %3%S5\";
4563 [(set_attr "conds" "set")
4564 (set_attr "length" "20")])
4566 (define_insn "*reload_mulsi_compare0_scratch"
4567 [(set (reg:CC_NOOV 24)
4568 (compare:CC_NOOV (plus:SI
4570 (match_operator:SI 5 "shift_operator"
4571 [(match_operand:SI 3 "" "r")
4572 (match_operand:SI 4 "" "rM")])
4573 (match_operand:SI 1 "" "r"))
4574 (match_operand:SI 2 "const_int_operand" "n"))
4576 (clobber (match_scratch:SI 0 "=&r"))]
4577 "reload_in_progress"
4579 output_add_immediate (operands);
4580 return \"add%?s\\t%0, %0, %3%S5\";
4582 [(set_attr "conds" "set")
4583 (set_attr "length" "20")])
4585 ;; These are similar, but are needed when the mla pattern contains the
4586 ;; eliminated register as operand 3.
4588 (define_insn "*reload_muladdsi"
4589 [(set (match_operand:SI 0 "" "=&r,&r")
4590 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
4591 (match_operand:SI 2 "" "r,r"))
4592 (match_operand:SI 3 "" "r,r"))
4593 (match_operand:SI 4 "const_int_operand" "n,n")))]
4594 "reload_in_progress"
4596 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
4597 operands[2] = operands[4];
4598 operands[1] = operands[0];
4599 return output_add_immediate (operands);
4601 [(set_attr "length" "20")
4602 (set_attr "type" "mult")])
4604 (define_insn "*reload_muladdsi_compare0"
4605 [(set (reg:CC_NOOV 24)
4606 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4607 (match_operand:SI 3 "" "r")
4608 (match_operand:SI 4 "" "r"))
4609 (match_operand:SI 1 "" "r"))
4610 (match_operand:SI 2 "const_int_operand" "n"))
4612 (set (match_operand:SI 0 "" "=&r")
4613 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
4615 "reload_in_progress"
4617 output_add_immediate (operands);
4618 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
4621 [(set_attr "length" "20")
4622 (set_attr "conds" "set")
4623 (set_attr "type" "mult")])
4625 (define_insn "*reload_muladdsi_compare0_scratch"
4626 [(set (reg:CC_NOOV 24)
4627 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
4628 (match_operand:SI 3 "" "r")
4629 (match_operand:SI 4 "" "r"))
4630 (match_operand:SI 1 "" "r"))
4631 (match_operand:SI 2 "const_int_operand" "n"))
4633 (clobber (match_scratch:SI 0 "=&r"))]
4634 "reload_in_progress"
4636 output_add_immediate (operands);
4637 return \"mla%?s\\t%0, %3, %4, %0\";
4639 [(set_attr "length" "20")
4640 (set_attr "conds" "set")
4641 (set_attr "type" "mult")])
4645 (define_insn "*and_scc"
4646 [(set (match_operand:SI 0 "s_register_operand" "=r")
4647 (and:SI (match_operator 1 "comparison_operator"
4648 [(match_operand 3 "cc_register" "") (const_int 0)])
4649 (match_operand:SI 2 "s_register_operand" "r")))]
4651 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
4652 [(set_attr "conds" "use")
4653 (set_attr "length" "8")])
4655 (define_insn "*ior_scc"
4656 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4657 (ior:SI (match_operator 2 "comparison_operator"
4658 [(match_operand 3 "cc_register" "") (const_int 0)])
4659 (match_operand:SI 1 "s_register_operand" "0,?r")))]
4663 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
4664 [(set_attr "conds" "use")
4665 (set_attr "length" "4,8")])
4667 (define_insn "*compare_scc"
4668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4669 (match_operator 1 "comparison_operator"
4670 [(match_operand:SI 2 "s_register_operand" "r,r")
4671 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
4672 (clobber (reg:CC 24))]
4675 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
4676 return \"mov\\t%0, %2, lsr #31\";
4678 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
4679 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
4681 if (GET_CODE (operands[1]) == NE)
4683 if (which_alternative == 1)
4684 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
4685 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
4687 if (which_alternative == 1)
4688 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
4690 output_asm_insn (\"cmp\\t%2, %3\", operands);
4691 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
4693 [(set_attr "conds" "clob")
4694 (set_attr "length" "12")])
4696 (define_insn "*cond_move"
4697 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4698 (if_then_else:SI (match_operator 3 "equality_operator"
4699 [(match_operator 4 "comparison_operator"
4700 [(match_operand 5 "cc_register" "") (const_int 0)])
4702 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4703 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
4706 if (GET_CODE (operands[3]) == NE)
4708 if (which_alternative != 1)
4709 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
4710 if (which_alternative != 0)
4711 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
4714 if (which_alternative != 0)
4715 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4716 if (which_alternative != 1)
4717 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
4720 [(set_attr "conds" "use")
4721 (set_attr "length" "4,4,8")])
4723 (define_insn "*cond_arith"
4724 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4725 (match_operator:SI 5 "shiftable_operator"
4726 [(match_operator:SI 4 "comparison_operator"
4727 [(match_operand:SI 2 "s_register_operand" "r,r")
4728 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
4729 (match_operand:SI 1 "s_register_operand" "0,?r")]))
4730 (clobber (reg:CC 24))]
4733 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
4734 return \"%i5\\t%0, %1, %2, lsr #31\";
4736 output_asm_insn (\"cmp\\t%2, %3\", operands);
4737 if (GET_CODE (operands[5]) == AND)
4738 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
4739 else if (GET_CODE (operands[5]) == MINUS)
4740 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
4741 else if (which_alternative != 0)
4742 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4743 return \"%i5%d4\\t%0, %1, #1\";
4745 [(set_attr "conds" "clob")
4746 (set_attr "length" "12")])
4748 (define_insn "*cond_sub"
4749 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4750 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
4751 (match_operator:SI 4 "comparison_operator"
4752 [(match_operand:SI 2 "s_register_operand" "r,r")
4753 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
4754 (clobber (reg:CC 24))]
4757 output_asm_insn (\"cmp\\t%2, %3\", operands);
4758 if (which_alternative != 0)
4759 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
4760 return \"sub%d4\\t%0, %1, #1\";
4762 [(set_attr "conds" "clob")
4763 (set_attr "length" "8,12")])
4765 (define_insn "*cmp_ite0"
4766 [(set (match_operand 6 "dominant_cc_register" "")
4769 (match_operator 4 "comparison_operator"
4770 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4771 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4772 (match_operator:SI 5 "comparison_operator"
4773 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4774 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4780 char* opcodes[4][2] =
4782 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
4783 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
4784 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
4785 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
4786 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
4789 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
4791 return opcodes[which_alternative][swap];
4794 [(set_attr "conds" "set")
4795 (set_attr "length" "8")])
4797 (define_insn "*cmp_ite1"
4798 [(set (match_operand 6 "dominant_cc_register" "")
4801 (match_operator 4 "comparison_operator"
4802 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
4803 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
4804 (match_operator:SI 5 "comparison_operator"
4805 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
4806 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
4812 char* opcodes[4][2] =
4814 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
4815 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
4816 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
4817 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
4818 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
4821 comparison_dominates_p (GET_CODE (operands[5]),
4822 reverse_condition (GET_CODE (operands[4])));
4824 return opcodes[which_alternative][swap];
4827 [(set_attr "conds" "set")
4828 (set_attr "length" "8")])
4830 (define_insn "*negscc"
4831 [(set (match_operand:SI 0 "s_register_operand" "=r")
4832 (neg:SI (match_operator 3 "comparison_operator"
4833 [(match_operand:SI 1 "s_register_operand" "r")
4834 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
4835 (clobber (reg:CC 24))]
4838 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
4839 return \"mov\\t%0, %1, asr #31\";
4841 if (GET_CODE (operands[3]) == NE)
4842 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
4844 if (GET_CODE (operands[3]) == GT)
4845 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
4847 output_asm_insn (\"cmp\\t%1, %2\", operands);
4848 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
4849 return \"mvn%d3\\t%0, #0\";
4851 [(set_attr "conds" "clob")
4852 (set_attr "length" "12")])
4854 (define_insn "movcond"
4855 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
4857 (match_operator 5 "comparison_operator"
4858 [(match_operand:SI 3 "s_register_operand" "r,r,r")
4859 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
4860 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
4861 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
4862 (clobber (reg:CC 24))]
4865 if (GET_CODE (operands[5]) == LT
4866 && (operands[4] == const0_rtx))
4868 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4870 if (operands[2] == const0_rtx)
4871 return \"and\\t%0, %1, %3, asr #31\";
4872 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
4874 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4876 if (operands[1] == const0_rtx)
4877 return \"bic\\t%0, %2, %3, asr #31\";
4878 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
4880 /* The only case that falls through to here is when both ops 1 & 2
4884 if (GET_CODE (operands[5]) == GE
4885 && (operands[4] == const0_rtx))
4887 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
4889 if (operands[2] == const0_rtx)
4890 return \"bic\\t%0, %1, %3, asr #31\";
4891 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
4893 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
4895 if (operands[1] == const0_rtx)
4896 return \"and\\t%0, %2, %3, asr #31\";
4897 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
4899 /* The only case that falls through to here is when both ops 1 & 2
4902 if (GET_CODE (operands[4]) == CONST_INT
4903 && !const_ok_for_arm (INTVAL (operands[4])))
4904 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
4906 output_asm_insn (\"cmp\\t%3, %4\", operands);
4907 if (which_alternative != 0)
4908 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
4909 if (which_alternative != 1)
4910 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
4913 [(set_attr "conds" "clob")
4914 (set_attr "length" "8,8,12")])
4916 (define_insn "*ifcompare_plus_move"
4917 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4918 (if_then_else:SI (match_operator 6 "comparison_operator"
4919 [(match_operand:SI 4 "s_register_operand" "r,r")
4920 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4922 (match_operand:SI 2 "s_register_operand" "r,r")
4923 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
4924 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
4925 (clobber (reg:CC 24))]
4928 [(set_attr "conds" "clob")
4929 (set_attr "length" "8,12")])
4931 (define_insn "*if_plus_move"
4932 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4934 (match_operator 4 "comparison_operator"
4935 [(match_operand 5 "cc_register" "") (const_int 0)])
4937 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
4938 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
4939 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
4943 sub%d4\\t%0, %2, #%n3
4944 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
4945 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
4946 [(set_attr "conds" "use")
4947 (set_attr "length" "4,4,8,8")
4948 (set_attr "type" "*,*,*,*")])
4950 (define_insn "*ifcompare_move_plus"
4951 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4952 (if_then_else:SI (match_operator 6 "comparison_operator"
4953 [(match_operand:SI 4 "s_register_operand" "r,r")
4954 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
4955 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
4957 (match_operand:SI 2 "s_register_operand" "r,r")
4958 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
4959 (clobber (reg:CC 24))]
4962 [(set_attr "conds" "clob")
4963 (set_attr "length" "8,12")])
4965 (define_insn "*if_move_plus"
4966 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
4968 (match_operator 4 "comparison_operator"
4969 [(match_operand 5 "cc_register" "") (const_int 0)])
4970 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
4972 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
4973 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
4977 sub%D4\\t%0, %2, #%n3
4978 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
4979 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
4980 [(set_attr "conds" "use")
4981 (set_attr "length" "4,4,8,8")
4982 (set_attr "type" "*,*,*,*")])
4984 (define_insn "*ifcompare_arith_arith"
4985 [(set (match_operand:SI 0 "s_register_operand" "=r")
4986 (if_then_else:SI (match_operator 9 "comparison_operator"
4987 [(match_operand:SI 5 "s_register_operand" "r")
4988 (match_operand:SI 6 "arm_add_operand" "rIL")])
4989 (match_operator:SI 8 "shiftable_operator"
4990 [(match_operand:SI 1 "s_register_operand" "r")
4991 (match_operand:SI 2 "arm_rhs_operand" "rI")])
4992 (match_operator:SI 7 "shiftable_operator"
4993 [(match_operand:SI 3 "s_register_operand" "r")
4994 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
4995 (clobber (reg:CC 24))]
4998 [(set_attr "conds" "clob")
4999 (set_attr "length" "12")])
5001 (define_insn "*if_arith_arith"
5002 [(set (match_operand:SI 0 "s_register_operand" "=r")
5003 (if_then_else:SI (match_operator 5 "comparison_operator"
5004 [(match_operand 8 "cc_register" "") (const_int 0)])
5005 (match_operator:SI 6 "shiftable_operator"
5006 [(match_operand:SI 1 "s_register_operand" "r")
5007 (match_operand:SI 2 "arm_rhs_operand" "rI")])
5008 (match_operator:SI 7 "shiftable_operator"
5009 [(match_operand:SI 3 "s_register_operand" "r")
5010 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
5012 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
5013 [(set_attr "conds" "use")
5014 (set_attr "length" "8")])
5016 (define_insn "*ifcompare_arith_move"
5017 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5018 (if_then_else:SI (match_operator 6 "comparison_operator"
5019 [(match_operand:SI 2 "s_register_operand" "r,r")
5020 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
5021 (match_operator:SI 7 "shiftable_operator"
5022 [(match_operand:SI 4 "s_register_operand" "r,r")
5023 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
5024 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
5025 (clobber (reg:CC 24))]
5028 /* If we have an operation where (op x 0) is the identity operation and
5029 the conditional operator is LT or GE and we are comparing against zero and
5030 everything is in registers then we can do this in two instructions */
5031 if (operands[3] == const0_rtx
5032 && GET_CODE (operands[7]) != AND
5033 && GET_CODE (operands[5]) == REG
5034 && GET_CODE (operands[1]) == REG
5035 && REGNO (operands[1]) == REGNO (operands[4])
5036 && REGNO (operands[4]) != REGNO (operands[0]))
5038 if (GET_CODE (operands[6]) == LT)
5039 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
5040 else if (GET_CODE (operands[6]) == GE)
5041 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
5043 if (GET_CODE (operands[3]) == CONST_INT
5044 && !const_ok_for_arm (INTVAL (operands[3])))
5045 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
5047 output_asm_insn (\"cmp\\t%2, %3\", operands);
5048 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
5049 if (which_alternative != 0)
5050 return \"mov%D6\\t%0, %1\";
5053 [(set_attr "conds" "clob")
5054 (set_attr "length" "8,12")])
5056 (define_insn "*if_arith_move"
5057 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5058 (if_then_else:SI (match_operator 4 "comparison_operator"
5059 [(match_operand 6 "cc_register" "") (const_int 0)])
5060 (match_operator:SI 5 "shiftable_operator"
5061 [(match_operand:SI 2 "s_register_operand" "r,r")
5062 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
5063 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
5067 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
5068 [(set_attr "conds" "use")
5069 (set_attr "length" "4,8")
5070 (set_attr "type" "*,*")])
5072 (define_insn "*ifcompare_move_arith"
5073 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5074 (if_then_else:SI (match_operator 6 "comparison_operator"
5075 [(match_operand:SI 4 "s_register_operand" "r,r")
5076 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5077 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5078 (match_operator:SI 7 "shiftable_operator"
5079 [(match_operand:SI 2 "s_register_operand" "r,r")
5080 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
5081 (clobber (reg:CC 24))]
5084 /* If we have an operation where (op x 0) is the identity operation and
5085 the conditional operator is LT or GE and we are comparing against zero and
5086 everything is in registers then we can do this in two instructions */
5087 if (operands[5] == const0_rtx
5088 && GET_CODE (operands[7]) != AND
5089 && GET_CODE (operands[3]) == REG
5090 && GET_CODE (operands[1]) == REG
5091 && REGNO (operands[1]) == REGNO (operands[2])
5092 && REGNO (operands[2]) != REGNO (operands[0]))
5094 if (GET_CODE (operands[6]) == GE)
5095 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
5096 else if (GET_CODE (operands[6]) == LT)
5097 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
5100 if (GET_CODE (operands[5]) == CONST_INT
5101 && !const_ok_for_arm (INTVAL (operands[5])))
5102 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
5104 output_asm_insn (\"cmp\\t%4, %5\", operands);
5106 if (which_alternative != 0)
5107 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
5108 return \"%I7%D6\\t%0, %2, %3\";
5110 [(set_attr "conds" "clob")
5111 (set_attr "length" "8,12")])
5113 (define_insn "*if_move_arith"
5114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5116 (match_operator 4 "comparison_operator"
5117 [(match_operand 6 "cc_register" "") (const_int 0)])
5118 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
5119 (match_operator:SI 5 "shiftable_operator"
5120 [(match_operand:SI 2 "s_register_operand" "r,r")
5121 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
5125 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
5126 [(set_attr "conds" "use")
5127 (set_attr "length" "4,8")
5128 (set_attr "type" "*,*")])
5130 (define_insn "*ifcompare_move_not"
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")])
5136 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5138 (match_operand:SI 2 "s_register_operand" "r,r"))))
5139 (clobber (reg:CC 24))]
5142 [(set_attr "conds" "clob")
5143 (set_attr "length" "8,12")])
5145 (define_insn "*if_move_not"
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 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5151 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
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_not_move"
5161 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5163 (match_operator 5 "comparison_operator"
5164 [(match_operand:SI 3 "s_register_operand" "r,r")
5165 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5167 (match_operand:SI 2 "s_register_operand" "r,r"))
5168 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5169 (clobber (reg:CC 24))]
5172 [(set_attr "conds" "clob")
5173 (set_attr "length" "8,12")])
5175 (define_insn "*if_not_move"
5176 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5178 (match_operator 4 "comparison_operator"
5179 [(match_operand 3 "cc_register" "") (const_int 0)])
5180 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
5181 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5185 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
5186 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
5187 [(set_attr "conds" "use")
5188 (set_attr "length" "4,8,8")])
5190 (define_insn "*ifcompare_shift_move"
5191 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5193 (match_operator 6 "comparison_operator"
5194 [(match_operand:SI 4 "s_register_operand" "r,r")
5195 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5196 (match_operator:SI 7 "shift_operator"
5197 [(match_operand:SI 2 "s_register_operand" "r,r")
5198 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
5199 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5200 (clobber (reg:CC 24))]
5203 [(set_attr "conds" "clob")
5204 (set_attr "length" "8,12")])
5206 (define_insn "*if_shift_move"
5207 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5209 (match_operator 5 "comparison_operator"
5210 [(match_operand 6 "cc_register" "") (const_int 0)])
5211 (match_operator:SI 4 "shift_operator"
5212 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5213 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
5214 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5218 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
5219 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
5220 [(set_attr "conds" "use")
5221 (set_attr "length" "4,8,8")])
5223 (define_insn "*ifcompare_move_shift"
5224 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5226 (match_operator 6 "comparison_operator"
5227 [(match_operand:SI 4 "s_register_operand" "r,r")
5228 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
5229 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5230 (match_operator:SI 7 "shift_operator"
5231 [(match_operand:SI 2 "s_register_operand" "r,r")
5232 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
5233 (clobber (reg:CC 24))]
5236 [(set_attr "conds" "clob")
5237 (set_attr "length" "8,12")])
5239 (define_insn "*if_move_shift"
5240 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5242 (match_operator 5 "comparison_operator"
5243 [(match_operand 6 "cc_register" "") (const_int 0)])
5244 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5245 (match_operator:SI 4 "shift_operator"
5246 [(match_operand:SI 2 "s_register_operand" "r,r,r")
5247 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
5251 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
5252 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
5253 [(set_attr "conds" "use")
5254 (set_attr "length" "4,8,8")])
5256 (define_insn "*ifcompare_shift_shift"
5257 [(set (match_operand:SI 0 "s_register_operand" "=r")
5259 (match_operator 7 "comparison_operator"
5260 [(match_operand:SI 5 "s_register_operand" "r")
5261 (match_operand:SI 6 "arm_add_operand" "rIL")])
5262 (match_operator:SI 8 "shift_operator"
5263 [(match_operand:SI 1 "s_register_operand" "r")
5264 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5265 (match_operator:SI 9 "shift_operator"
5266 [(match_operand:SI 3 "s_register_operand" "r")
5267 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
5268 (clobber (reg:CC 24))]
5271 [(set_attr "conds" "clob")
5272 (set_attr "length" "12")])
5274 (define_insn "*if_shift_shift"
5275 [(set (match_operand:SI 0 "s_register_operand" "=r")
5277 (match_operator 5 "comparison_operator"
5278 [(match_operand 8 "cc_register" "") (const_int 0)])
5279 (match_operator:SI 6 "shift_operator"
5280 [(match_operand:SI 1 "s_register_operand" "r")
5281 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5282 (match_operator:SI 7 "shift_operator"
5283 [(match_operand:SI 3 "s_register_operand" "r")
5284 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
5286 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
5287 [(set_attr "conds" "use")
5288 (set_attr "length" "8")])
5290 (define_insn "*ifcompare_not_arith"
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 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5297 (match_operator:SI 7 "shiftable_operator"
5298 [(match_operand:SI 2 "s_register_operand" "r")
5299 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
5300 (clobber (reg:CC 24))]
5303 [(set_attr "conds" "clob")
5304 (set_attr "length" "12")])
5306 (define_insn "*if_not_arith"
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 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5312 (match_operator:SI 6 "shiftable_operator"
5313 [(match_operand:SI 2 "s_register_operand" "r")
5314 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
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_arith_not"
5321 [(set (match_operand:SI 0 "s_register_operand" "=r")
5323 (match_operator 6 "comparison_operator"
5324 [(match_operand:SI 4 "s_register_operand" "r")
5325 (match_operand:SI 5 "arm_add_operand" "rIL")])
5326 (match_operator:SI 7 "shiftable_operator"
5327 [(match_operand:SI 2 "s_register_operand" "r")
5328 (match_operand:SI 3 "arm_rhs_operand" "rI")])
5329 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
5330 (clobber (reg:CC 24))]
5333 [(set_attr "conds" "clob")
5334 (set_attr "length" "12")])
5336 (define_insn "*if_arith_not"
5337 [(set (match_operand:SI 0 "s_register_operand" "=r")
5339 (match_operator 5 "comparison_operator"
5340 [(match_operand 4 "cc_register" "") (const_int 0)])
5341 (match_operator:SI 6 "shiftable_operator"
5342 [(match_operand:SI 2 "s_register_operand" "r")
5343 (match_operand:SI 3 "arm_rhs_operand" "rI")])
5344 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
5346 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
5347 [(set_attr "conds" "use")
5348 (set_attr "length" "8")])
5350 (define_insn "*ifcompare_neg_move"
5351 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5353 (match_operator 5 "comparison_operator"
5354 [(match_operand:SI 3 "s_register_operand" "r,r")
5355 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5356 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
5357 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
5358 (clobber (reg:CC 24))]
5361 [(set_attr "conds" "clob")
5362 (set_attr "length" "8,12")])
5364 (define_insn "*if_neg_move"
5365 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5367 (match_operator 4 "comparison_operator"
5368 [(match_operand 3 "cc_register" "") (const_int 0)])
5369 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
5370 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
5374 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
5375 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
5376 [(set_attr "conds" "use")
5377 (set_attr "length" "4,8,8")])
5379 (define_insn "*ifcompare_move_neg"
5380 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5382 (match_operator 5 "comparison_operator"
5383 [(match_operand:SI 3 "s_register_operand" "r,r")
5384 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
5385 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5386 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
5387 (clobber (reg:CC 24))]
5390 [(set_attr "conds" "clob")
5391 (set_attr "length" "8,12")])
5393 (define_insn "*if_move_neg"
5394 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5396 (match_operator 4 "comparison_operator"
5397 [(match_operand 3 "cc_register" "") (const_int 0)])
5398 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
5399 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
5403 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
5404 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
5405 [(set_attr "conds" "use")
5406 (set_attr "length" "4,8,8")])
5408 (define_insn "*arith_adjacentmem"
5409 [(set (match_operand:SI 0 "s_register_operand" "=r")
5410 (match_operator:SI 1 "shiftable_operator"
5411 [(match_operand:SI 2 "memory_operand" "m")
5412 (match_operand:SI 3 "memory_operand" "m")]))
5413 (clobber (match_scratch:SI 4 "=r"))]
5414 "adjacent_mem_locations (operands[2], operands[3])"
5419 int val1 = 0, val2 = 0;
5421 if (REGNO (operands[0]) > REGNO (operands[4]))
5423 ldm[1] = operands[4];
5424 ldm[2] = operands[0];
5428 ldm[1] = operands[0];
5429 ldm[2] = operands[4];
5431 if (GET_CODE (XEXP (operands[2], 0)) != REG)
5432 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
5433 if (GET_CODE (XEXP (operands[3], 0)) != REG)
5434 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
5435 arith[0] = operands[0];
5436 arith[3] = operands[1];
5450 ldm[0] = ops[0] = operands[4];
5451 ops[1] = XEXP (XEXP (operands[2], 0), 0);
5452 ops[2] = XEXP (XEXP (operands[2], 0), 1);
5453 output_add_immediate (ops);
5455 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5457 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5461 ldm[0] = XEXP (operands[3], 0);
5463 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5465 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5469 ldm[0] = XEXP (operands[2], 0);
5471 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
5473 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
5475 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
5479 [(set_attr "length" "12")
5480 (set_attr "type" "load")])
5482 ;; the arm can support extended pre-inc instructions
5484 ;; In all these cases, we use operands 0 and 1 for the register being
5485 ;; incremented because those are the operands that local-alloc will
5486 ;; tie and these are the pair most likely to be tieable (and the ones
5487 ;; that will benefit the most).
5489 ;; We reject the frame pointer if it occurs anywhere in these patterns since
5490 ;; elimination will cause too many headaches.
5492 (define_insn "*strqi_preinc"
5493 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5494 (match_operand:SI 2 "index_operand" "rJ")))
5495 (match_operand:QI 3 "s_register_operand" "r"))
5496 (set (match_operand:SI 0 "s_register_operand" "=r")
5497 (plus:SI (match_dup 1) (match_dup 2)))]
5498 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5499 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5500 && (GET_CODE (operands[2]) != REG
5501 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5502 "str%?b\\t%3, [%0, %2]!"
5503 [(set_attr "type" "store1")])
5505 (define_insn "*strqi_predec"
5506 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5507 (match_operand:SI 2 "s_register_operand" "r")))
5508 (match_operand:QI 3 "s_register_operand" "r"))
5509 (set (match_operand:SI 0 "s_register_operand" "=r")
5510 (minus:SI (match_dup 1) (match_dup 2)))]
5511 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5512 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5513 && (GET_CODE (operands[2]) != REG
5514 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5515 "str%?b\\t%3, [%0, -%2]!"
5516 [(set_attr "type" "store1")])
5518 (define_insn "*loadqi_preinc"
5519 [(set (match_operand:QI 3 "s_register_operand" "=r")
5520 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5521 (match_operand:SI 2 "index_operand" "rJ"))))
5522 (set (match_operand:SI 0 "s_register_operand" "=r")
5523 (plus:SI (match_dup 1) (match_dup 2)))]
5524 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5525 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5526 && (GET_CODE (operands[2]) != REG
5527 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5528 "ldr%?b\\t%3, [%0, %2]!"
5529 [(set_attr "type" "load")])
5531 (define_insn "*loadqi_predec"
5532 [(set (match_operand:QI 3 "s_register_operand" "=r")
5533 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5534 (match_operand:SI 2 "s_register_operand" "r"))))
5535 (set (match_operand:SI 0 "s_register_operand" "=r")
5536 (minus:SI (match_dup 1) (match_dup 2)))]
5537 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5538 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5539 && (GET_CODE (operands[2]) != REG
5540 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5541 "ldr%?b\\t%3, [%0, -%2]!"
5542 [(set_attr "type" "load")])
5544 (define_insn "*loadqisi_preinc"
5545 [(set (match_operand:SI 3 "s_register_operand" "=r")
5547 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5548 (match_operand:SI 2 "index_operand" "rJ")))))
5549 (set (match_operand:SI 0 "s_register_operand" "=r")
5550 (plus:SI (match_dup 1) (match_dup 2)))]
5551 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5552 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5553 && (GET_CODE (operands[2]) != REG
5554 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5555 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
5556 [(set_attr "type" "load")])
5558 (define_insn "*loadqisi_predec"
5559 [(set (match_operand:SI 3 "s_register_operand" "=r")
5561 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5562 (match_operand:SI 2 "s_register_operand" "r")))))
5563 (set (match_operand:SI 0 "s_register_operand" "=r")
5564 (minus:SI (match_dup 1) (match_dup 2)))]
5565 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5566 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5567 && (GET_CODE (operands[2]) != REG
5568 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5569 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
5570 [(set_attr "type" "load")])
5572 (define_insn "*strsi_preinc"
5573 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5574 (match_operand:SI 2 "index_operand" "rJ")))
5575 (match_operand:SI 3 "s_register_operand" "r"))
5576 (set (match_operand:SI 0 "s_register_operand" "=r")
5577 (plus:SI (match_dup 1) (match_dup 2)))]
5578 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5579 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5580 && (GET_CODE (operands[2]) != REG
5581 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5582 "str%?\\t%3, [%0, %2]!"
5583 [(set_attr "type" "store1")])
5585 (define_insn "*strqi_predec"
5586 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5587 (match_operand:SI 2 "s_register_operand" "r")))
5588 (match_operand:SI 3 "s_register_operand" "r"))
5589 (set (match_operand:SI 0 "s_register_operand" "=r")
5590 (minus:SI (match_dup 1) (match_dup 2)))]
5591 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5592 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5593 && (GET_CODE (operands[2]) != REG
5594 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5595 "str%?\\t%3, [%0, -%2]!"
5596 [(set_attr "type" "store1")])
5598 (define_insn "*loadsi_preinc"
5599 [(set (match_operand:SI 3 "s_register_operand" "=r")
5600 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5601 (match_operand:SI 2 "index_operand" "rJ"))))
5602 (set (match_operand:SI 0 "s_register_operand" "=r")
5603 (plus:SI (match_dup 1) (match_dup 2)))]
5604 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5605 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5606 && (GET_CODE (operands[2]) != REG
5607 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5608 "ldr%?\\t%3, [%0, %2]!"
5609 [(set_attr "type" "load")])
5611 (define_insn "*loadsi_predec"
5612 [(set (match_operand:SI 3 "s_register_operand" "=r")
5613 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5614 (match_operand:SI 2 "s_register_operand" "r"))))
5615 (set (match_operand:SI 0 "s_register_operand" "=r")
5616 (minus:SI (match_dup 1) (match_dup 2)))]
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]!"
5622 [(set_attr "type" "load")])
5624 (define_insn "*loadhi_preinc"
5625 [(set (match_operand:HI 3 "s_register_operand" "=r")
5626 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
5627 (match_operand:SI 2 "index_operand" "rJ"))))
5628 (set (match_operand:SI 0 "s_register_operand" "=r")
5629 (plus:SI (match_dup 1) (match_dup 2)))]
5630 "(! BYTES_BIG_ENDIAN)
5631 && ! TARGET_SHORT_BY_BYTES
5632 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5633 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5634 && (GET_CODE (operands[2]) != REG
5635 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5636 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
5637 [(set_attr "type" "load")])
5639 (define_insn "*loadhi_predec"
5640 [(set (match_operand:HI 3 "s_register_operand" "=r")
5641 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5642 (match_operand:SI 2 "s_register_operand" "r"))))
5643 (set (match_operand:SI 0 "s_register_operand" "=r")
5644 (minus:SI (match_dup 1) (match_dup 2)))]
5645 "(!BYTES_BIG_ENDIAN)
5646 && ! TARGET_SHORT_BY_BYTES
5647 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5648 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5649 && (GET_CODE (operands[2]) != REG
5650 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
5651 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
5652 [(set_attr "type" "load")])
5654 (define_insn "*strqi_shiftpreinc"
5655 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5656 [(match_operand:SI 3 "s_register_operand" "r")
5657 (match_operand:SI 4 "const_shift_operand" "n")])
5658 (match_operand:SI 1 "s_register_operand" "0")))
5659 (match_operand:QI 5 "s_register_operand" "r"))
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 "str%?b\\t%5, [%0, %3%S2]!"
5667 [(set_attr "type" "store1")])
5669 (define_insn "*strqi_shiftpredec"
5670 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5671 (match_operator:SI 2 "shift_operator"
5672 [(match_operand:SI 3 "s_register_operand" "r")
5673 (match_operand:SI 4 "const_shift_operand" "n")])))
5674 (match_operand:QI 5 "s_register_operand" "r"))
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 "str%?b\\t%5, [%0, -%3%S2]!"
5682 [(set_attr "type" "store1")])
5684 (define_insn "*loadqi_shiftpreinc"
5685 [(set (match_operand:QI 5 "s_register_operand" "=r")
5686 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
5687 [(match_operand:SI 3 "s_register_operand" "r")
5688 (match_operand:SI 4 "const_shift_operand" "n")])
5689 (match_operand:SI 1 "s_register_operand" "0"))))
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 "ldr%?b\\t%5, [%0, %3%S2]!"
5697 [(set_attr "type" "load")])
5699 (define_insn "*loadqi_shiftpredec"
5700 [(set (match_operand:QI 5 "s_register_operand" "=r")
5701 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5702 (match_operator:SI 2 "shift_operator"
5703 [(match_operand:SI 3 "s_register_operand" "r")
5704 (match_operand:SI 4 "const_shift_operand" "n")]))))
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 "ldr%?b\\t%5, [%0, -%3%S2]!"
5712 [(set_attr "type" "load")])
5714 (define_insn "*strsi_shiftpreinc"
5715 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
5716 [(match_operand:SI 3 "s_register_operand" "r")
5717 (match_operand:SI 4 "const_shift_operand" "n")])
5718 (match_operand:SI 1 "s_register_operand" "0")))
5719 (match_operand:SI 5 "s_register_operand" "r"))
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 "str%?\\t%5, [%0, %3%S2]!"
5727 [(set_attr "type" "store1")])
5729 (define_insn "*strsi_shiftpredec"
5730 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5731 (match_operator:SI 2 "shift_operator"
5732 [(match_operand:SI 3 "s_register_operand" "r")
5733 (match_operand:SI 4 "const_shift_operand" "n")])))
5734 (match_operand:SI 5 "s_register_operand" "r"))
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 "str%?\\t%5, [%0, -%3%S2]!"
5742 [(set_attr "type" "store1")])
5744 (define_insn "*loadqi_shiftpreinc"
5745 [(set (match_operand:SI 5 "s_register_operand" "=r")
5746 (mem:SI (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 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5754 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5755 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5756 "ldr%?\\t%5, [%0, %3%S2]!"
5757 [(set_attr "type" "load")])
5759 (define_insn "*loadqi_shiftpredec"
5760 [(set (match_operand:SI 5 "s_register_operand" "=r")
5761 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5762 (match_operator:SI 2 "shift_operator"
5763 [(match_operand:SI 3 "s_register_operand" "r")
5764 (match_operand:SI 4 "const_shift_operand" "n")]))))
5765 (set (match_operand:SI 0 "s_register_operand" "=r")
5766 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5768 "REGNO (operands[0]) != FRAME_POINTER_REGNUM
5769 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5770 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5771 "ldr%?\\t%5, [%0, -%3%S2]!"
5772 [(set_attr "type" "load")])
5774 (define_insn "*loadhi_shiftpreinc"
5775 [(set (match_operand:HI 5 "s_register_operand" "=r")
5776 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
5777 [(match_operand:SI 3 "s_register_operand" "r")
5778 (match_operand:SI 4 "const_shift_operand" "n")])
5779 (match_operand:SI 1 "s_register_operand" "0"))))
5780 (set (match_operand:SI 0 "s_register_operand" "=r")
5781 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
5783 "(! BYTES_BIG_ENDIAN)
5784 && ! TARGET_SHORT_BY_BYTES
5785 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5786 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5787 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5788 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
5789 [(set_attr "type" "load")])
5791 (define_insn "*loadhi_shiftpredec"
5792 [(set (match_operand:HI 5 "s_register_operand" "=r")
5793 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
5794 (match_operator:SI 2 "shift_operator"
5795 [(match_operand:SI 3 "s_register_operand" "r")
5796 (match_operand:SI 4 "const_shift_operand" "n")]))))
5797 (set (match_operand:SI 0 "s_register_operand" "=r")
5798 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
5800 "(! BYTES_BIG_ENDIAN)
5801 && ! TARGET_SHORT_BY_BYTES
5802 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
5803 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
5804 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
5805 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
5806 [(set_attr "type" "load")])
5808 ; It can also support extended post-inc expressions, but combine doesn't
5810 ; It doesn't seem worth adding peepholes for anything but the most common
5811 ; cases since, unlike combine, the increment must immediately follow the load
5812 ; for this pattern to match.
5813 ; When loading we must watch to see that the base register isn't trampled by
5814 ; the load. In such cases this isn't a post-inc expression.
5817 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
5818 (match_operand:QI 2 "s_register_operand" "r"))
5820 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5822 "str%?b\\t%2, [%0], %1")
5825 [(set (match_operand:QI 0 "s_register_operand" "=r")
5826 (mem:QI (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%?b\\t%0, [%1], %2")
5835 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
5836 (match_operand:SI 2 "s_register_operand" "r"))
5838 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
5840 "str%?\\t%2, [%0], %1")
5843 [(set (match_operand:HI 0 "s_register_operand" "=r")
5844 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
5846 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5847 "(! BYTES_BIG_ENDIAN)
5848 && ! TARGET_SHORT_BY_BYTES
5849 && REGNO(operands[0]) != REGNO(operands[1])
5850 && (GET_CODE (operands[2]) != REG
5851 || REGNO(operands[0]) != REGNO (operands[2]))"
5852 "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
5855 [(set (match_operand:SI 0 "s_register_operand" "=r")
5856 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
5858 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
5859 "REGNO(operands[0]) != REGNO(operands[1])
5860 && (GET_CODE (operands[2]) != REG
5861 || REGNO(operands[0]) != REGNO (operands[2]))"
5862 "ldr%?\\t%0, [%1], %2")
5865 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
5866 (match_operand:SI 1 "index_operand" "rJ")))
5867 (match_operand:QI 2 "s_register_operand" "r"))
5868 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
5870 "str%?b\\t%2, [%0, %1]!")
5873 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
5874 [(match_operand:SI 0 "s_register_operand" "r")
5875 (match_operand:SI 1 "const_int_operand" "n")])
5876 (match_operand:SI 2 "s_register_operand" "+r")))
5877 (match_operand:QI 3 "s_register_operand" "r"))
5878 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
5881 "str%?b\\t%3, [%2, %0%S4]!")
5883 ; This pattern is never tried by combine, so do it as a peephole
5886 [(set (match_operand:SI 0 "s_register_operand" "=r")
5887 (match_operand:SI 1 "s_register_operand" "r"))
5889 (compare:CC (match_dup 1) (const_int 0)))]
5891 "sub%?s\\t%0, %1, #0"
5892 [(set_attr "conds" "set")])
5894 ; Peepholes to spot possible load- and store-multiples, if the ordering is
5895 ; reversed, check that the memory references aren't volatile.
5898 [(set (match_operand:SI 0 "s_register_operand" "=r")
5899 (match_operand:SI 4 "memory_operand" "m"))
5900 (set (match_operand:SI 1 "s_register_operand" "=r")
5901 (match_operand:SI 5 "memory_operand" "m"))
5902 (set (match_operand:SI 2 "s_register_operand" "=r")
5903 (match_operand:SI 6 "memory_operand" "m"))
5904 (set (match_operand:SI 3 "s_register_operand" "=r")
5905 (match_operand:SI 7 "memory_operand" "m"))]
5906 "load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5908 return emit_ldm_seq (operands, 4);
5912 [(set (match_operand:SI 0 "s_register_operand" "=r")
5913 (match_operand:SI 3 "memory_operand" "m"))
5914 (set (match_operand:SI 1 "s_register_operand" "=r")
5915 (match_operand:SI 4 "memory_operand" "m"))
5916 (set (match_operand:SI 2 "s_register_operand" "=r")
5917 (match_operand:SI 5 "memory_operand" "m"))]
5918 "load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5920 return emit_ldm_seq (operands, 3);
5924 [(set (match_operand:SI 0 "s_register_operand" "=r")
5925 (match_operand:SI 2 "memory_operand" "m"))
5926 (set (match_operand:SI 1 "s_register_operand" "=r")
5927 (match_operand:SI 3 "memory_operand" "m"))]
5928 "load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5930 return emit_ldm_seq (operands, 2);
5934 [(set (match_operand:SI 4 "memory_operand" "=m")
5935 (match_operand:SI 0 "s_register_operand" "r"))
5936 (set (match_operand:SI 5 "memory_operand" "=m")
5937 (match_operand:SI 1 "s_register_operand" "r"))
5938 (set (match_operand:SI 6 "memory_operand" "=m")
5939 (match_operand:SI 2 "s_register_operand" "r"))
5940 (set (match_operand:SI 7 "memory_operand" "=m")
5941 (match_operand:SI 3 "s_register_operand" "r"))]
5942 "store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
5944 return emit_stm_seq (operands, 4);
5948 [(set (match_operand:SI 3 "memory_operand" "=m")
5949 (match_operand:SI 0 "s_register_operand" "r"))
5950 (set (match_operand:SI 4 "memory_operand" "=m")
5951 (match_operand:SI 1 "s_register_operand" "r"))
5952 (set (match_operand:SI 5 "memory_operand" "=m")
5953 (match_operand:SI 2 "s_register_operand" "r"))]
5954 "store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
5956 return emit_stm_seq (operands, 3);
5960 [(set (match_operand:SI 2 "memory_operand" "=m")
5961 (match_operand:SI 0 "s_register_operand" "r"))
5962 (set (match_operand:SI 3 "memory_operand" "=m")
5963 (match_operand:SI 1 "s_register_operand" "r"))]
5964 "store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
5966 return emit_stm_seq (operands, 2);
5969 ;; A call followed by return can be replaced by restoring the regs and
5970 ;; jumping to the subroutine, provided we aren't passing the address of
5971 ;; any of our local variables. If we call alloca then this is unsafe
5972 ;; since restoring the frame frees the memory, which is not what we want.
5973 ;; Sometimes the return might have been targeted by the final prescan:
5974 ;; if so then emit a proper return insn as well.
5975 ;; Unfortunately, if the frame pointer is required, we don't know if the
5976 ;; current function has any implicit stack pointer adjustments that will
5977 ;; be restored by the return: we can't therefore do a tail call.
5978 ;; Another unfortunate that we can't handle is if current_function_args_size
5979 ;; is non-zero: in this case elimination of the argument pointer assumed
5980 ;; that lr was pushed onto the stack, so eliminating upsets the offset
5984 [(parallel [(call (mem:SI (match_operand:SI 0 "" "X"))
5985 (match_operand:SI 1 "general_operand" "g"))
5986 (clobber (reg:SI 14))])
5988 "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
5989 && !get_frame_size () && !current_function_calls_alloca
5990 && !frame_pointer_needed && !current_function_args_size)"
5993 extern rtx arm_target_insn;
5994 extern int arm_ccfsm_state;
5996 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
5998 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
5999 output_return_instruction (NULL, TRUE, FALSE);
6000 arm_ccfsm_state = 0;
6001 arm_target_insn = NULL;
6004 output_return_instruction (NULL, FALSE, FALSE);
6005 return \"b%?\\t%a0\";
6007 [(set_attr "type" "call")
6008 (set_attr "length" "8")])
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))])
6016 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
6017 && !get_frame_size () && !current_function_calls_alloca
6018 && !frame_pointer_needed && !current_function_args_size)"
6021 extern rtx arm_target_insn;
6022 extern int arm_ccfsm_state;
6024 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
6026 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6027 output_return_instruction (NULL, TRUE, FALSE);
6028 arm_ccfsm_state = 0;
6029 arm_target_insn = NULL;
6032 output_return_instruction (NULL, FALSE, FALSE);
6033 return \"b%?\\t%a1\";
6035 [(set_attr "type" "call")
6036 (set_attr "length" "8")])
6038 ;; As above but when this function is not void, we must be returning the
6039 ;; result of the called subroutine.
6042 [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
6043 (call (mem:SI (match_operand:SI 1 "" "X"))
6044 (match_operand:SI 2 "general_operand" "g")))
6045 (clobber (reg:SI 14))])
6048 "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
6049 && !get_frame_size () && !current_function_calls_alloca
6050 && !frame_pointer_needed && !current_function_args_size)"
6053 extern rtx arm_target_insn;
6054 extern int arm_ccfsm_state;
6056 if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
6058 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6059 output_return_instruction (NULL, TRUE, FALSE);
6060 arm_ccfsm_state = 0;
6061 arm_target_insn = NULL;
6064 output_return_instruction (NULL, FALSE, FALSE);
6065 return \"b%?\\t%a1\";
6067 [(set_attr "type" "call")
6068 (set_attr "length" "8")])
6071 [(set (match_operand:SI 0 "s_register_operand" "")
6072 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
6074 (neg:SI (match_operator:SI 2 "comparison_operator"
6075 [(match_operand:SI 3 "s_register_operand" "")
6076 (match_operand:SI 4 "arm_rhs_operand" "")]))))
6077 (clobber (match_operand:SI 5 "s_register_operand" ""))]
6079 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
6080 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
6084 ;; This split can be used because CC_Z mode implies that the following
6085 ;; branch will be an equality, or an unsigned inequality, so the sign
6086 ;; extension is not needed.
6091 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
6093 (match_operand 1 "const_int_operand" "")))
6094 (clobber (match_scratch:SI 2 ""))]
6095 "((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
6096 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24"
6097 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
6098 (set (reg:CC 24) (compare:CC (match_dup 2) (match_dup 1)))]
6100 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
6103 (define_expand "prologue"
6104 [(clobber (const_int 0))]
6107 arm_expand_prologue ();
6111 ;; This split is only used during output to reduce the number of patterns
6112 ;; that need assembler instructions adding to them. We allowed the setting
6113 ;; of the conditions to be implicit during rtl generation so that
6114 ;; the conditional compare patterns would work. However this conflicts to
6115 ;; some extent with the conditional data operations, so we have to split them
6119 [(set (match_operand:SI 0 "s_register_operand" "")
6120 (if_then_else:SI (match_operator 1 "comparison_operator"
6121 [(match_operand 2 "" "") (match_operand 3 "" "")])
6122 (match_operand 4 "" "")
6123 (match_operand 5 "" "")))
6124 (clobber (reg:CC 24))]
6126 [(set (match_dup 6) (match_dup 7))
6128 (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
6133 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
6136 operands[6] = gen_rtx_REG (mode, 24);
6137 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
6141 ;; The next two patterns occur when an AND operation is followed by a
6142 ;; scc insn sequence
6144 (define_insn "*sign_extract_onebit"
6145 [(set (match_operand:SI 0 "s_register_operand" "=r")
6146 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
6148 (match_operand:SI 2 "const_int_operand" "n")))]
6151 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6152 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
6153 return \"mvnne\\t%0, #0\";
6155 [(set_attr "conds" "clob")
6156 (set_attr "length" "8")])
6158 (define_insn "*not_signextract_onebit"
6159 [(set (match_operand:SI 0 "s_register_operand" "=r")
6161 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
6163 (match_operand:SI 2 "const_int_operand" "n"))))]
6166 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6167 output_asm_insn (\"tst\\t%1, %2\", operands);
6168 output_asm_insn (\"mvneq\\t%0, #0\", operands);
6169 return \"movne\\t%0, #0\";
6171 [(set_attr "conds" "clob")
6172 (set_attr "length" "12")])
6174 ;; Push multiple registers to the stack. The first register is in the
6175 ;; unspec part of the insn; subsequent registers are in parallel (use ...)
6177 (define_insn "*push_multi"
6178 [(match_parallel 2 "multi_register_push"
6179 [(set (match_operand:BLK 0 "memory_operand" "=m")
6180 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
6186 extern int lr_save_eliminated;
6188 if (lr_save_eliminated)
6190 if (XVECLEN (operands[2], 0) > 1)
6194 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
6195 for (i = 1; i < XVECLEN (operands[2], 0); i++)
6197 strcat (pattern, \", %|\");
6198 strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
6201 strcat (pattern, \"}\");
6202 output_asm_insn (pattern, operands);
6205 [(set_attr "type" "store4")])
6207 ;; Similarly for the floating point registers
6208 (define_insn "*push_fp_multi"
6209 [(match_parallel 2 "multi_register_push"
6210 [(set (match_operand:BLK 0 "memory_operand" "=m")
6211 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")] 2))])]
6218 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
6219 output_asm_insn (pattern, operands);
6222 [(set_attr "type" "f_store")])
6224 ;; Special patterns for dealing with the constant pool
6226 (define_insn "consttable_4"
6227 [(unspec_volatile [(match_operand 0 "" "")] 2)]
6231 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
6235 union real_extract u;
6236 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
6237 assemble_real (u.d, GET_MODE (operands[0]));
6241 assemble_integer (operands[0], 4, 1);
6246 [(set_attr "length" "4")])
6248 (define_insn "consttable_8"
6249 [(unspec_volatile [(match_operand 0 "" "")] 3)]
6253 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
6257 union real_extract u;
6258 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
6259 assemble_real (u.d, GET_MODE (operands[0]));
6263 assemble_integer (operands[0], 8, 1);
6268 [(set_attr "length" "8")])
6270 (define_insn "consttable_end"
6271 [(unspec_volatile [(const_int 0)] 4)]
6274 /* Nothing to do (currently). */
6278 (define_insn "align_4"
6279 [(unspec_volatile [(const_int 0)] 5)]
6282 assemble_align (32);