1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003 2004 Free Software Foundation, Inc.
4 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
5 ;; and Martin Simmons (@harleqn.co.uk).
6 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published
12 ;; by the Free Software Foundation; either version 2, or (at your
13 ;; option) any later version.
15 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 ;; License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;---------------------------------------------------------------------------
33 [(IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (CC_REGNUM 24) ; Condition code pseudo register
41 ;; 3rd operand to select_dominance_cc_mode
50 ;; Note: sin and cos are no-longer used.
53 [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT):
54 ; operand 0 is the result,
55 ; operand 1 the parameter.
56 (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT):
57 ; operand 0 is the result,
58 ; operand 1 the parameter.
59 (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
60 ; operand 0 is the first register,
61 ; subsequent registers are in parallel (use ...)
63 (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
64 ; usage, that is, we will add the pic_register
65 ; value to it before trying to dereference it.
66 (UNSPEC_PIC_BASE 4) ; Adding the PC value to the offset to the
67 ; GLOBAL_OFFSET_TABLE. The operation is fully
68 ; described by the RTL but must be wrapped to
69 ; prevent combine from trying to rip it apart.
70 (UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
71 ; being scheduled before the stack adjustment insn.
72 (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
73 ; this unspec is used to prevent the deletion of
74 ; instructions setting registers for EH handling
75 ; and stack frame generation. Operand 0 is the
77 (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
78 (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
79 (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
80 (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
81 (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
82 (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
83 (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
84 (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
85 (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
86 (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
87 (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
88 (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
89 (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
93 ;; UNSPEC_VOLATILE Usage:
96 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
98 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
99 ; instruction epilogue sequence that isn't expanded
100 ; into normal RTL. Used for both normal and sibcall
102 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
103 ; for inlined constants.
104 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
106 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
108 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
110 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
112 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
114 (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
115 (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
116 (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
117 (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
118 (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
119 (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
120 (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
125 ;;---------------------------------------------------------------------------
128 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
129 ; generating ARM code. This is used to control the length of some insn
130 ; patterns that share the same RTL in both ARM and Thumb code.
131 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
133 ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
134 ; scheduling decisions for the load unit and the multiplier.
135 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
137 ; IS_XSCALE is set to 'yes' when compiling for XScale.
138 (define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
140 ;; Operand number of an input operand that is shifted. Zero if the
141 ;; given instruction does not shift one of its input operands.
142 (define_attr "shift" "" (const_int 0))
144 ; Floating Point Unit. If we only have floating point emulation, then there
145 ; is no point in scheduling the floating point insns. (Well, for best
146 ; performance we should try and group them together).
147 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
148 (const (symbol_ref "arm_fpu_attr")))
150 ; LENGTH of an instruction (in bytes)
151 (define_attr "length" "" (const_int 4))
153 ; POOL_RANGE is how far away from a constant pool entry that this insn
154 ; can be placed. If the distance is zero, then this insn will never
155 ; reference the pool.
156 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
157 ; before its address.
158 (define_attr "pool_range" "" (const_int 0))
159 (define_attr "neg_pool_range" "" (const_int 0))
161 ; An assembler sequence may clobber the condition codes without us knowing.
162 ; If such an insn references the pool, then we have no way of knowing how,
163 ; so use the most conservative value for pool_range.
164 (define_asm_attributes
165 [(set_attr "conds" "clob")
166 (set_attr "length" "4")
167 (set_attr "pool_range" "250")])
169 ;; The instruction used to implement a particular pattern. This
170 ;; information is used by pipeline descriptions to provide accurate
171 ;; scheduling information.
174 "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,other"
175 (const_string "other"))
177 ; TYPE attribute is used to detect floating point instructions which, if
178 ; running on a co-processor can run in parallel with other, basic instructions
179 ; If write-buffer scheduling is enabled then it can also be used in the
180 ; scheduling of writes.
182 ; Classification of each insn
183 ; alu any alu instruction that doesn't hit memory or fp
184 ; regs or have a shifted source operand
185 ; alu_shift any data instruction that doesn't hit memory or fp
186 ; regs, but has a source operand shifted by a constant
187 ; alu_shift_reg any data instruction that doesn't hit memory or fp
188 ; regs, but has a source operand shifted by a register value
189 ; mult a multiply instruction
190 ; block blockage insn, this blocks all functional units
191 ; float a floating point arithmetic operation (subject to expansion)
192 ; fdivd DFmode floating point division
193 ; fdivs SFmode floating point division
194 ; fmul Floating point multiply
195 ; ffmul Fast floating point multiply
196 ; farith Floating point arithmetic (4 cycle)
197 ; ffarith Fast floating point arithmetic (2 cycle)
198 ; float_em a floating point arithmetic operation that is normally emulated
199 ; even on a machine with an fpa.
200 ; f_load a floating point load from memory
201 ; f_store a floating point store to memory
202 ; f_mem_r a transfer of a floating point register to a real reg via mem
203 ; r_mem_f the reverse of f_mem_r
204 ; f_2_r fast transfer float to arm (no memory needed)
205 ; r_2_f fast transfer arm to float
207 ; call a subroutine call
208 ; load_byte load byte(s) from memory to arm registers
209 ; load1 load 1 word from memory to arm registers
210 ; load2 load 2 words from memory to arm registers
211 ; load3 load 3 words from memory to arm registers
212 ; load4 load 4 words from memory to arm registers
213 ; store store 1 word to memory from arm registers
214 ; store2 store 2 words
215 ; store3 store 3 words
216 ; store4 store 4 (or more) words
217 ; Additions for Cirrus Maverick co-processor:
218 ; mav_farith Floating point arithmetic (4 cycle)
219 ; mav_dmult Double multiplies (7 cycle)
222 "alu,alu_shift,alu_shift_reg,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,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
224 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
225 (const_string "mult")
226 (const_string "alu")))
228 ; Load scheduling, set from the arm_ld_sched variable
229 ; initialized by arm_override_options()
230 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
232 ; condition codes: this one is used by final_prescan_insn to speed up
233 ; conditionalizing instructions. It saves having to scan the rtl to see if
234 ; it uses or alters the condition codes.
236 ; USE means that the condition codes are used by the insn in the process of
237 ; outputting code, this means (at present) that we can't use the insn in
240 ; SET means that the purpose of the insn is to set the condition codes in a
241 ; well defined manner.
243 ; CLOB means that the condition codes are altered in an undefined manner, if
244 ; they are altered at all
246 ; JUMP_CLOB is used when the condition cannot be represented by a single
247 ; instruction (UNEQ and LTGT). These cannot be predicated.
249 ; NOCOND means that the condition codes are neither altered nor affect the
250 ; output of this insn
252 (define_attr "conds" "use,set,clob,jump_clob,nocond"
253 (if_then_else (eq_attr "type" "call")
254 (const_string "clob")
255 (const_string "nocond")))
257 ; Predicable means that the insn can be conditionally executed based on
258 ; an automatically added predicate (additional patterns are generated by
259 ; gen...). We default to 'no' because no Thumb patterns match this rule
260 ; and not all ARM patterns do.
261 (define_attr "predicable" "no,yes" (const_string "no"))
263 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
264 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
265 ; suffer blockages enough to warrant modelling this (and it can adversely
266 ; affect the schedule).
267 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
269 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
270 ; to stall the processor. Used with model_wbuf above.
271 (define_attr "write_conflict" "no,yes"
272 (if_then_else (eq_attr "type"
273 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
275 (const_string "no")))
277 ; Classify the insns into those that take one cycle and those that take more
278 ; than one on the main cpu execution unit.
279 (define_attr "core_cycles" "single,multi"
280 (if_then_else (eq_attr "type"
281 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
282 (const_string "single")
283 (const_string "multi")))
285 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
286 ;; distant label. Only applicable to Thumb code.
287 (define_attr "far_jump" "yes,no" (const_string "no"))
289 (include "predicates.md")
291 ;;---------------------------------------------------------------------------
292 ;; Pipeline descriptions
294 ;; Processor type. This is created automatically from arm-cores.def.
295 (include "arm-tune.md")
297 ;; True if the generic scheduling description should be used.
299 (define_attr "generic_sched" "yes,no"
301 (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
303 (const_string "yes")))
305 (include "arm-generic.md")
306 (include "arm926ejs.md")
307 (include "arm1026ejs.md")
308 (include "arm1136jfs.md")
311 ;;---------------------------------------------------------------------------
316 ;; Note: For DImode insns, there is normally no reason why operands should
317 ;; not be in the same register, what we don't want is for something being
318 ;; written to partially overlap something that is an input.
319 ;; Cirrus 64bit additions should not be split because we have a native
320 ;; 64bit addition instructions.
322 (define_expand "adddi3"
324 [(set (match_operand:DI 0 "s_register_operand" "")
325 (plus:DI (match_operand:DI 1 "s_register_operand" "")
326 (match_operand:DI 2 "s_register_operand" "")))
327 (clobber (reg:CC CC_REGNUM))])]
330 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
332 if (!cirrus_fp_register (operands[0], DImode))
333 operands[0] = force_reg (DImode, operands[0]);
334 if (!cirrus_fp_register (operands[1], DImode))
335 operands[1] = force_reg (DImode, operands[1]);
336 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
342 if (GET_CODE (operands[1]) != REG)
343 operands[1] = force_reg (SImode, operands[1]);
344 if (GET_CODE (operands[2]) != REG)
345 operands[2] = force_reg (SImode, operands[2]);
350 (define_insn "*thumb_adddi3"
351 [(set (match_operand:DI 0 "register_operand" "=l")
352 (plus:DI (match_operand:DI 1 "register_operand" "%0")
353 (match_operand:DI 2 "register_operand" "l")))
354 (clobber (reg:CC CC_REGNUM))
357 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
358 [(set_attr "length" "4")]
361 (define_insn_and_split "*arm_adddi3"
362 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
363 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
364 (match_operand:DI 2 "s_register_operand" "r, 0")))
365 (clobber (reg:CC CC_REGNUM))]
366 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
368 "TARGET_ARM && reload_completed"
369 [(parallel [(set (reg:CC_C CC_REGNUM)
370 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
372 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
373 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
374 (plus:SI (match_dup 4) (match_dup 5))))]
377 operands[3] = gen_highpart (SImode, operands[0]);
378 operands[0] = gen_lowpart (SImode, operands[0]);
379 operands[4] = gen_highpart (SImode, operands[1]);
380 operands[1] = gen_lowpart (SImode, operands[1]);
381 operands[5] = gen_highpart (SImode, operands[2]);
382 operands[2] = gen_lowpart (SImode, operands[2]);
384 [(set_attr "conds" "clob")
385 (set_attr "length" "8")]
388 (define_insn_and_split "*adddi_sesidi_di"
389 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
390 (plus:DI (sign_extend:DI
391 (match_operand:SI 2 "s_register_operand" "r,r"))
392 (match_operand:DI 1 "s_register_operand" "r,0")))
393 (clobber (reg:CC CC_REGNUM))]
394 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
396 "TARGET_ARM && reload_completed"
397 [(parallel [(set (reg:CC_C CC_REGNUM)
398 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
400 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
401 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
402 (plus:SI (ashiftrt:SI (match_dup 2)
407 operands[3] = gen_highpart (SImode, operands[0]);
408 operands[0] = gen_lowpart (SImode, operands[0]);
409 operands[4] = gen_highpart (SImode, operands[1]);
410 operands[1] = gen_lowpart (SImode, operands[1]);
411 operands[2] = gen_lowpart (SImode, operands[2]);
413 [(set_attr "conds" "clob")
414 (set_attr "length" "8")]
417 (define_insn_and_split "*adddi_zesidi_di"
418 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
419 (plus:DI (zero_extend:DI
420 (match_operand:SI 2 "s_register_operand" "r,r"))
421 (match_operand:DI 1 "s_register_operand" "r,0")))
422 (clobber (reg:CC CC_REGNUM))]
423 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
425 "TARGET_ARM && reload_completed"
426 [(parallel [(set (reg:CC_C CC_REGNUM)
427 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
429 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
430 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
431 (plus:SI (match_dup 4) (const_int 0))))]
434 operands[3] = gen_highpart (SImode, operands[0]);
435 operands[0] = gen_lowpart (SImode, operands[0]);
436 operands[4] = gen_highpart (SImode, operands[1]);
437 operands[1] = gen_lowpart (SImode, operands[1]);
438 operands[2] = gen_lowpart (SImode, operands[2]);
440 [(set_attr "conds" "clob")
441 (set_attr "length" "8")]
444 (define_expand "addsi3"
445 [(set (match_operand:SI 0 "s_register_operand" "")
446 (plus:SI (match_operand:SI 1 "s_register_operand" "")
447 (match_operand:SI 2 "reg_or_int_operand" "")))]
450 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
452 arm_split_constant (PLUS, SImode, NULL_RTX,
453 INTVAL (operands[2]), operands[0], operands[1],
454 optimize && !no_new_pseudos);
460 ; If there is a scratch available, this will be faster than synthesizing the
463 [(match_scratch:SI 3 "r")
464 (set (match_operand:SI 0 "arm_general_register_operand" "")
465 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
466 (match_operand:SI 2 "const_int_operand" "")))]
468 !(const_ok_for_arm (INTVAL (operands[2]))
469 || const_ok_for_arm (-INTVAL (operands[2])))
470 && const_ok_for_arm (~INTVAL (operands[2]))"
471 [(set (match_dup 3) (match_dup 2))
472 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
476 (define_insn_and_split "*arm_addsi3"
477 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
478 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
479 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
486 GET_CODE (operands[2]) == CONST_INT
487 && !(const_ok_for_arm (INTVAL (operands[2]))
488 || const_ok_for_arm (-INTVAL (operands[2])))"
489 [(clobber (const_int 0))]
491 arm_split_constant (PLUS, SImode, curr_insn,
492 INTVAL (operands[2]), operands[0],
496 [(set_attr "length" "4,4,16")
497 (set_attr "predicable" "yes")]
500 ;; Register group 'k' is a single register group containing only the stack
501 ;; register. Trying to reload it will always fail catastrophically,
502 ;; so never allow those alternatives to match if reloading is needed.
504 (define_insn "*thumb_addsi3"
505 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
506 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
507 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
510 static const char * const asms[] =
512 \"add\\t%0, %0, %2\",
513 \"sub\\t%0, %0, #%n2\",
514 \"add\\t%0, %1, %2\",
515 \"add\\t%0, %0, %2\",
516 \"add\\t%0, %0, %2\",
517 \"add\\t%0, %1, %2\",
520 if ((which_alternative == 2 || which_alternative == 6)
521 && GET_CODE (operands[2]) == CONST_INT
522 && INTVAL (operands[2]) < 0)
523 return \"sub\\t%0, %1, #%n2\";
524 return asms[which_alternative];
526 [(set_attr "length" "2")]
529 ;; Reloading and elimination of the frame pointer can
530 ;; sometimes cause this optimization to be missed.
532 [(set (match_operand:SI 0 "arm_general_register_operand" "")
533 (match_operand:SI 1 "const_int_operand" ""))
535 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
537 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
538 && (INTVAL (operands[1]) & 3) == 0"
539 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
543 (define_insn "*addsi3_compare0"
544 [(set (reg:CC_NOOV CC_REGNUM)
546 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
547 (match_operand:SI 2 "arm_add_operand" "rI,L"))
549 (set (match_operand:SI 0 "s_register_operand" "=r,r")
550 (plus:SI (match_dup 1) (match_dup 2)))]
554 sub%?s\\t%0, %1, #%n2"
555 [(set_attr "conds" "set")]
558 (define_insn "*addsi3_compare0_scratch"
559 [(set (reg:CC_NOOV CC_REGNUM)
561 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
562 (match_operand:SI 1 "arm_add_operand" "rI,L"))
568 [(set_attr "conds" "set")]
571 ;; These patterns are the same ones as the two regular addsi3_compare0
572 ;; patterns, except we write them slightly different - the combiner
573 ;; tends to generate them this way.
574 (define_insn "*addsi3_compare0_for_combiner"
575 [(set (reg:CC CC_REGNUM)
577 (match_operand:SI 1 "s_register_operand" "r,r")
578 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
579 (set (match_operand:SI 0 "s_register_operand" "=r,r")
580 (plus:SI (match_dup 1) (match_dup 2)))]
584 sub%?s\\t%0, %1, #%n2"
585 [(set_attr "conds" "set")]
588 (define_insn "*addsi3_compare0_scratch_for_combiner"
589 [(set (reg:CC CC_REGNUM)
591 (match_operand:SI 0 "s_register_operand" "r,r")
592 (neg:SI (match_operand:SI 1 "arm_add_operand" "rI,L"))))]
597 [(set_attr "conds" "set")]
600 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
601 ;; addend is a constant.
602 (define_insn "*cmpsi2_addneg"
603 [(set (reg:CC CC_REGNUM)
605 (match_operand:SI 1 "s_register_operand" "r,r")
606 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
607 (set (match_operand:SI 0 "s_register_operand" "=r,r")
608 (plus:SI (match_dup 1)
609 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
610 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
613 add%?s\\t%0, %1, #%n2"
614 [(set_attr "conds" "set")]
617 ;; Convert the sequence
619 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
623 ;; bcs dest ((unsigned)rn >= 1)
624 ;; similarly for the beq variant using bcc.
625 ;; This is a common looping idiom (while (n--))
627 [(set (match_operand:SI 0 "arm_general_register_operand" "")
628 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
630 (set (match_operand 2 "cc_register" "")
631 (compare (match_dup 0) (const_int -1)))
633 (if_then_else (match_operator 3 "equality_operator"
634 [(match_dup 2) (const_int 0)])
635 (match_operand 4 "" "")
636 (match_operand 5 "" "")))]
637 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
641 (match_dup 1) (const_int 1)))
642 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
644 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
647 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
648 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
651 operands[2], const0_rtx);"
654 ;; The next four insns work because they compare the result with one of
655 ;; the operands, and we know that the use of the condition code is
656 ;; either GEU or LTU, so we can use the carry flag from the addition
657 ;; instead of doing the compare a second time.
658 (define_insn "*addsi3_compare_op1"
659 [(set (reg:CC_C CC_REGNUM)
661 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
662 (match_operand:SI 2 "arm_add_operand" "rI,L"))
664 (set (match_operand:SI 0 "s_register_operand" "=r,r")
665 (plus:SI (match_dup 1) (match_dup 2)))]
669 sub%?s\\t%0, %1, #%n2"
670 [(set_attr "conds" "set")]
673 (define_insn "*addsi3_compare_op2"
674 [(set (reg:CC_C CC_REGNUM)
676 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
677 (match_operand:SI 2 "arm_add_operand" "rI,L"))
679 (set (match_operand:SI 0 "s_register_operand" "=r,r")
680 (plus:SI (match_dup 1) (match_dup 2)))]
684 sub%?s\\t%0, %1, #%n2"
685 [(set_attr "conds" "set")]
688 (define_insn "*compare_addsi2_op0"
689 [(set (reg:CC_C CC_REGNUM)
691 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
692 (match_operand:SI 1 "arm_add_operand" "rI,L"))
698 [(set_attr "conds" "set")]
701 (define_insn "*compare_addsi2_op1"
702 [(set (reg:CC_C CC_REGNUM)
704 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
705 (match_operand:SI 1 "arm_add_operand" "rI,L"))
711 [(set_attr "conds" "set")]
714 (define_insn "*addsi3_carryin"
715 [(set (match_operand:SI 0 "s_register_operand" "=r")
716 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
717 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
718 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
721 [(set_attr "conds" "use")]
724 (define_insn "*addsi3_carryin_shift"
725 [(set (match_operand:SI 0 "s_register_operand" "=r")
726 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
728 (match_operator:SI 2 "shift_operator"
729 [(match_operand:SI 3 "s_register_operand" "r")
730 (match_operand:SI 4 "reg_or_int_operand" "rM")])
731 (match_operand:SI 1 "s_register_operand" "r"))))]
733 "adc%?\\t%0, %1, %3%S2"
734 [(set_attr "conds" "use")
735 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
736 (const_string "alu_shift")
737 (const_string "alu_shift_reg")))]
740 (define_insn "*addsi3_carryin_alt1"
741 [(set (match_operand:SI 0 "s_register_operand" "=r")
742 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
743 (match_operand:SI 2 "arm_rhs_operand" "rI"))
744 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
747 [(set_attr "conds" "use")]
750 (define_insn "*addsi3_carryin_alt2"
751 [(set (match_operand:SI 0 "s_register_operand" "=r")
752 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
753 (match_operand:SI 1 "s_register_operand" "r"))
754 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
757 [(set_attr "conds" "use")]
760 (define_insn "*addsi3_carryin_alt3"
761 [(set (match_operand:SI 0 "s_register_operand" "=r")
762 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
763 (match_operand:SI 2 "arm_rhs_operand" "rI"))
764 (match_operand:SI 1 "s_register_operand" "r")))]
767 [(set_attr "conds" "use")]
770 (define_insn "incscc"
771 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
772 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
773 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
774 (match_operand:SI 1 "s_register_operand" "0,?r")))]
778 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
779 [(set_attr "conds" "use")
780 (set_attr "length" "4,8")]
783 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
785 [(set (match_operand:SI 0 "s_register_operand" "")
786 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
787 (match_operand:SI 2 "s_register_operand" ""))
789 (clobber (match_operand:SI 3 "s_register_operand" ""))]
791 [(set (match_dup 3) (match_dup 1))
792 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
794 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
797 (define_expand "addsf3"
798 [(set (match_operand:SF 0 "s_register_operand" "")
799 (plus:SF (match_operand:SF 1 "s_register_operand" "")
800 (match_operand:SF 2 "arm_float_add_operand" "")))]
801 "TARGET_ARM && TARGET_HARD_FLOAT"
804 && !cirrus_fp_register (operands[2], SFmode))
805 operands[2] = force_reg (SFmode, operands[2]);
808 (define_expand "adddf3"
809 [(set (match_operand:DF 0 "s_register_operand" "")
810 (plus:DF (match_operand:DF 1 "s_register_operand" "")
811 (match_operand:DF 2 "arm_float_add_operand" "")))]
812 "TARGET_ARM && TARGET_HARD_FLOAT"
815 && !cirrus_fp_register (operands[2], DFmode))
816 operands[2] = force_reg (DFmode, operands[2]);
819 (define_expand "subdi3"
821 [(set (match_operand:DI 0 "s_register_operand" "")
822 (minus:DI (match_operand:DI 1 "s_register_operand" "")
823 (match_operand:DI 2 "s_register_operand" "")))
824 (clobber (reg:CC CC_REGNUM))])]
827 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
829 && cirrus_fp_register (operands[0], DImode)
830 && cirrus_fp_register (operands[1], DImode))
832 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
838 if (GET_CODE (operands[1]) != REG)
839 operands[1] = force_reg (SImode, operands[1]);
840 if (GET_CODE (operands[2]) != REG)
841 operands[2] = force_reg (SImode, operands[2]);
846 (define_insn "*arm_subdi3"
847 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
848 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
849 (match_operand:DI 2 "s_register_operand" "r,0,0")))
850 (clobber (reg:CC CC_REGNUM))]
852 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
853 [(set_attr "conds" "clob")
854 (set_attr "length" "8")]
857 (define_insn "*thumb_subdi3"
858 [(set (match_operand:DI 0 "register_operand" "=l")
859 (minus:DI (match_operand:DI 1 "register_operand" "0")
860 (match_operand:DI 2 "register_operand" "l")))
861 (clobber (reg:CC CC_REGNUM))]
863 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
864 [(set_attr "length" "4")]
867 (define_insn "*subdi_di_zesidi"
868 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
869 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
871 (match_operand:SI 2 "s_register_operand" "r,r"))))
872 (clobber (reg:CC CC_REGNUM))]
874 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
875 [(set_attr "conds" "clob")
876 (set_attr "length" "8")]
879 (define_insn "*subdi_di_sesidi"
880 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
881 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
883 (match_operand:SI 2 "s_register_operand" "r,r"))))
884 (clobber (reg:CC CC_REGNUM))]
886 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
887 [(set_attr "conds" "clob")
888 (set_attr "length" "8")]
891 (define_insn "*subdi_zesidi_di"
892 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
893 (minus:DI (zero_extend:DI
894 (match_operand:SI 2 "s_register_operand" "r,r"))
895 (match_operand:DI 1 "s_register_operand" "?r,0")))
896 (clobber (reg:CC CC_REGNUM))]
898 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
899 [(set_attr "conds" "clob")
900 (set_attr "length" "8")]
903 (define_insn "*subdi_sesidi_di"
904 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
905 (minus:DI (sign_extend:DI
906 (match_operand:SI 2 "s_register_operand" "r,r"))
907 (match_operand:DI 1 "s_register_operand" "?r,0")))
908 (clobber (reg:CC CC_REGNUM))]
910 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
911 [(set_attr "conds" "clob")
912 (set_attr "length" "8")]
915 (define_insn "*subdi_zesidi_zesidi"
916 [(set (match_operand:DI 0 "s_register_operand" "=r")
917 (minus:DI (zero_extend:DI
918 (match_operand:SI 1 "s_register_operand" "r"))
920 (match_operand:SI 2 "s_register_operand" "r"))))
921 (clobber (reg:CC CC_REGNUM))]
923 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
924 [(set_attr "conds" "clob")
925 (set_attr "length" "8")]
928 (define_expand "subsi3"
929 [(set (match_operand:SI 0 "s_register_operand" "")
930 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
931 (match_operand:SI 2 "s_register_operand" "")))]
934 if (GET_CODE (operands[1]) == CONST_INT)
938 arm_split_constant (MINUS, SImode, NULL_RTX,
939 INTVAL (operands[1]), operands[0],
940 operands[2], optimize && !no_new_pseudos);
943 else /* TARGET_THUMB */
944 operands[1] = force_reg (SImode, operands[1]);
949 (define_insn "*thumb_subsi3_insn"
950 [(set (match_operand:SI 0 "register_operand" "=l")
951 (minus:SI (match_operand:SI 1 "register_operand" "l")
952 (match_operand:SI 2 "register_operand" "l")))]
955 [(set_attr "length" "2")]
958 (define_insn_and_split "*arm_subsi3_insn"
959 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
960 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
961 (match_operand:SI 2 "s_register_operand" "r,r")))]
967 && GET_CODE (operands[1]) == CONST_INT
968 && !const_ok_for_arm (INTVAL (operands[1]))"
969 [(clobber (const_int 0))]
971 arm_split_constant (MINUS, SImode, curr_insn,
972 INTVAL (operands[1]), operands[0], operands[2], 0);
975 [(set_attr "length" "4,16")
976 (set_attr "predicable" "yes")]
980 [(match_scratch:SI 3 "r")
981 (set (match_operand:SI 0 "arm_general_register_operand" "")
982 (minus:SI (match_operand:SI 1 "const_int_operand" "")
983 (match_operand:SI 2 "arm_general_register_operand" "")))]
985 && !const_ok_for_arm (INTVAL (operands[1]))
986 && const_ok_for_arm (~INTVAL (operands[1]))"
987 [(set (match_dup 3) (match_dup 1))
988 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
992 (define_insn "*subsi3_compare0"
993 [(set (reg:CC_NOOV CC_REGNUM)
995 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
996 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
998 (set (match_operand:SI 0 "s_register_operand" "=r,r")
999 (minus:SI (match_dup 1) (match_dup 2)))]
1003 rsb%?s\\t%0, %2, %1"
1004 [(set_attr "conds" "set")]
1007 (define_insn "decscc"
1008 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1009 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1010 (match_operator:SI 2 "arm_comparison_operator"
1011 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1015 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1016 [(set_attr "conds" "use")
1017 (set_attr "length" "*,8")]
1020 (define_expand "subsf3"
1021 [(set (match_operand:SF 0 "s_register_operand" "")
1022 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1023 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1024 "TARGET_ARM && TARGET_HARD_FLOAT"
1026 if (TARGET_MAVERICK)
1028 if (!cirrus_fp_register (operands[1], SFmode))
1029 operands[1] = force_reg (SFmode, operands[1]);
1030 if (!cirrus_fp_register (operands[2], SFmode))
1031 operands[2] = force_reg (SFmode, operands[2]);
1035 (define_expand "subdf3"
1036 [(set (match_operand:DF 0 "s_register_operand" "")
1037 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1038 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1039 "TARGET_ARM && TARGET_HARD_FLOAT"
1041 if (TARGET_MAVERICK)
1043 if (!cirrus_fp_register (operands[1], DFmode))
1044 operands[1] = force_reg (DFmode, operands[1]);
1045 if (!cirrus_fp_register (operands[2], DFmode))
1046 operands[2] = force_reg (DFmode, operands[2]);
1051 ;; Multiplication insns
1053 (define_expand "mulsi3"
1054 [(set (match_operand:SI 0 "s_register_operand" "")
1055 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1056 (match_operand:SI 1 "s_register_operand" "")))]
1061 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1062 (define_insn "*arm_mulsi3"
1063 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1064 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1065 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1067 "mul%?\\t%0, %2, %1"
1068 [(set_attr "insn" "mul")
1069 (set_attr "predicable" "yes")]
1072 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1073 ; 1 and 2; are the same, because reload will make operand 0 match
1074 ; operand 1 without realizing that this conflicts with operand 2. We fix
1075 ; this by adding another alternative to match this case, and then `reload'
1076 ; it ourselves. This alternative must come first.
1077 (define_insn "*thumb_mulsi3"
1078 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1079 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1080 (match_operand:SI 2 "register_operand" "l,l,l")))]
1083 if (which_alternative < 2)
1084 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1086 return \"mul\\t%0, %0, %2\";
1088 [(set_attr "length" "4,4,2")
1089 (set_attr "insn" "mul")]
1092 (define_insn "*mulsi3_compare0"
1093 [(set (reg:CC_NOOV CC_REGNUM)
1094 (compare:CC_NOOV (mult:SI
1095 (match_operand:SI 2 "s_register_operand" "r,r")
1096 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1098 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1099 (mult:SI (match_dup 2) (match_dup 1)))]
1100 "TARGET_ARM && !arm_arch_xscale"
1101 "mul%?s\\t%0, %2, %1"
1102 [(set_attr "conds" "set")
1103 (set_attr "insn" "muls")]
1106 (define_insn "*mulsi_compare0_scratch"
1107 [(set (reg:CC_NOOV CC_REGNUM)
1108 (compare:CC_NOOV (mult:SI
1109 (match_operand:SI 2 "s_register_operand" "r,r")
1110 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1112 (clobber (match_scratch:SI 0 "=&r,&r"))]
1113 "TARGET_ARM && !arm_arch_xscale"
1114 "mul%?s\\t%0, %2, %1"
1115 [(set_attr "conds" "set")
1116 (set_attr "insn" "muls")]
1119 ;; Unnamed templates to match MLA instruction.
1121 (define_insn "*mulsi3addsi"
1122 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1124 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1125 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1126 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1128 "mla%?\\t%0, %2, %1, %3"
1129 [(set_attr "insn" "mla")
1130 (set_attr "predicable" "yes")]
1133 (define_insn "*mulsi3addsi_compare0"
1134 [(set (reg:CC_NOOV CC_REGNUM)
1137 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1138 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1139 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1141 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1142 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1144 "TARGET_ARM && !arm_arch_xscale"
1145 "mla%?s\\t%0, %2, %1, %3"
1146 [(set_attr "conds" "set")
1147 (set_attr "insn" "mlas")]
1150 (define_insn "*mulsi3addsi_compare0_scratch"
1151 [(set (reg:CC_NOOV CC_REGNUM)
1154 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1155 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1156 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1158 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1159 "TARGET_ARM && !arm_arch_xscale"
1160 "mla%?s\\t%0, %2, %1, %3"
1161 [(set_attr "conds" "set")
1162 (set_attr "insn" "mlas")]
1165 ;; Unnamed template to match long long multiply-accumulate (smlal)
1167 (define_insn "*mulsidi3adddi"
1168 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1171 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1172 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1173 (match_operand:DI 1 "s_register_operand" "0")))]
1174 "TARGET_ARM && arm_arch3m"
1175 "smlal%?\\t%Q0, %R0, %3, %2"
1176 [(set_attr "insn" "smlal")
1177 (set_attr "predicable" "yes")]
1180 (define_insn "mulsidi3"
1181 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1183 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1184 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1185 "TARGET_ARM && arm_arch3m"
1186 "smull%?\\t%Q0, %R0, %1, %2"
1187 [(set_attr "insn" "smull")
1188 (set_attr "predicable" "yes")]
1191 (define_insn "umulsidi3"
1192 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1194 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1195 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1196 "TARGET_ARM && arm_arch3m"
1197 "umull%?\\t%Q0, %R0, %1, %2"
1198 [(set_attr "insn" "umull")
1199 (set_attr "predicable" "yes")]
1202 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1204 (define_insn "*umulsidi3adddi"
1205 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1208 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1209 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1210 (match_operand:DI 1 "s_register_operand" "0")))]
1211 "TARGET_ARM && arm_arch3m"
1212 "umlal%?\\t%Q0, %R0, %3, %2"
1213 [(set_attr "insn" "umlal")
1214 (set_attr "predicable" "yes")]
1217 (define_insn "smulsi3_highpart"
1218 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1222 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1223 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1225 (clobber (match_scratch:SI 3 "=&r,&r"))]
1226 "TARGET_ARM && arm_arch3m"
1227 "smull%?\\t%3, %0, %2, %1"
1228 [(set_attr "insn" "smull")
1229 (set_attr "predicable" "yes")]
1232 (define_insn "umulsi3_highpart"
1233 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1237 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1238 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1240 (clobber (match_scratch:SI 3 "=&r,&r"))]
1241 "TARGET_ARM && arm_arch3m"
1242 "umull%?\\t%3, %0, %2, %1"
1243 [(set_attr "insn" "umull")
1244 (set_attr "predicable" "yes")]
1247 (define_insn "mulhisi3"
1248 [(set (match_operand:SI 0 "s_register_operand" "=r")
1249 (mult:SI (sign_extend:SI
1250 (match_operand:HI 1 "s_register_operand" "%r"))
1252 (match_operand:HI 2 "s_register_operand" "r"))))]
1253 "TARGET_ARM && arm_arch5e"
1254 "smulbb%?\\t%0, %1, %2"
1255 [(set_attr "insn" "smulxy")
1256 (set_attr "predicable" "yes")]
1259 (define_insn "*mulhisi3tb"
1260 [(set (match_operand:SI 0 "s_register_operand" "=r")
1261 (mult:SI (ashiftrt:SI
1262 (match_operand:SI 1 "s_register_operand" "r")
1265 (match_operand:HI 2 "s_register_operand" "r"))))]
1266 "TARGET_ARM && arm_arch5e"
1267 "smultb%?\\t%0, %1, %2"
1268 [(set_attr "insn" "smulxy")
1269 (set_attr "predicable" "yes")]
1272 (define_insn "*mulhisi3bt"
1273 [(set (match_operand:SI 0 "s_register_operand" "=r")
1274 (mult:SI (sign_extend:SI
1275 (match_operand:HI 1 "s_register_operand" "r"))
1277 (match_operand:SI 2 "s_register_operand" "r")
1279 "TARGET_ARM && arm_arch5e"
1280 "smulbt%?\\t%0, %1, %2"
1281 [(set_attr "insn" "smulxy")
1282 (set_attr "predicable" "yes")]
1285 (define_insn "*mulhisi3tt"
1286 [(set (match_operand:SI 0 "s_register_operand" "=r")
1287 (mult:SI (ashiftrt:SI
1288 (match_operand:SI 1 "s_register_operand" "r")
1291 (match_operand:SI 2 "s_register_operand" "r")
1293 "TARGET_ARM && arm_arch5e"
1294 "smultt%?\\t%0, %1, %2"
1295 [(set_attr "insn" "smulxy")
1296 (set_attr "predicable" "yes")]
1299 (define_insn "*mulhisi3addsi"
1300 [(set (match_operand:SI 0 "s_register_operand" "=r")
1301 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1302 (mult:SI (sign_extend:SI
1303 (match_operand:HI 2 "s_register_operand" "%r"))
1305 (match_operand:HI 3 "s_register_operand" "r")))))]
1306 "TARGET_ARM && arm_arch5e"
1307 "smlabb%?\\t%0, %2, %3, %1"
1308 [(set_attr "insn" "smlaxy")
1309 (set_attr "predicable" "yes")]
1312 (define_insn "*mulhidi3adddi"
1313 [(set (match_operand:DI 0 "s_register_operand" "=r")
1315 (match_operand:DI 1 "s_register_operand" "0")
1316 (mult:DI (sign_extend:DI
1317 (match_operand:HI 2 "s_register_operand" "%r"))
1319 (match_operand:HI 3 "s_register_operand" "r")))))]
1320 "TARGET_ARM && arm_arch5e"
1321 "smlalbb%?\\t%Q0, %R0, %2, %3"
1322 [(set_attr "insn" "smlalxy")
1323 (set_attr "predicable" "yes")])
1325 (define_expand "mulsf3"
1326 [(set (match_operand:SF 0 "s_register_operand" "")
1327 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1328 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1329 "TARGET_ARM && TARGET_HARD_FLOAT"
1332 && !cirrus_fp_register (operands[2], SFmode))
1333 operands[2] = force_reg (SFmode, operands[2]);
1336 (define_expand "muldf3"
1337 [(set (match_operand:DF 0 "s_register_operand" "")
1338 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1339 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1340 "TARGET_ARM && TARGET_HARD_FLOAT"
1343 && !cirrus_fp_register (operands[2], DFmode))
1344 operands[2] = force_reg (DFmode, operands[2]);
1349 (define_expand "divsf3"
1350 [(set (match_operand:SF 0 "s_register_operand" "")
1351 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1352 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1353 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1356 (define_expand "divdf3"
1357 [(set (match_operand:DF 0 "s_register_operand" "")
1358 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1359 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1360 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1365 (define_expand "modsf3"
1366 [(set (match_operand:SF 0 "s_register_operand" "")
1367 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1368 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1369 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1372 (define_expand "moddf3"
1373 [(set (match_operand:DF 0 "s_register_operand" "")
1374 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1375 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1376 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1379 ;; Boolean and,ior,xor insns
1381 ;; Split up double word logical operations
1383 ;; Split up simple DImode logical operations. Simply perform the logical
1384 ;; operation on the upper and lower halves of the registers.
1386 [(set (match_operand:DI 0 "s_register_operand" "")
1387 (match_operator:DI 6 "logical_binary_operator"
1388 [(match_operand:DI 1 "s_register_operand" "")
1389 (match_operand:DI 2 "s_register_operand" "")]))]
1390 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1391 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1392 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1395 operands[3] = gen_highpart (SImode, operands[0]);
1396 operands[0] = gen_lowpart (SImode, operands[0]);
1397 operands[4] = gen_highpart (SImode, operands[1]);
1398 operands[1] = gen_lowpart (SImode, operands[1]);
1399 operands[5] = gen_highpart (SImode, operands[2]);
1400 operands[2] = gen_lowpart (SImode, operands[2]);
1405 [(set (match_operand:DI 0 "s_register_operand" "")
1406 (match_operator:DI 6 "logical_binary_operator"
1407 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1408 (match_operand:DI 1 "s_register_operand" "")]))]
1409 "TARGET_ARM && reload_completed"
1410 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1411 (set (match_dup 3) (match_op_dup:SI 6
1412 [(ashiftrt:SI (match_dup 2) (const_int 31))
1416 operands[3] = gen_highpart (SImode, operands[0]);
1417 operands[0] = gen_lowpart (SImode, operands[0]);
1418 operands[4] = gen_highpart (SImode, operands[1]);
1419 operands[1] = gen_lowpart (SImode, operands[1]);
1420 operands[5] = gen_highpart (SImode, operands[2]);
1421 operands[2] = gen_lowpart (SImode, operands[2]);
1425 ;; The zero extend of operand 2 means we can just copy the high part of
1426 ;; operand1 into operand0.
1428 [(set (match_operand:DI 0 "s_register_operand" "")
1430 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1431 (match_operand:DI 1 "s_register_operand" "")))]
1432 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1433 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1434 (set (match_dup 3) (match_dup 4))]
1437 operands[4] = gen_highpart (SImode, operands[1]);
1438 operands[3] = gen_highpart (SImode, operands[0]);
1439 operands[0] = gen_lowpart (SImode, operands[0]);
1440 operands[1] = gen_lowpart (SImode, operands[1]);
1444 ;; The zero extend of operand 2 means we can just copy the high part of
1445 ;; operand1 into operand0.
1447 [(set (match_operand:DI 0 "s_register_operand" "")
1449 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1450 (match_operand:DI 1 "s_register_operand" "")))]
1451 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1452 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1453 (set (match_dup 3) (match_dup 4))]
1456 operands[4] = gen_highpart (SImode, operands[1]);
1457 operands[3] = gen_highpart (SImode, operands[0]);
1458 operands[0] = gen_lowpart (SImode, operands[0]);
1459 operands[1] = gen_lowpart (SImode, operands[1]);
1463 (define_insn "anddi3"
1464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1465 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1466 (match_operand:DI 2 "s_register_operand" "r,r")))]
1467 "TARGET_ARM && ! TARGET_IWMMXT"
1469 [(set_attr "length" "8")]
1472 (define_insn_and_split "*anddi_zesidi_di"
1473 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1474 (and:DI (zero_extend:DI
1475 (match_operand:SI 2 "s_register_operand" "r,r"))
1476 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1479 "TARGET_ARM && reload_completed"
1480 ; The zero extend of operand 2 clears the high word of the output
1482 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1483 (set (match_dup 3) (const_int 0))]
1486 operands[3] = gen_highpart (SImode, operands[0]);
1487 operands[0] = gen_lowpart (SImode, operands[0]);
1488 operands[1] = gen_lowpart (SImode, operands[1]);
1490 [(set_attr "length" "8")]
1493 (define_insn "*anddi_sesdi_di"
1494 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1495 (and:DI (sign_extend:DI
1496 (match_operand:SI 2 "s_register_operand" "r,r"))
1497 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1500 [(set_attr "length" "8")]
1503 (define_expand "andsi3"
1504 [(set (match_operand:SI 0 "s_register_operand" "")
1505 (and:SI (match_operand:SI 1 "s_register_operand" "")
1506 (match_operand:SI 2 "reg_or_int_operand" "")))]
1511 if (GET_CODE (operands[2]) == CONST_INT)
1513 arm_split_constant (AND, SImode, NULL_RTX,
1514 INTVAL (operands[2]), operands[0],
1515 operands[1], optimize && !no_new_pseudos);
1520 else /* TARGET_THUMB */
1522 if (GET_CODE (operands[2]) != CONST_INT)
1523 operands[2] = force_reg (SImode, operands[2]);
1528 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1530 operands[2] = force_reg (SImode,
1531 GEN_INT (~INTVAL (operands[2])));
1533 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1538 for (i = 9; i <= 31; i++)
1540 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1542 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1546 else if ((((HOST_WIDE_INT) 1) << i) - 1
1547 == ~INTVAL (operands[2]))
1549 rtx shift = GEN_INT (i);
1550 rtx reg = gen_reg_rtx (SImode);
1552 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1553 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1559 operands[2] = force_reg (SImode, operands[2]);
1565 (define_insn_and_split "*arm_andsi3_insn"
1566 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1567 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1568 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1572 bic%?\\t%0, %1, #%B2
1575 && GET_CODE (operands[2]) == CONST_INT
1576 && !(const_ok_for_arm (INTVAL (operands[2]))
1577 || const_ok_for_arm (~INTVAL (operands[2])))"
1578 [(clobber (const_int 0))]
1580 arm_split_constant (AND, SImode, curr_insn,
1581 INTVAL (operands[2]), operands[0], operands[1], 0);
1584 [(set_attr "length" "4,4,16")
1585 (set_attr "predicable" "yes")]
1588 (define_insn "*thumb_andsi3_insn"
1589 [(set (match_operand:SI 0 "register_operand" "=l")
1590 (and:SI (match_operand:SI 1 "register_operand" "%0")
1591 (match_operand:SI 2 "register_operand" "l")))]
1594 [(set_attr "length" "2")]
1597 (define_insn "*andsi3_compare0"
1598 [(set (reg:CC_NOOV CC_REGNUM)
1600 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1601 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1603 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1604 (and:SI (match_dup 1) (match_dup 2)))]
1608 bic%?s\\t%0, %1, #%B2"
1609 [(set_attr "conds" "set")]
1612 (define_insn "*andsi3_compare0_scratch"
1613 [(set (reg:CC_NOOV CC_REGNUM)
1615 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1616 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1618 (clobber (match_scratch:SI 2 "=X,r"))]
1622 bic%?s\\t%2, %0, #%B1"
1623 [(set_attr "conds" "set")]
1626 (define_insn "*zeroextractsi_compare0_scratch"
1627 [(set (reg:CC_NOOV CC_REGNUM)
1628 (compare:CC_NOOV (zero_extract:SI
1629 (match_operand:SI 0 "s_register_operand" "r")
1630 (match_operand 1 "const_int_operand" "n")
1631 (match_operand 2 "const_int_operand" "n"))
1634 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1635 && INTVAL (operands[1]) > 0
1636 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1637 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1639 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1640 << INTVAL (operands[2]));
1641 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1644 [(set_attr "conds" "set")]
1647 (define_insn_and_split "*ne_zeroextractsi"
1648 [(set (match_operand:SI 0 "s_register_operand" "=r")
1649 (ne:SI (zero_extract:SI
1650 (match_operand:SI 1 "s_register_operand" "r")
1651 (match_operand:SI 2 "const_int_operand" "n")
1652 (match_operand:SI 3 "const_int_operand" "n"))
1654 (clobber (reg:CC CC_REGNUM))]
1656 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1657 && INTVAL (operands[2]) > 0
1658 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1659 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1662 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1663 && INTVAL (operands[2]) > 0
1664 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1665 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1666 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1667 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1669 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1671 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1672 (match_dup 0) (const_int 1)))]
1674 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1675 << INTVAL (operands[3]));
1677 [(set_attr "conds" "clob")
1678 (set_attr "length" "8")]
1681 (define_insn_and_split "*ne_zeroextractsi_shifted"
1682 [(set (match_operand:SI 0 "s_register_operand" "=r")
1683 (ne:SI (zero_extract:SI
1684 (match_operand:SI 1 "s_register_operand" "r")
1685 (match_operand:SI 2 "const_int_operand" "n")
1688 (clobber (reg:CC CC_REGNUM))]
1692 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1693 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1695 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1697 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1698 (match_dup 0) (const_int 1)))]
1700 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1702 [(set_attr "conds" "clob")
1703 (set_attr "length" "8")]
1706 (define_insn_and_split "*ite_ne_zeroextractsi"
1707 [(set (match_operand:SI 0 "s_register_operand" "=r")
1708 (if_then_else:SI (ne (zero_extract:SI
1709 (match_operand:SI 1 "s_register_operand" "r")
1710 (match_operand:SI 2 "const_int_operand" "n")
1711 (match_operand:SI 3 "const_int_operand" "n"))
1713 (match_operand:SI 4 "arm_not_operand" "rIK")
1715 (clobber (reg:CC CC_REGNUM))]
1717 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1718 && INTVAL (operands[2]) > 0
1719 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1720 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1721 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1724 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1725 && INTVAL (operands[2]) > 0
1726 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1727 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1728 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1729 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1730 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1732 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1734 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1735 (match_dup 0) (match_dup 4)))]
1737 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1738 << INTVAL (operands[3]));
1740 [(set_attr "conds" "clob")
1741 (set_attr "length" "8")]
1744 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
1745 [(set (match_operand:SI 0 "s_register_operand" "=r")
1746 (if_then_else:SI (ne (zero_extract:SI
1747 (match_operand:SI 1 "s_register_operand" "r")
1748 (match_operand:SI 2 "const_int_operand" "n")
1751 (match_operand:SI 3 "arm_not_operand" "rIK")
1753 (clobber (reg:CC CC_REGNUM))]
1754 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1756 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1757 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1758 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1760 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1762 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1763 (match_dup 0) (match_dup 3)))]
1765 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1767 [(set_attr "conds" "clob")
1768 (set_attr "length" "8")]
1772 [(set (match_operand:SI 0 "s_register_operand" "")
1773 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1774 (match_operand:SI 2 "const_int_operand" "")
1775 (match_operand:SI 3 "const_int_operand" "")))
1776 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1778 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1779 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1781 HOST_WIDE_INT temp = INTVAL (operands[2]);
1783 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1784 operands[3] = GEN_INT (32 - temp);
1789 [(set (match_operand:SI 0 "s_register_operand" "")
1790 (match_operator:SI 1 "shiftable_operator"
1791 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1792 (match_operand:SI 3 "const_int_operand" "")
1793 (match_operand:SI 4 "const_int_operand" ""))
1794 (match_operand:SI 5 "s_register_operand" "")]))
1795 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1797 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1800 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1803 HOST_WIDE_INT temp = INTVAL (operands[3]);
1805 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1806 operands[4] = GEN_INT (32 - temp);
1811 [(set (match_operand:SI 0 "s_register_operand" "")
1812 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1813 (match_operand:SI 2 "const_int_operand" "")
1814 (match_operand:SI 3 "const_int_operand" "")))]
1816 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1817 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1819 HOST_WIDE_INT temp = INTVAL (operands[2]);
1821 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1822 operands[3] = GEN_INT (32 - temp);
1827 [(set (match_operand:SI 0 "s_register_operand" "")
1828 (match_operator:SI 1 "shiftable_operator"
1829 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1830 (match_operand:SI 3 "const_int_operand" "")
1831 (match_operand:SI 4 "const_int_operand" ""))
1832 (match_operand:SI 5 "s_register_operand" "")]))
1833 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1835 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1838 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1841 HOST_WIDE_INT temp = INTVAL (operands[3]);
1843 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1844 operands[4] = GEN_INT (32 - temp);
1848 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1849 ;;; represented by the bitfield, then this will produce incorrect results.
1850 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1851 ;;; which have a real bit-field insert instruction, the truncation happens
1852 ;;; in the bit-field insert instruction itself. Since arm does not have a
1853 ;;; bit-field insert instruction, we would have to emit code here to truncate
1854 ;;; the value before we insert. This loses some of the advantage of having
1855 ;;; this insv pattern, so this pattern needs to be reevalutated.
1857 (define_expand "insv"
1858 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1859 (match_operand:SI 1 "general_operand" "")
1860 (match_operand:SI 2 "general_operand" ""))
1861 (match_operand:SI 3 "reg_or_int_operand" ""))]
1865 int start_bit = INTVAL (operands[2]);
1866 int width = INTVAL (operands[1]);
1867 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1868 rtx target, subtarget;
1870 target = operands[0];
1871 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1872 subreg as the final target. */
1873 if (GET_CODE (target) == SUBREG)
1875 subtarget = gen_reg_rtx (SImode);
1876 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1877 < GET_MODE_SIZE (SImode))
1878 target = SUBREG_REG (target);
1883 if (GET_CODE (operands[3]) == CONST_INT)
1885 /* Since we are inserting a known constant, we may be able to
1886 reduce the number of bits that we have to clear so that
1887 the mask becomes simple. */
1888 /* ??? This code does not check to see if the new mask is actually
1889 simpler. It may not be. */
1890 rtx op1 = gen_reg_rtx (SImode);
1891 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1892 start of this pattern. */
1893 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1894 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1896 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1897 emit_insn (gen_iorsi3 (subtarget, op1,
1898 GEN_INT (op3_value << start_bit)));
1900 else if (start_bit == 0
1901 && !(const_ok_for_arm (mask)
1902 || const_ok_for_arm (~mask)))
1904 /* A Trick, since we are setting the bottom bits in the word,
1905 we can shift operand[3] up, operand[0] down, OR them together
1906 and rotate the result back again. This takes 3 insns, and
1907 the third might be mergeable into another op. */
1908 /* The shift up copes with the possibility that operand[3] is
1909 wider than the bitfield. */
1910 rtx op0 = gen_reg_rtx (SImode);
1911 rtx op1 = gen_reg_rtx (SImode);
1913 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1914 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1915 emit_insn (gen_iorsi3 (op1, op1, op0));
1916 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1918 else if ((width + start_bit == 32)
1919 && !(const_ok_for_arm (mask)
1920 || const_ok_for_arm (~mask)))
1922 /* Similar trick, but slightly less efficient. */
1924 rtx op0 = gen_reg_rtx (SImode);
1925 rtx op1 = gen_reg_rtx (SImode);
1927 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1928 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1929 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1930 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1934 rtx op0 = GEN_INT (mask);
1935 rtx op1 = gen_reg_rtx (SImode);
1936 rtx op2 = gen_reg_rtx (SImode);
1938 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1940 rtx tmp = gen_reg_rtx (SImode);
1942 emit_insn (gen_movsi (tmp, op0));
1946 /* Mask out any bits in operand[3] that are not needed. */
1947 emit_insn (gen_andsi3 (op1, operands[3], op0));
1949 if (GET_CODE (op0) == CONST_INT
1950 && (const_ok_for_arm (mask << start_bit)
1951 || const_ok_for_arm (~(mask << start_bit))))
1953 op0 = GEN_INT (~(mask << start_bit));
1954 emit_insn (gen_andsi3 (op2, operands[0], op0));
1958 if (GET_CODE (op0) == CONST_INT)
1960 rtx tmp = gen_reg_rtx (SImode);
1962 emit_insn (gen_movsi (tmp, op0));
1967 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1969 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1973 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1975 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1978 if (subtarget != target)
1980 /* If TARGET is still a SUBREG, then it must be wider than a word,
1981 so we must be careful only to set the subword we were asked to. */
1982 if (GET_CODE (target) == SUBREG)
1983 emit_move_insn (target, subtarget);
1985 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1992 ; constants for op 2 will never be given to these patterns.
1993 (define_insn_and_split "*anddi_notdi_di"
1994 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1995 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1996 (match_operand:DI 2 "s_register_operand" "0,r")))]
1999 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2000 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2001 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2004 operands[3] = gen_highpart (SImode, operands[0]);
2005 operands[0] = gen_lowpart (SImode, operands[0]);
2006 operands[4] = gen_highpart (SImode, operands[1]);
2007 operands[1] = gen_lowpart (SImode, operands[1]);
2008 operands[5] = gen_highpart (SImode, operands[2]);
2009 operands[2] = gen_lowpart (SImode, operands[2]);
2011 [(set_attr "length" "8")
2012 (set_attr "predicable" "yes")]
2015 (define_insn_and_split "*anddi_notzesidi_di"
2016 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2017 (and:DI (not:DI (zero_extend:DI
2018 (match_operand:SI 2 "s_register_operand" "r,r")))
2019 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2022 bic%?\\t%Q0, %Q1, %2
2024 ; (not (zero_extend ...)) allows us to just copy the high word from
2025 ; operand1 to operand0.
2028 && operands[0] != operands[1]"
2029 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2030 (set (match_dup 3) (match_dup 4))]
2033 operands[3] = gen_highpart (SImode, operands[0]);
2034 operands[0] = gen_lowpart (SImode, operands[0]);
2035 operands[4] = gen_highpart (SImode, operands[1]);
2036 operands[1] = gen_lowpart (SImode, operands[1]);
2038 [(set_attr "length" "4,8")
2039 (set_attr "predicable" "yes")]
2042 (define_insn_and_split "*anddi_notsesidi_di"
2043 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2044 (and:DI (not:DI (sign_extend:DI
2045 (match_operand:SI 2 "s_register_operand" "r,r")))
2046 (match_operand:DI 1 "s_register_operand" "0,r")))]
2049 "TARGET_ARM && reload_completed"
2050 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2051 (set (match_dup 3) (and:SI (not:SI
2052 (ashiftrt:SI (match_dup 2) (const_int 31)))
2056 operands[3] = gen_highpart (SImode, operands[0]);
2057 operands[0] = gen_lowpart (SImode, operands[0]);
2058 operands[4] = gen_highpart (SImode, operands[1]);
2059 operands[1] = gen_lowpart (SImode, operands[1]);
2061 [(set_attr "length" "8")
2062 (set_attr "predicable" "yes")]
2065 (define_insn "andsi_notsi_si"
2066 [(set (match_operand:SI 0 "s_register_operand" "=r")
2067 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2068 (match_operand:SI 1 "s_register_operand" "r")))]
2070 "bic%?\\t%0, %1, %2"
2071 [(set_attr "predicable" "yes")]
2074 (define_insn "bicsi3"
2075 [(set (match_operand:SI 0 "register_operand" "=l")
2076 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2077 (match_operand:SI 2 "register_operand" "0")))]
2080 [(set_attr "length" "2")]
2083 (define_insn "andsi_not_shiftsi_si"
2084 [(set (match_operand:SI 0 "s_register_operand" "=r")
2085 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2086 [(match_operand:SI 2 "s_register_operand" "r")
2087 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2088 (match_operand:SI 1 "s_register_operand" "r")))]
2090 "bic%?\\t%0, %1, %2%S4"
2091 [(set_attr "predicable" "yes")
2092 (set_attr "shift" "2")
2093 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2094 (const_string "alu_shift")
2095 (const_string "alu_shift_reg")))]
2098 (define_insn "*andsi_notsi_si_compare0"
2099 [(set (reg:CC_NOOV CC_REGNUM)
2101 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2102 (match_operand:SI 1 "s_register_operand" "r"))
2104 (set (match_operand:SI 0 "s_register_operand" "=r")
2105 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2107 "bic%?s\\t%0, %1, %2"
2108 [(set_attr "conds" "set")]
2111 (define_insn "*andsi_notsi_si_compare0_scratch"
2112 [(set (reg:CC_NOOV CC_REGNUM)
2114 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2115 (match_operand:SI 1 "s_register_operand" "r"))
2117 (clobber (match_scratch:SI 0 "=r"))]
2119 "bic%?s\\t%0, %1, %2"
2120 [(set_attr "conds" "set")]
2123 (define_insn "iordi3"
2124 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2125 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2126 (match_operand:DI 2 "s_register_operand" "r,r")))]
2127 "TARGET_ARM && ! TARGET_IWMMXT"
2129 [(set_attr "length" "8")
2130 (set_attr "predicable" "yes")]
2133 (define_insn "*iordi_zesidi_di"
2134 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2135 (ior:DI (zero_extend:DI
2136 (match_operand:SI 2 "s_register_operand" "r,r"))
2137 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2140 orr%?\\t%Q0, %Q1, %2
2142 [(set_attr "length" "4,8")
2143 (set_attr "predicable" "yes")]
2146 (define_insn "*iordi_sesidi_di"
2147 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2148 (ior:DI (sign_extend:DI
2149 (match_operand:SI 2 "s_register_operand" "r,r"))
2150 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2153 [(set_attr "length" "8")
2154 (set_attr "predicable" "yes")]
2157 (define_expand "iorsi3"
2158 [(set (match_operand:SI 0 "s_register_operand" "")
2159 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2160 (match_operand:SI 2 "reg_or_int_operand" "")))]
2163 if (GET_CODE (operands[2]) == CONST_INT)
2167 arm_split_constant (IOR, SImode, NULL_RTX,
2168 INTVAL (operands[2]), operands[0], operands[1],
2169 optimize && !no_new_pseudos);
2172 else /* TARGET_THUMB */
2173 operands [2] = force_reg (SImode, operands [2]);
2178 (define_insn_and_split "*arm_iorsi3"
2179 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2180 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2181 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2187 && GET_CODE (operands[2]) == CONST_INT
2188 && !const_ok_for_arm (INTVAL (operands[2]))"
2189 [(clobber (const_int 0))]
2191 arm_split_constant (IOR, SImode, curr_insn,
2192 INTVAL (operands[2]), operands[0], operands[1], 0);
2195 [(set_attr "length" "4,16")
2196 (set_attr "predicable" "yes")]
2199 (define_insn "*thumb_iorsi3"
2200 [(set (match_operand:SI 0 "register_operand" "=l")
2201 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2202 (match_operand:SI 2 "register_operand" "l")))]
2205 [(set_attr "length" "2")]
2209 [(match_scratch:SI 3 "r")
2210 (set (match_operand:SI 0 "arm_general_register_operand" "")
2211 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2212 (match_operand:SI 2 "const_int_operand" "")))]
2214 && !const_ok_for_arm (INTVAL (operands[2]))
2215 && const_ok_for_arm (~INTVAL (operands[2]))"
2216 [(set (match_dup 3) (match_dup 2))
2217 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2221 (define_insn "*iorsi3_compare0"
2222 [(set (reg:CC_NOOV CC_REGNUM)
2223 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2224 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2226 (set (match_operand:SI 0 "s_register_operand" "=r")
2227 (ior:SI (match_dup 1) (match_dup 2)))]
2229 "orr%?s\\t%0, %1, %2"
2230 [(set_attr "conds" "set")]
2233 (define_insn "*iorsi3_compare0_scratch"
2234 [(set (reg:CC_NOOV CC_REGNUM)
2235 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2236 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2238 (clobber (match_scratch:SI 0 "=r"))]
2240 "orr%?s\\t%0, %1, %2"
2241 [(set_attr "conds" "set")]
2244 (define_insn "xordi3"
2245 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2246 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2247 (match_operand:DI 2 "s_register_operand" "r,r")))]
2248 "TARGET_ARM && !TARGET_IWMMXT"
2250 [(set_attr "length" "8")
2251 (set_attr "predicable" "yes")]
2254 (define_insn "*xordi_zesidi_di"
2255 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2256 (xor:DI (zero_extend:DI
2257 (match_operand:SI 2 "s_register_operand" "r,r"))
2258 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2261 eor%?\\t%Q0, %Q1, %2
2263 [(set_attr "length" "4,8")
2264 (set_attr "predicable" "yes")]
2267 (define_insn "*xordi_sesidi_di"
2268 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2269 (xor:DI (sign_extend:DI
2270 (match_operand:SI 2 "s_register_operand" "r,r"))
2271 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2274 [(set_attr "length" "8")
2275 (set_attr "predicable" "yes")]
2278 (define_expand "xorsi3"
2279 [(set (match_operand:SI 0 "s_register_operand" "")
2280 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2281 (match_operand:SI 2 "arm_rhs_operand" "")))]
2284 if (GET_CODE (operands[2]) == CONST_INT)
2285 operands[2] = force_reg (SImode, operands[2]);
2289 (define_insn "*arm_xorsi3"
2290 [(set (match_operand:SI 0 "s_register_operand" "=r")
2291 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2292 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2294 "eor%?\\t%0, %1, %2"
2295 [(set_attr "predicable" "yes")]
2298 (define_insn "*thumb_xorsi3"
2299 [(set (match_operand:SI 0 "register_operand" "=l")
2300 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2301 (match_operand:SI 2 "register_operand" "l")))]
2304 [(set_attr "length" "2")]
2307 (define_insn "*xorsi3_compare0"
2308 [(set (reg:CC_NOOV CC_REGNUM)
2309 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2310 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2312 (set (match_operand:SI 0 "s_register_operand" "=r")
2313 (xor:SI (match_dup 1) (match_dup 2)))]
2315 "eor%?s\\t%0, %1, %2"
2316 [(set_attr "conds" "set")]
2319 (define_insn "*xorsi3_compare0_scratch"
2320 [(set (reg:CC_NOOV CC_REGNUM)
2321 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2322 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2326 [(set_attr "conds" "set")]
2329 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2330 ; (NOT D) we can sometimes merge the final NOT into one of the following
2334 [(set (match_operand:SI 0 "s_register_operand" "")
2335 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2336 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2337 (match_operand:SI 3 "arm_rhs_operand" "")))
2338 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2340 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2341 (not:SI (match_dup 3))))
2342 (set (match_dup 0) (not:SI (match_dup 4)))]
2346 (define_insn "*andsi_iorsi3_notsi"
2347 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2348 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2349 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2350 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2352 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2353 [(set_attr "length" "8")
2354 (set_attr "predicable" "yes")]
2358 [(set (match_operand:SI 0 "s_register_operand" "")
2359 (match_operator:SI 1 "logical_binary_operator"
2360 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2361 (match_operand:SI 3 "const_int_operand" "")
2362 (match_operand:SI 4 "const_int_operand" ""))
2363 (match_operator:SI 9 "logical_binary_operator"
2364 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2365 (match_operand:SI 6 "const_int_operand" ""))
2366 (match_operand:SI 7 "s_register_operand" "")])]))
2367 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2369 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2370 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2373 [(ashift:SI (match_dup 2) (match_dup 4))
2377 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2380 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2384 [(set (match_operand:SI 0 "s_register_operand" "")
2385 (match_operator:SI 1 "logical_binary_operator"
2386 [(match_operator:SI 9 "logical_binary_operator"
2387 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2388 (match_operand:SI 6 "const_int_operand" ""))
2389 (match_operand:SI 7 "s_register_operand" "")])
2390 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2391 (match_operand:SI 3 "const_int_operand" "")
2392 (match_operand:SI 4 "const_int_operand" ""))]))
2393 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2395 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2396 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2399 [(ashift:SI (match_dup 2) (match_dup 4))
2403 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2406 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2410 [(set (match_operand:SI 0 "s_register_operand" "")
2411 (match_operator:SI 1 "logical_binary_operator"
2412 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2413 (match_operand:SI 3 "const_int_operand" "")
2414 (match_operand:SI 4 "const_int_operand" ""))
2415 (match_operator:SI 9 "logical_binary_operator"
2416 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2417 (match_operand:SI 6 "const_int_operand" ""))
2418 (match_operand:SI 7 "s_register_operand" "")])]))
2419 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2421 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2422 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2425 [(ashift:SI (match_dup 2) (match_dup 4))
2429 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2432 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2436 [(set (match_operand:SI 0 "s_register_operand" "")
2437 (match_operator:SI 1 "logical_binary_operator"
2438 [(match_operator:SI 9 "logical_binary_operator"
2439 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2440 (match_operand:SI 6 "const_int_operand" ""))
2441 (match_operand:SI 7 "s_register_operand" "")])
2442 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2443 (match_operand:SI 3 "const_int_operand" "")
2444 (match_operand:SI 4 "const_int_operand" ""))]))
2445 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2447 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2448 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2451 [(ashift:SI (match_dup 2) (match_dup 4))
2455 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2458 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2462 ;; Minimum and maximum insns
2464 (define_insn "smaxsi3"
2465 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2466 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2467 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2468 (clobber (reg:CC CC_REGNUM))]
2471 cmp\\t%1, %2\;movlt\\t%0, %2
2472 cmp\\t%1, %2\;movge\\t%0, %1
2473 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2474 [(set_attr "conds" "clob")
2475 (set_attr "length" "8,8,12")]
2478 (define_insn "sminsi3"
2479 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2480 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2481 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2482 (clobber (reg:CC CC_REGNUM))]
2485 cmp\\t%1, %2\;movge\\t%0, %2
2486 cmp\\t%1, %2\;movlt\\t%0, %1
2487 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2488 [(set_attr "conds" "clob")
2489 (set_attr "length" "8,8,12")]
2492 (define_insn "umaxsi3"
2493 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2494 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2495 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2496 (clobber (reg:CC CC_REGNUM))]
2499 cmp\\t%1, %2\;movcc\\t%0, %2
2500 cmp\\t%1, %2\;movcs\\t%0, %1
2501 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2502 [(set_attr "conds" "clob")
2503 (set_attr "length" "8,8,12")]
2506 (define_insn "uminsi3"
2507 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2508 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2509 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2510 (clobber (reg:CC CC_REGNUM))]
2513 cmp\\t%1, %2\;movcs\\t%0, %2
2514 cmp\\t%1, %2\;movcc\\t%0, %1
2515 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2516 [(set_attr "conds" "clob")
2517 (set_attr "length" "8,8,12")]
2520 (define_insn "*store_minmaxsi"
2521 [(set (match_operand:SI 0 "memory_operand" "=m")
2522 (match_operator:SI 3 "minmax_operator"
2523 [(match_operand:SI 1 "s_register_operand" "r")
2524 (match_operand:SI 2 "s_register_operand" "r")]))
2525 (clobber (reg:CC CC_REGNUM))]
2528 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2529 operands[1], operands[2]);
2530 output_asm_insn (\"cmp\\t%1, %2\", operands);
2531 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2532 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2535 [(set_attr "conds" "clob")
2536 (set_attr "length" "12")
2537 (set_attr "type" "store1")]
2540 ; Reject the frame pointer in operand[1], since reloading this after
2541 ; it has been eliminated can cause carnage.
2542 (define_insn "*minmax_arithsi"
2543 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2544 (match_operator:SI 4 "shiftable_operator"
2545 [(match_operator:SI 5 "minmax_operator"
2546 [(match_operand:SI 2 "s_register_operand" "r,r")
2547 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2548 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2549 (clobber (reg:CC CC_REGNUM))]
2551 && (GET_CODE (operands[1]) != REG
2552 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
2553 && REGNO(operands[1]) != ARG_POINTER_REGNUM))"
2556 enum rtx_code code = GET_CODE (operands[4]);
2558 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2559 operands[2], operands[3]);
2560 output_asm_insn (\"cmp\\t%2, %3\", operands);
2561 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2562 if (which_alternative != 0 || operands[3] != const0_rtx
2563 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2564 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2567 [(set_attr "conds" "clob")
2568 (set_attr "length" "12")]
2572 ;; Shift and rotation insns
2574 (define_expand "ashldi3"
2575 [(set (match_operand:DI 0 "s_register_operand" "")
2576 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2577 (match_operand:SI 2 "reg_or_int_operand" "")))]
2580 if (GET_CODE (operands[2]) == CONST_INT)
2582 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2584 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2587 /* Ideally we shouldn't fail here if we could know that operands[1]
2588 ends up already living in an iwmmxt register. Otherwise it's
2589 cheaper to have the alternate code being generated than moving
2590 values to iwmmxt regs and back. */
2593 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2598 (define_insn "arm_ashldi3_1bit"
2599 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2600 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2602 (clobber (reg:CC CC_REGNUM))]
2604 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2605 [(set_attr "conds" "clob")
2606 (set_attr "length" "8")]
2609 (define_expand "ashlsi3"
2610 [(set (match_operand:SI 0 "s_register_operand" "")
2611 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2612 (match_operand:SI 2 "arm_rhs_operand" "")))]
2615 if (GET_CODE (operands[2]) == CONST_INT
2616 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2618 emit_insn (gen_movsi (operands[0], const0_rtx));
2624 (define_insn "*thumb_ashlsi3"
2625 [(set (match_operand:SI 0 "register_operand" "=l,l")
2626 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2627 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2630 [(set_attr "length" "2")]
2633 (define_expand "ashrdi3"
2634 [(set (match_operand:DI 0 "s_register_operand" "")
2635 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2636 (match_operand:SI 2 "reg_or_int_operand" "")))]
2639 if (GET_CODE (operands[2]) == CONST_INT)
2641 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2643 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2646 /* Ideally we shouldn't fail here if we could know that operands[1]
2647 ends up already living in an iwmmxt register. Otherwise it's
2648 cheaper to have the alternate code being generated than moving
2649 values to iwmmxt regs and back. */
2652 else if (!TARGET_REALLY_IWMMXT)
2657 (define_insn "arm_ashrdi3_1bit"
2658 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2659 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2661 (clobber (reg:CC CC_REGNUM))]
2663 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2664 [(set_attr "conds" "clob")
2665 (set_attr "length" "8")]
2668 (define_expand "ashrsi3"
2669 [(set (match_operand:SI 0 "s_register_operand" "")
2670 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2671 (match_operand:SI 2 "arm_rhs_operand" "")))]
2674 if (GET_CODE (operands[2]) == CONST_INT
2675 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2676 operands[2] = GEN_INT (31);
2680 (define_insn "*thumb_ashrsi3"
2681 [(set (match_operand:SI 0 "register_operand" "=l,l")
2682 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2683 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2686 [(set_attr "length" "2")]
2689 (define_expand "lshrdi3"
2690 [(set (match_operand:DI 0 "s_register_operand" "")
2691 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2692 (match_operand:SI 2 "reg_or_int_operand" "")))]
2695 if (GET_CODE (operands[2]) == CONST_INT)
2697 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2699 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2702 /* Ideally we shouldn't fail here if we could know that operands[1]
2703 ends up already living in an iwmmxt register. Otherwise it's
2704 cheaper to have the alternate code being generated than moving
2705 values to iwmmxt regs and back. */
2708 else if (!TARGET_REALLY_IWMMXT)
2713 (define_insn "arm_lshrdi3_1bit"
2714 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2715 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2717 (clobber (reg:CC CC_REGNUM))]
2719 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2720 [(set_attr "conds" "clob")
2721 (set_attr "length" "8")]
2724 (define_expand "lshrsi3"
2725 [(set (match_operand:SI 0 "s_register_operand" "")
2726 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2727 (match_operand:SI 2 "arm_rhs_operand" "")))]
2730 if (GET_CODE (operands[2]) == CONST_INT
2731 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2733 emit_insn (gen_movsi (operands[0], const0_rtx));
2739 (define_insn "*thumb_lshrsi3"
2740 [(set (match_operand:SI 0 "register_operand" "=l,l")
2741 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2742 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2745 [(set_attr "length" "2")]
2748 (define_expand "rotlsi3"
2749 [(set (match_operand:SI 0 "s_register_operand" "")
2750 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2751 (match_operand:SI 2 "reg_or_int_operand" "")))]
2754 if (GET_CODE (operands[2]) == CONST_INT)
2755 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2758 rtx reg = gen_reg_rtx (SImode);
2759 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2765 (define_expand "rotrsi3"
2766 [(set (match_operand:SI 0 "s_register_operand" "")
2767 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2768 (match_operand:SI 2 "arm_rhs_operand" "")))]
2773 if (GET_CODE (operands[2]) == CONST_INT
2774 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2775 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2777 else /* TARGET_THUMB */
2779 if (GET_CODE (operands [2]) == CONST_INT)
2780 operands [2] = force_reg (SImode, operands[2]);
2785 (define_insn "*thumb_rotrsi3"
2786 [(set (match_operand:SI 0 "register_operand" "=l")
2787 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2788 (match_operand:SI 2 "register_operand" "l")))]
2791 [(set_attr "length" "2")]
2794 (define_insn "*arm_shiftsi3"
2795 [(set (match_operand:SI 0 "s_register_operand" "=r")
2796 (match_operator:SI 3 "shift_operator"
2797 [(match_operand:SI 1 "s_register_operand" "r")
2798 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2801 [(set_attr "predicable" "yes")
2802 (set_attr "shift" "1")
2803 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2804 (const_string "alu_shift")
2805 (const_string "alu_shift_reg")))]
2808 (define_insn "*shiftsi3_compare0"
2809 [(set (reg:CC_NOOV CC_REGNUM)
2810 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2811 [(match_operand:SI 1 "s_register_operand" "r")
2812 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2814 (set (match_operand:SI 0 "s_register_operand" "=r")
2815 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2817 "mov%?s\\t%0, %1%S3"
2818 [(set_attr "conds" "set")
2819 (set_attr "shift" "1")
2820 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2821 (const_string "alu_shift")
2822 (const_string "alu_shift_reg")))]
2825 (define_insn "*shiftsi3_compare0_scratch"
2826 [(set (reg:CC_NOOV CC_REGNUM)
2827 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2828 [(match_operand:SI 1 "s_register_operand" "r")
2829 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2831 (clobber (match_scratch:SI 0 "=r"))]
2833 "mov%?s\\t%0, %1%S3"
2834 [(set_attr "conds" "set")
2835 (set_attr "shift" "1")]
2838 (define_insn "*notsi_shiftsi"
2839 [(set (match_operand:SI 0 "s_register_operand" "=r")
2840 (not:SI (match_operator:SI 3 "shift_operator"
2841 [(match_operand:SI 1 "s_register_operand" "r")
2842 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2845 [(set_attr "predicable" "yes")
2846 (set_attr "shift" "1")
2847 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2848 (const_string "alu_shift")
2849 (const_string "alu_shift_reg")))]
2852 (define_insn "*notsi_shiftsi_compare0"
2853 [(set (reg:CC_NOOV CC_REGNUM)
2854 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2855 [(match_operand:SI 1 "s_register_operand" "r")
2856 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2858 (set (match_operand:SI 0 "s_register_operand" "=r")
2859 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2861 "mvn%?s\\t%0, %1%S3"
2862 [(set_attr "conds" "set")
2863 (set_attr "shift" "1")
2864 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2865 (const_string "alu_shift")
2866 (const_string "alu_shift_reg")))]
2869 (define_insn "*not_shiftsi_compare0_scratch"
2870 [(set (reg:CC_NOOV CC_REGNUM)
2871 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2872 [(match_operand:SI 1 "s_register_operand" "r")
2873 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2875 (clobber (match_scratch:SI 0 "=r"))]
2877 "mvn%?s\\t%0, %1%S3"
2878 [(set_attr "conds" "set")
2879 (set_attr "shift" "1")
2880 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2881 (const_string "alu_shift")
2882 (const_string "alu_shift_reg")))]
2885 ;; We don't really have extzv, but defining this using shifts helps
2886 ;; to reduce register pressure later on.
2888 (define_expand "extzv"
2890 (ashift:SI (match_operand:SI 1 "register_operand" "")
2891 (match_operand:SI 2 "const_int_operand" "")))
2892 (set (match_operand:SI 0 "register_operand" "")
2893 (lshiftrt:SI (match_dup 4)
2894 (match_operand:SI 3 "const_int_operand" "")))]
2898 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2899 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2901 operands[3] = GEN_INT (rshift);
2905 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2909 operands[2] = GEN_INT (lshift);
2910 operands[4] = gen_reg_rtx (SImode);
2915 ;; Unary arithmetic insns
2917 (define_expand "negdi2"
2919 [(set (match_operand:DI 0 "s_register_operand" "")
2920 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2921 (clobber (reg:CC CC_REGNUM))])]
2926 if (GET_CODE (operands[1]) != REG)
2927 operands[1] = force_reg (SImode, operands[1]);
2932 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
2933 ;; The second alternative is to allow the common case of a *full* overlap.
2934 (define_insn "*arm_negdi2"
2935 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2936 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
2937 (clobber (reg:CC CC_REGNUM))]
2939 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
2940 [(set_attr "conds" "clob")
2941 (set_attr "length" "8")]
2944 (define_insn "*thumb_negdi2"
2945 [(set (match_operand:DI 0 "register_operand" "=&l")
2946 (neg:DI (match_operand:DI 1 "register_operand" "l")))
2947 (clobber (reg:CC CC_REGNUM))]
2949 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
2950 [(set_attr "length" "6")]
2953 (define_expand "negsi2"
2954 [(set (match_operand:SI 0 "s_register_operand" "")
2955 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
2960 (define_insn "*arm_negsi2"
2961 [(set (match_operand:SI 0 "s_register_operand" "=r")
2962 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
2964 "rsb%?\\t%0, %1, #0"
2965 [(set_attr "predicable" "yes")]
2968 (define_insn "*thumb_negsi2"
2969 [(set (match_operand:SI 0 "register_operand" "=l")
2970 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
2973 [(set_attr "length" "2")]
2976 (define_expand "negsf2"
2977 [(set (match_operand:SF 0 "s_register_operand" "")
2978 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
2979 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2983 (define_expand "negdf2"
2984 [(set (match_operand:DF 0 "s_register_operand" "")
2985 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
2986 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2989 ;; abssi2 doesn't really clobber the condition codes if a different register
2990 ;; is being set. To keep things simple, assume during rtl manipulations that
2991 ;; it does, but tell the final scan operator the truth. Similarly for
2994 (define_expand "abssi2"
2996 [(set (match_operand:SI 0 "s_register_operand" "")
2997 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
2998 (clobber (reg:CC CC_REGNUM))])]
3002 (define_insn "*arm_abssi2"
3003 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3004 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
3005 (clobber (reg:CC CC_REGNUM))]
3008 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
3009 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
3010 [(set_attr "conds" "clob,*")
3011 (set_attr "shift" "1")
3012 ;; predicable can't be set based on the variant, so left as no
3013 (set_attr "length" "8")]
3016 (define_insn "*neg_abssi2"
3017 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3018 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
3019 (clobber (reg:CC CC_REGNUM))]
3022 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
3023 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
3024 [(set_attr "conds" "clob,*")
3025 (set_attr "shift" "1")
3026 ;; predicable can't be set based on the variant, so left as no
3027 (set_attr "length" "8")]
3030 (define_expand "abssf2"
3031 [(set (match_operand:SF 0 "s_register_operand" "")
3032 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
3033 "TARGET_ARM && TARGET_HARD_FLOAT"
3036 (define_expand "absdf2"
3037 [(set (match_operand:DF 0 "s_register_operand" "")
3038 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
3039 "TARGET_ARM && TARGET_HARD_FLOAT"
3042 (define_expand "sqrtsf2"
3043 [(set (match_operand:SF 0 "s_register_operand" "")
3044 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
3045 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3048 (define_expand "sqrtdf2"
3049 [(set (match_operand:DF 0 "s_register_operand" "")
3050 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
3051 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3054 (define_insn_and_split "one_cmpldi2"
3055 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3056 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
3059 "TARGET_ARM && reload_completed"
3060 [(set (match_dup 0) (not:SI (match_dup 1)))
3061 (set (match_dup 2) (not:SI (match_dup 3)))]
3064 operands[2] = gen_highpart (SImode, operands[0]);
3065 operands[0] = gen_lowpart (SImode, operands[0]);
3066 operands[3] = gen_highpart (SImode, operands[1]);
3067 operands[1] = gen_lowpart (SImode, operands[1]);
3069 [(set_attr "length" "8")
3070 (set_attr "predicable" "yes")]
3073 (define_expand "one_cmplsi2"
3074 [(set (match_operand:SI 0 "s_register_operand" "")
3075 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
3080 (define_insn "*arm_one_cmplsi2"
3081 [(set (match_operand:SI 0 "s_register_operand" "=r")
3082 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
3085 [(set_attr "predicable" "yes")]
3088 (define_insn "*thumb_one_cmplsi2"
3089 [(set (match_operand:SI 0 "register_operand" "=l")
3090 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3093 [(set_attr "length" "2")]
3096 (define_insn "*notsi_compare0"
3097 [(set (reg:CC_NOOV CC_REGNUM)
3098 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3100 (set (match_operand:SI 0 "s_register_operand" "=r")
3101 (not:SI (match_dup 1)))]
3104 [(set_attr "conds" "set")]
3107 (define_insn "*notsi_compare0_scratch"
3108 [(set (reg:CC_NOOV CC_REGNUM)
3109 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3111 (clobber (match_scratch:SI 0 "=r"))]
3114 [(set_attr "conds" "set")]
3117 ;; Fixed <--> Floating conversion insns
3119 (define_expand "floatsisf2"
3120 [(set (match_operand:SF 0 "s_register_operand" "")
3121 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3122 "TARGET_ARM && TARGET_HARD_FLOAT"
3124 if (TARGET_MAVERICK)
3126 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3131 (define_expand "floatsidf2"
3132 [(set (match_operand:DF 0 "s_register_operand" "")
3133 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3134 "TARGET_ARM && TARGET_HARD_FLOAT"
3136 if (TARGET_MAVERICK)
3138 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3143 (define_expand "fix_truncsfsi2"
3144 [(set (match_operand:SI 0 "s_register_operand" "")
3145 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3146 "TARGET_ARM && TARGET_HARD_FLOAT"
3148 if (TARGET_MAVERICK)
3150 if (!cirrus_fp_register (operands[0], SImode))
3151 operands[0] = force_reg (SImode, operands[0]);
3152 if (!cirrus_fp_register (operands[1], SFmode))
3153 operands[1] = force_reg (SFmode, operands[0]);
3154 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3159 (define_expand "fix_truncdfsi2"
3160 [(set (match_operand:SI 0 "s_register_operand" "")
3161 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3162 "TARGET_ARM && TARGET_HARD_FLOAT"
3164 if (TARGET_MAVERICK)
3166 if (!cirrus_fp_register (operands[1], DFmode))
3167 operands[1] = force_reg (DFmode, operands[0]);
3168 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3175 (define_expand "truncdfsf2"
3176 [(set (match_operand:SF 0 "s_register_operand" "")
3178 (match_operand:DF 1 "s_register_operand" "")))]
3179 "TARGET_ARM && TARGET_HARD_FLOAT"
3183 ;; Zero and sign extension instructions.
3185 (define_insn "zero_extendsidi2"
3186 [(set (match_operand:DI 0 "s_register_operand" "=r")
3187 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3190 if (REGNO (operands[1])
3191 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3192 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3193 return \"mov%?\\t%R0, #0\";
3195 [(set_attr "length" "8")
3196 (set_attr "predicable" "yes")]
3199 (define_insn "zero_extendqidi2"
3200 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3201 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3204 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3205 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3206 [(set_attr "length" "8")
3207 (set_attr "predicable" "yes")
3208 (set_attr "type" "*,load_byte")
3209 (set_attr "pool_range" "*,4092")
3210 (set_attr "neg_pool_range" "*,4084")]
3213 (define_insn "extendsidi2"
3214 [(set (match_operand:DI 0 "s_register_operand" "=r")
3215 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3218 if (REGNO (operands[1])
3219 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3220 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3221 return \"mov%?\\t%R0, %Q0, asr #31\";
3223 [(set_attr "length" "8")
3224 (set_attr "shift" "1")
3225 (set_attr "predicable" "yes")]
3228 (define_expand "zero_extendhisi2"
3230 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3232 (set (match_operand:SI 0 "s_register_operand" "")
3233 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3237 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3239 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3240 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3244 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3246 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3250 if (!s_register_operand (operands[1], HImode))
3251 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3255 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3256 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3260 operands[1] = gen_lowpart (SImode, operands[1]);
3261 operands[2] = gen_reg_rtx (SImode);
3265 (define_insn "*thumb_zero_extendhisi2"
3266 [(set (match_operand:SI 0 "register_operand" "=l")
3267 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3268 "TARGET_THUMB && !arm_arch6"
3270 rtx mem = XEXP (operands[1], 0);
3272 if (GET_CODE (mem) == CONST)
3273 mem = XEXP (mem, 0);
3275 if (GET_CODE (mem) == LABEL_REF)
3276 return \"ldr\\t%0, %1\";
3278 if (GET_CODE (mem) == PLUS)
3280 rtx a = XEXP (mem, 0);
3281 rtx b = XEXP (mem, 1);
3283 /* This can happen due to bugs in reload. */
3284 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3287 ops[0] = operands[0];
3290 output_asm_insn (\"mov %0, %1\", ops);
3292 XEXP (mem, 0) = operands[0];
3295 else if ( GET_CODE (a) == LABEL_REF
3296 && GET_CODE (b) == CONST_INT)
3297 return \"ldr\\t%0, %1\";
3300 return \"ldrh\\t%0, %1\";
3302 [(set_attr "length" "4")
3303 (set_attr "type" "load_byte")
3304 (set_attr "pool_range" "60")]
3307 (define_insn "*thumb_zero_extendhisi2_v6"
3308 [(set (match_operand:SI 0 "register_operand" "=l,l")
3309 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3310 "TARGET_THUMB && arm_arch6"
3314 if (which_alternative == 0)
3315 return \"uxth\\t%0, %1\";
3317 mem = XEXP (operands[1], 0);
3319 if (GET_CODE (mem) == CONST)
3320 mem = XEXP (mem, 0);
3322 if (GET_CODE (mem) == LABEL_REF)
3323 return \"ldr\\t%0, %1\";
3325 if (GET_CODE (mem) == PLUS)
3327 rtx a = XEXP (mem, 0);
3328 rtx b = XEXP (mem, 1);
3330 /* This can happen due to bugs in reload. */
3331 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3334 ops[0] = operands[0];
3337 output_asm_insn (\"mov %0, %1\", ops);
3339 XEXP (mem, 0) = operands[0];
3342 else if ( GET_CODE (a) == LABEL_REF
3343 && GET_CODE (b) == CONST_INT)
3344 return \"ldr\\t%0, %1\";
3347 return \"ldrh\\t%0, %1\";
3349 [(set_attr "length" "2,4")
3350 (set_attr "type" "alu_shift,load_byte")
3351 (set_attr "pool_range" "*,60")]
3354 (define_insn "*arm_zero_extendhisi2"
3355 [(set (match_operand:SI 0 "s_register_operand" "=r")
3356 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3357 "TARGET_ARM && arm_arch4 && !arm_arch6"
3359 [(set_attr "type" "load_byte")
3360 (set_attr "predicable" "yes")
3361 (set_attr "pool_range" "256")
3362 (set_attr "neg_pool_range" "244")]
3365 (define_insn "*arm_zero_extendhisi2_v6"
3366 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3367 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3368 "TARGET_ARM && arm_arch6"
3372 [(set_attr "type" "alu_shift,load_byte")
3373 (set_attr "predicable" "yes")
3374 (set_attr "pool_range" "*,256")
3375 (set_attr "neg_pool_range" "*,244")]
3378 (define_insn "*arm_zero_extendhisi2addsi"
3379 [(set (match_operand:SI 0 "s_register_operand" "=r")
3380 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3381 (match_operand:SI 2 "s_register_operand" "r")))]
3382 "TARGET_ARM && arm_arch6"
3383 "uxtah%?\\t%0, %2, %1"
3384 [(set_attr "type" "alu_shift")
3385 (set_attr "predicable" "yes")]
3389 [(set (match_operand:SI 0 "s_register_operand" "")
3390 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3391 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3392 "TARGET_ARM && (!arm_arch4)"
3393 [(set (match_dup 2) (match_dup 1))
3394 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
3396 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3402 [(set (match_operand:SI 0 "s_register_operand" "")
3403 (match_operator:SI 3 "shiftable_operator"
3404 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3405 (match_operand:SI 4 "s_register_operand" "")]))
3406 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3407 "TARGET_ARM && (!arm_arch4)"
3408 [(set (match_dup 2) (match_dup 1))
3411 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3413 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3418 (define_expand "zero_extendqisi2"
3419 [(set (match_operand:SI 0 "s_register_operand" "")
3420 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3423 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3427 emit_insn (gen_andsi3 (operands[0],
3428 gen_lowpart (SImode, operands[1]),
3431 else /* TARGET_THUMB */
3433 rtx temp = gen_reg_rtx (SImode);
3436 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3437 operands[1] = gen_lowpart (SImode, operands[1]);
3440 ops[1] = operands[1];
3441 ops[2] = GEN_INT (24);
3443 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3444 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3446 ops[0] = operands[0];
3448 ops[2] = GEN_INT (24);
3450 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3451 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3458 (define_insn "*thumb_zero_extendqisi2"
3459 [(set (match_operand:SI 0 "register_operand" "=l")
3460 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3461 "TARGET_THUMB && !arm_arch6"
3463 [(set_attr "length" "2")
3464 (set_attr "type" "load_byte")
3465 (set_attr "pool_range" "32")]
3468 (define_insn "*thumb_zero_extendqisi2_v6"
3469 [(set (match_operand:SI 0 "register_operand" "=l,l")
3470 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3471 "TARGET_THUMB && arm_arch6"
3475 [(set_attr "length" "2,2")
3476 (set_attr "type" "alu_shift,load_byte")
3477 (set_attr "pool_range" "*,32")]
3480 (define_insn "*arm_zero_extendqisi2"
3481 [(set (match_operand:SI 0 "s_register_operand" "=r")
3482 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3483 "TARGET_ARM && !arm_arch6"
3484 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3485 [(set_attr "type" "load_byte")
3486 (set_attr "predicable" "yes")
3487 (set_attr "pool_range" "4096")
3488 (set_attr "neg_pool_range" "4084")]
3491 (define_insn "*arm_zero_extendqisi2_v6"
3492 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3493 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3494 "TARGET_ARM && arm_arch6"
3497 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3498 [(set_attr "type" "alu_shift,load_byte")
3499 (set_attr "predicable" "yes")
3500 (set_attr "pool_range" "*,4096")
3501 (set_attr "neg_pool_range" "*,4084")]
3504 (define_insn "*arm_zero_extendqisi2addsi"
3505 [(set (match_operand:SI 0 "s_register_operand" "=r")
3506 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3507 (match_operand:SI 2 "s_register_operand" "r")))]
3508 "TARGET_ARM && arm_arch6"
3509 "uxtab%?\\t%0, %2, %1"
3510 [(set_attr "predicable" "yes")
3511 (set_attr "type" "alu_shift")]
3515 [(set (match_operand:SI 0 "s_register_operand" "")
3516 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3517 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3518 "TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3519 [(set (match_dup 2) (match_dup 1))
3520 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3524 (define_insn "*compareqi_eq0"
3525 [(set (reg:CC_Z CC_REGNUM)
3526 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3530 [(set_attr "conds" "set")]
3533 (define_expand "extendhisi2"
3535 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3537 (set (match_operand:SI 0 "s_register_operand" "")
3538 (ashiftrt:SI (match_dup 2)
3543 if (GET_CODE (operands[1]) == MEM)
3547 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3552 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3553 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3558 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3560 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3564 if (!s_register_operand (operands[1], HImode))
3565 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3570 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3572 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3573 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3578 operands[1] = gen_lowpart (SImode, operands[1]);
3579 operands[2] = gen_reg_rtx (SImode);
3583 (define_insn "thumb_extendhisi2"
3584 [(set (match_operand:SI 0 "register_operand" "=l")
3585 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
3586 (clobber (match_scratch:SI 2 "=&l"))]
3587 "TARGET_THUMB && !arm_arch6"
3591 rtx mem = XEXP (operands[1], 0);
3593 /* This code used to try to use 'V', and fix the address only if it was
3594 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3595 range of QImode offsets, and offsettable_address_p does a QImode
3598 if (GET_CODE (mem) == CONST)
3599 mem = XEXP (mem, 0);
3601 if (GET_CODE (mem) == LABEL_REF)
3602 return \"ldr\\t%0, %1\";
3604 if (GET_CODE (mem) == PLUS)
3606 rtx a = XEXP (mem, 0);
3607 rtx b = XEXP (mem, 1);
3609 if (GET_CODE (a) == LABEL_REF
3610 && GET_CODE (b) == CONST_INT)
3611 return \"ldr\\t%0, %1\";
3613 if (GET_CODE (b) == REG)
3614 return \"ldrsh\\t%0, %1\";
3622 ops[2] = const0_rtx;
3625 if (GET_CODE (ops[1]) != REG)
3631 ops[0] = operands[0];
3632 ops[3] = operands[2];
3633 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3636 [(set_attr "length" "4")
3637 (set_attr "type" "load_byte")
3638 (set_attr "pool_range" "1020")]
3641 ;; We used to have an early-clobber on the scratch register here.
3642 ;; However, there's a bug somewhere in reload which means that this
3643 ;; can be partially ignored during spill allocation if the memory
3644 ;; address also needs reloading; this causes an abort later on when
3645 ;; we try to verify the operands. Fortunately, we don't really need
3646 ;; the early-clobber: we can always use operand 0 if operand 2
3647 ;; overlaps the address.
3648 (define_insn "*thumb_extendhisi2_insn_v6"
3649 [(set (match_operand:SI 0 "register_operand" "=l,l")
3650 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
3651 (clobber (match_scratch:SI 2 "=X,l"))]
3652 "TARGET_THUMB && arm_arch6"
3658 if (which_alternative == 0)
3659 return \"sxth\\t%0, %1\";
3661 mem = XEXP (operands[1], 0);
3663 /* This code used to try to use 'V', and fix the address only if it was
3664 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3665 range of QImode offsets, and offsettable_address_p does a QImode
3668 if (GET_CODE (mem) == CONST)
3669 mem = XEXP (mem, 0);
3671 if (GET_CODE (mem) == LABEL_REF)
3672 return \"ldr\\t%0, %1\";
3674 if (GET_CODE (mem) == PLUS)
3676 rtx a = XEXP (mem, 0);
3677 rtx b = XEXP (mem, 1);
3679 if (GET_CODE (a) == LABEL_REF
3680 && GET_CODE (b) == CONST_INT)
3681 return \"ldr\\t%0, %1\";
3683 if (GET_CODE (b) == REG)
3684 return \"ldrsh\\t%0, %1\";
3692 ops[2] = const0_rtx;
3695 if (GET_CODE (ops[1]) != REG)
3701 ops[0] = operands[0];
3702 if (reg_mentioned_p (operands[2], ops[1]))
3705 ops[3] = operands[2];
3706 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3709 [(set_attr "length" "2,4")
3710 (set_attr "type" "alu_shift,load_byte")
3711 (set_attr "pool_range" "*,1020")]
3714 (define_expand "extendhisi2_mem"
3715 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3717 (zero_extend:SI (match_dup 7)))
3718 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
3719 (set (match_operand:SI 0 "" "")
3720 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
3725 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3727 mem1 = gen_rtx_MEM (QImode, addr);
3728 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3729 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3730 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3731 operands[0] = gen_lowpart (SImode, operands[0]);
3733 operands[2] = gen_reg_rtx (SImode);
3734 operands[3] = gen_reg_rtx (SImode);
3735 operands[6] = gen_reg_rtx (SImode);
3738 if (BYTES_BIG_ENDIAN)
3740 operands[4] = operands[2];
3741 operands[5] = operands[3];
3745 operands[4] = operands[3];
3746 operands[5] = operands[2];
3751 (define_insn "*arm_extendhisi2"
3752 [(set (match_operand:SI 0 "s_register_operand" "=r")
3753 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3754 "TARGET_ARM && arm_arch4 && !arm_arch6"
3756 [(set_attr "type" "load_byte")
3757 (set_attr "predicable" "yes")
3758 (set_attr "pool_range" "256")
3759 (set_attr "neg_pool_range" "244")]
3762 (define_insn "*arm_extendhisi2_v6"
3763 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3764 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3765 "TARGET_ARM && arm_arch6"
3769 [(set_attr "type" "alu_shift,load_byte")
3770 (set_attr "predicable" "yes")
3771 (set_attr "pool_range" "*,256")
3772 (set_attr "neg_pool_range" "*,244")]
3775 (define_insn "*arm_extendhisi2addsi"
3776 [(set (match_operand:SI 0 "s_register_operand" "=r")
3777 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3778 (match_operand:SI 2 "s_register_operand" "r")))]
3779 "TARGET_ARM && arm_arch6"
3780 "sxtah%?\\t%0, %2, %1"
3784 [(set (match_operand:SI 0 "s_register_operand" "")
3785 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3786 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3787 "TARGET_ARM && (!arm_arch4)"
3788 [(set (match_dup 2) (match_dup 1))
3789 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
3791 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3797 [(set (match_operand:SI 0 "s_register_operand" "")
3798 (match_operator:SI 3 "shiftable_operator"
3799 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3800 (match_operand:SI 4 "s_register_operand" "")]))
3801 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3802 "TARGET_ARM && (!arm_arch4)"
3803 [(set (match_dup 2) (match_dup 1))
3806 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3807 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3812 (define_expand "extendqihi2"
3814 (ashift:SI (match_operand:QI 1 "general_operand" "")
3816 (set (match_operand:HI 0 "s_register_operand" "")
3817 (ashiftrt:SI (match_dup 2)
3822 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
3824 emit_insn (gen_rtx_SET (VOIDmode,
3826 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
3829 if (!s_register_operand (operands[1], QImode))
3830 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3831 operands[0] = gen_lowpart (SImode, operands[0]);
3832 operands[1] = gen_lowpart (SImode, operands[1]);
3833 operands[2] = gen_reg_rtx (SImode);
3837 (define_insn "*extendqihi_insn"
3838 [(set (match_operand:HI 0 "s_register_operand" "=r")
3839 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
3840 "TARGET_ARM && arm_arch4"
3842 [(set_attr "type" "load_byte")
3843 (set_attr "predicable" "yes")
3844 (set_attr "pool_range" "256")
3845 (set_attr "neg_pool_range" "244")]
3848 (define_expand "extendqisi2"
3850 (ashift:SI (match_operand:QI 1 "general_operand" "")
3852 (set (match_operand:SI 0 "s_register_operand" "")
3853 (ashiftrt:SI (match_dup 2)
3858 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3860 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3861 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3865 if (!s_register_operand (operands[1], QImode))
3866 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3870 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3871 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3875 operands[1] = gen_lowpart (SImode, operands[1]);
3876 operands[2] = gen_reg_rtx (SImode);
3880 (define_insn "*arm_extendqisi"
3881 [(set (match_operand:SI 0 "s_register_operand" "=r")
3882 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
3883 "TARGET_ARM && arm_arch4 && !arm_arch6"
3885 [(set_attr "type" "load_byte")
3886 (set_attr "predicable" "yes")
3887 (set_attr "pool_range" "256")
3888 (set_attr "neg_pool_range" "244")]
3891 (define_insn "*arm_extendqisi_v6"
3892 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3893 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
3894 "TARGET_ARM && arm_arch6"
3898 [(set_attr "type" "alu_shift,load_byte")
3899 (set_attr "predicable" "yes")
3900 (set_attr "pool_range" "*,256")
3901 (set_attr "neg_pool_range" "*,244")]
3904 (define_insn "*arm_extendqisi2addsi"
3905 [(set (match_operand:SI 0 "s_register_operand" "=r")
3906 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3907 (match_operand:SI 2 "s_register_operand" "r")))]
3908 "TARGET_ARM && arm_arch6"
3909 "sxtab%?\\t%0, %2, %1"
3910 [(set_attr "type" "alu_shift")
3911 (set_attr "predicable" "yes")]
3914 (define_insn "*thumb_extendqisi2"
3915 [(set (match_operand:SI 0 "register_operand" "=l,l")
3916 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
3917 "TARGET_THUMB && !arm_arch6"
3921 rtx mem = XEXP (operands[1], 0);
3923 if (GET_CODE (mem) == CONST)
3924 mem = XEXP (mem, 0);
3926 if (GET_CODE (mem) == LABEL_REF)
3927 return \"ldr\\t%0, %1\";
3929 if (GET_CODE (mem) == PLUS
3930 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3931 return \"ldr\\t%0, %1\";
3933 if (which_alternative == 0)
3934 return \"ldrsb\\t%0, %1\";
3936 ops[0] = operands[0];
3938 if (GET_CODE (mem) == PLUS)
3940 rtx a = XEXP (mem, 0);
3941 rtx b = XEXP (mem, 1);
3946 if (GET_CODE (a) == REG)
3948 if (GET_CODE (b) == REG)
3949 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3950 else if (REGNO (a) == REGNO (ops[0]))
3952 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3953 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3954 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3957 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3959 else if (GET_CODE (b) != REG)
3963 if (REGNO (b) == REGNO (ops[0]))
3965 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3966 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3967 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3970 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3973 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3975 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3976 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3977 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3982 ops[2] = const0_rtx;
3984 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3988 [(set_attr "length" "2,6")
3989 (set_attr "type" "load_byte,load_byte")
3990 (set_attr "pool_range" "32,32")]
3993 (define_insn "*thumb_extendqisi2_v6"
3994 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
3995 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
3996 "TARGET_THUMB && arm_arch6"
4002 if (which_alternative == 0)
4003 return \"sxtb\\t%0, %1\";
4005 mem = XEXP (operands[1], 0);
4007 if (GET_CODE (mem) == CONST)
4008 mem = XEXP (mem, 0);
4010 if (GET_CODE (mem) == LABEL_REF)
4011 return \"ldr\\t%0, %1\";
4013 if (GET_CODE (mem) == PLUS
4014 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
4015 return \"ldr\\t%0, %1\";
4017 if (which_alternative == 0)
4018 return \"ldrsb\\t%0, %1\";
4020 ops[0] = operands[0];
4022 if (GET_CODE (mem) == PLUS)
4024 rtx a = XEXP (mem, 0);
4025 rtx b = XEXP (mem, 1);
4030 if (GET_CODE (a) == REG)
4032 if (GET_CODE (b) == REG)
4033 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
4034 else if (REGNO (a) == REGNO (ops[0]))
4036 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
4037 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4040 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4042 else if (GET_CODE (b) != REG)
4046 if (REGNO (b) == REGNO (ops[0]))
4048 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
4049 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4052 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4055 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
4057 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
4058 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4063 ops[2] = const0_rtx;
4065 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4069 [(set_attr "length" "2,2,4")
4070 (set_attr "type" "alu_shift,load_byte,load_byte")
4071 (set_attr "pool_range" "*,32,32")]
4074 (define_expand "extendsfdf2"
4075 [(set (match_operand:DF 0 "s_register_operand" "")
4076 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
4077 "TARGET_ARM && TARGET_HARD_FLOAT"
4081 ;; Move insns (including loads and stores)
4083 ;; XXX Just some ideas about movti.
4084 ;; I don't think these are a good idea on the arm, there just aren't enough
4086 ;;(define_expand "loadti"
4087 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4088 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4091 ;;(define_expand "storeti"
4092 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4093 ;; (match_operand:TI 1 "s_register_operand" ""))]
4096 ;;(define_expand "movti"
4097 ;; [(set (match_operand:TI 0 "general_operand" "")
4098 ;; (match_operand:TI 1 "general_operand" ""))]
4104 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4105 ;; operands[1] = copy_to_reg (operands[1]);
4106 ;; if (GET_CODE (operands[0]) == MEM)
4107 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4108 ;; else if (GET_CODE (operands[1]) == MEM)
4109 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4113 ;; emit_insn (insn);
4117 ;; Recognize garbage generated above.
4120 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4121 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4125 ;; register mem = (which_alternative < 3);
4126 ;; register const char *template;
4128 ;; operands[mem] = XEXP (operands[mem], 0);
4129 ;; switch (which_alternative)
4131 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4132 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4133 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4134 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4135 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4136 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4138 ;; output_asm_insn (template, operands);
4142 (define_expand "movdi"
4143 [(set (match_operand:DI 0 "general_operand" "")
4144 (match_operand:DI 1 "general_operand" ""))]
4149 if (!no_new_pseudos)
4151 if (GET_CODE (operands[0]) != REG)
4152 operands[1] = force_reg (DImode, operands[1]);
4158 (define_insn "*arm_movdi"
4159 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m")
4160 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
4162 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4165 return (output_move_double (operands));
4167 [(set_attr "length" "8")
4168 (set_attr "type" "*,load2,store2")
4169 (set_attr "pool_range" "*,1020,*")
4170 (set_attr "neg_pool_range" "*,1008,*")]
4173 ;; We can't actually do base+index doubleword loads if the index and
4174 ;; destination overlap. Split here so that we at least have chance to
4177 [(set (match_operand:DI 0 "s_register_operand" "")
4178 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
4179 (match_operand:SI 2 "s_register_operand" ""))))]
4181 && reg_overlap_mentioned_p (operands[0], operands[1])
4182 && reg_overlap_mentioned_p (operands[0], operands[2])"
4184 (plus:SI (match_dup 1)
4187 (mem:DI (match_dup 4)))]
4189 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
4193 ;;; ??? This should have alternatives for constants.
4194 ;;; ??? This was originally identical to the movdf_insn pattern.
4195 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4196 ;;; thumb_reorg with a memory reference.
4197 (define_insn "*thumb_movdi_insn"
4198 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4199 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4201 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4202 && ( register_operand (operands[0], DImode)
4203 || register_operand (operands[1], DImode))"
4206 switch (which_alternative)
4210 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4211 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4212 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4214 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4216 operands[1] = GEN_INT (- INTVAL (operands[1]));
4217 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4219 return \"ldmia\\t%1, {%0, %H0}\";
4221 return \"stmia\\t%0, {%1, %H1}\";
4223 return thumb_load_double_from_address (operands);
4225 operands[2] = gen_rtx_MEM (SImode,
4226 plus_constant (XEXP (operands[0], 0), 4));
4227 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4230 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4231 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4232 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4235 [(set_attr "length" "4,4,6,2,2,6,4,4")
4236 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4237 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4240 (define_expand "movsi"
4241 [(set (match_operand:SI 0 "general_operand" "")
4242 (match_operand:SI 1 "general_operand" ""))]
4247 /* Everything except mem = const or mem = mem can be done easily. */
4248 if (GET_CODE (operands[0]) == MEM)
4249 operands[1] = force_reg (SImode, operands[1]);
4250 if (arm_general_register_operand (operands[0], SImode)
4251 && GET_CODE (operands[1]) == CONST_INT
4252 && !(const_ok_for_arm (INTVAL (operands[1]))
4253 || const_ok_for_arm (~INTVAL (operands[1]))))
4255 arm_split_constant (SET, SImode, NULL_RTX,
4256 INTVAL (operands[1]), operands[0], NULL_RTX,
4257 optimize && !no_new_pseudos);
4261 else /* TARGET_THUMB.... */
4263 if (!no_new_pseudos)
4265 if (GET_CODE (operands[0]) != REG)
4266 operands[1] = force_reg (SImode, operands[1]);
4271 && (CONSTANT_P (operands[1])
4272 || symbol_mentioned_p (operands[1])
4273 || label_mentioned_p (operands[1])))
4274 operands[1] = legitimize_pic_address (operands[1], SImode,
4275 (no_new_pseudos ? operands[0] : 0));
4279 (define_insn "*arm_movsi_insn"
4280 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4281 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4282 "TARGET_ARM && ! TARGET_IWMMXT
4283 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4284 && ( register_operand (operands[0], SImode)
4285 || register_operand (operands[1], SImode))"
4291 [(set_attr "type" "*,*,load1,store1")
4292 (set_attr "predicable" "yes")
4293 (set_attr "pool_range" "*,*,4096,*")
4294 (set_attr "neg_pool_range" "*,*,4084,*")]
4298 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4299 (match_operand:SI 1 "const_int_operand" ""))]
4301 && (!(const_ok_for_arm (INTVAL (operands[1]))
4302 || const_ok_for_arm (~INTVAL (operands[1]))))"
4303 [(clobber (const_int 0))]
4305 arm_split_constant (SET, SImode, NULL_RTX,
4306 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4311 (define_insn "*thumb_movsi_insn"
4312 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4313 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4315 && ( register_operand (operands[0], SImode)
4316 || register_operand (operands[1], SImode))"
4327 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4328 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4329 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4333 [(set (match_operand:SI 0 "register_operand" "")
4334 (match_operand:SI 1 "const_int_operand" ""))]
4335 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4336 [(set (match_dup 0) (match_dup 1))
4337 (set (match_dup 0) (neg:SI (match_dup 0)))]
4338 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4342 [(set (match_operand:SI 0 "register_operand" "")
4343 (match_operand:SI 1 "const_int_operand" ""))]
4344 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4345 [(set (match_dup 0) (match_dup 1))
4346 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4349 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4350 unsigned HOST_WIDE_INT mask = 0xff;
4353 for (i = 0; i < 25; i++)
4354 if ((val & (mask << i)) == val)
4357 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4361 operands[1] = GEN_INT (val >> i);
4362 operands[2] = GEN_INT (i);
4366 ;; When generating pic, we need to load the symbol offset into a register.
4367 ;; So that the optimizer does not confuse this with a normal symbol load
4368 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4369 ;; since that is the only type of relocation we can use.
4371 ;; The rather odd constraints on the following are to force reload to leave
4372 ;; the insn alone, and to force the minipool generation pass to then move
4373 ;; the GOT symbol to memory.
4375 (define_insn "pic_load_addr_arm"
4376 [(set (match_operand:SI 0 "s_register_operand" "=r")
4377 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4378 "TARGET_ARM && flag_pic"
4380 [(set_attr "type" "load1")
4381 (set (attr "pool_range") (const_int 4096))
4382 (set (attr "neg_pool_range") (const_int 4084))]
4385 (define_insn "pic_load_addr_thumb"
4386 [(set (match_operand:SI 0 "s_register_operand" "=l")
4387 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4388 "TARGET_THUMB && flag_pic"
4390 [(set_attr "type" "load1")
4391 (set (attr "pool_range") (const_int 1024))]
4394 ;; This variant is used for AOF assembly, since it needs to mention the
4395 ;; pic register in the rtl.
4396 (define_expand "pic_load_addr_based"
4397 [(set (match_operand:SI 0 "s_register_operand" "")
4398 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4399 "TARGET_ARM && flag_pic"
4400 "operands[2] = pic_offset_table_rtx;"
4403 (define_insn "*pic_load_addr_based_insn"
4404 [(set (match_operand:SI 0 "s_register_operand" "=r")
4405 (unspec:SI [(match_operand 1 "" "")
4406 (match_operand 2 "s_register_operand" "r")]
4408 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4410 #ifdef AOF_ASSEMBLER
4411 operands[1] = aof_pic_entry (operands[1]);
4413 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4416 [(set_attr "type" "load1")
4417 (set (attr "pool_range")
4418 (if_then_else (eq_attr "is_thumb" "yes")
4421 (set (attr "neg_pool_range")
4422 (if_then_else (eq_attr "is_thumb" "yes")
4427 (define_insn "pic_add_dot_plus_four"
4428 [(set (match_operand:SI 0 "register_operand" "+r")
4429 (unspec:SI [(plus:SI (match_dup 0)
4430 (const (plus:SI (pc) (const_int 4))))]
4432 (use (label_ref (match_operand 1 "" "")))]
4433 "TARGET_THUMB && flag_pic"
4435 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4436 CODE_LABEL_NUMBER (operands[1]));
4437 return \"add\\t%0, %|pc\";
4439 [(set_attr "length" "2")]
4442 (define_insn "pic_add_dot_plus_eight"
4443 [(set (match_operand:SI 0 "register_operand" "+r")
4444 (unspec:SI [(plus:SI (match_dup 0)
4445 (const (plus:SI (pc) (const_int 8))))]
4447 (use (label_ref (match_operand 1 "" "")))]
4448 "TARGET_ARM && flag_pic"
4450 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4451 CODE_LABEL_NUMBER (operands[1]));
4452 return \"add%?\\t%0, %|pc, %0\";
4454 [(set_attr "predicable" "yes")]
4457 (define_expand "builtin_setjmp_receiver"
4458 [(label_ref (match_operand 0 "" ""))]
4462 arm_load_pic_register ();
4466 ;; If copying one reg to another we can set the condition codes according to
4467 ;; its value. Such a move is common after a return from subroutine and the
4468 ;; result is being tested against zero.
4470 (define_insn "*movsi_compare0"
4471 [(set (reg:CC CC_REGNUM)
4472 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4474 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4479 sub%?s\\t%0, %1, #0"
4480 [(set_attr "conds" "set")]
4483 ;; Subroutine to store a half word from a register into memory.
4484 ;; Operand 0 is the source register (HImode)
4485 ;; Operand 1 is the destination address in a register (SImode)
4487 ;; In both this routine and the next, we must be careful not to spill
4488 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4489 ;; can generate unrecognizable rtl.
4491 (define_expand "storehi"
4492 [;; store the low byte
4493 (set (match_operand 1 "" "") (match_dup 3))
4494 ;; extract the high byte
4496 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4497 ;; store the high byte
4498 (set (match_dup 4) (match_dup 5))]
4502 rtx op1 = operands[1];
4503 rtx addr = XEXP (op1, 0);
4504 enum rtx_code code = GET_CODE (addr);
4506 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4508 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4510 operands[4] = adjust_address (op1, QImode, 1);
4511 operands[1] = adjust_address (operands[1], QImode, 0);
4512 operands[3] = gen_lowpart (QImode, operands[0]);
4513 operands[0] = gen_lowpart (SImode, operands[0]);
4514 operands[2] = gen_reg_rtx (SImode);
4515 operands[5] = gen_lowpart (QImode, operands[2]);
4519 (define_expand "storehi_bigend"
4520 [(set (match_dup 4) (match_dup 3))
4522 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4523 (set (match_operand 1 "" "") (match_dup 5))]
4527 rtx op1 = operands[1];
4528 rtx addr = XEXP (op1, 0);
4529 enum rtx_code code = GET_CODE (addr);
4531 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4533 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4535 operands[4] = adjust_address (op1, QImode, 1);
4536 operands[1] = adjust_address (operands[1], QImode, 0);
4537 operands[3] = gen_lowpart (QImode, operands[0]);
4538 operands[0] = gen_lowpart (SImode, operands[0]);
4539 operands[2] = gen_reg_rtx (SImode);
4540 operands[5] = gen_lowpart (QImode, operands[2]);
4544 ;; Subroutine to store a half word integer constant into memory.
4545 (define_expand "storeinthi"
4546 [(set (match_operand 0 "" "")
4547 (match_operand 1 "" ""))
4548 (set (match_dup 3) (match_dup 2))]
4552 HOST_WIDE_INT value = INTVAL (operands[1]);
4553 rtx addr = XEXP (operands[0], 0);
4554 rtx op0 = operands[0];
4555 enum rtx_code code = GET_CODE (addr);
4557 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4559 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4561 operands[1] = gen_reg_rtx (SImode);
4562 if (BYTES_BIG_ENDIAN)
4564 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4565 if ((value & 255) == ((value >> 8) & 255))
4566 operands[2] = operands[1];
4569 operands[2] = gen_reg_rtx (SImode);
4570 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4575 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4576 if ((value & 255) == ((value >> 8) & 255))
4577 operands[2] = operands[1];
4580 operands[2] = gen_reg_rtx (SImode);
4581 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4585 operands[3] = adjust_address (op0, QImode, 1);
4586 operands[0] = adjust_address (operands[0], QImode, 0);
4587 operands[2] = gen_lowpart (QImode, operands[2]);
4588 operands[1] = gen_lowpart (QImode, operands[1]);
4592 (define_expand "storehi_single_op"
4593 [(set (match_operand:HI 0 "memory_operand" "")
4594 (match_operand:HI 1 "general_operand" ""))]
4595 "TARGET_ARM && arm_arch4"
4597 if (!s_register_operand (operands[1], HImode))
4598 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4602 (define_expand "movhi"
4603 [(set (match_operand:HI 0 "general_operand" "")
4604 (match_operand:HI 1 "general_operand" ""))]
4609 if (!no_new_pseudos)
4611 if (GET_CODE (operands[0]) == MEM)
4615 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4618 if (GET_CODE (operands[1]) == CONST_INT)
4619 emit_insn (gen_storeinthi (operands[0], operands[1]));
4622 if (GET_CODE (operands[1]) == MEM)
4623 operands[1] = force_reg (HImode, operands[1]);
4624 if (BYTES_BIG_ENDIAN)
4625 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4627 emit_insn (gen_storehi (operands[1], operands[0]));
4631 /* Sign extend a constant, and keep it in an SImode reg. */
4632 else if (GET_CODE (operands[1]) == CONST_INT)
4634 rtx reg = gen_reg_rtx (SImode);
4635 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4637 /* If the constant is already valid, leave it alone. */
4638 if (!const_ok_for_arm (val))
4640 /* If setting all the top bits will make the constant
4641 loadable in a single instruction, then set them.
4642 Otherwise, sign extend the number. */
4644 if (const_ok_for_arm (~(val | ~0xffff)))
4646 else if (val & 0x8000)
4650 emit_insn (gen_movsi (reg, GEN_INT (val)));
4651 operands[1] = gen_lowpart (HImode, reg);
4653 else if (arm_arch4 && optimize && !no_new_pseudos
4654 && GET_CODE (operands[1]) == MEM)
4656 rtx reg = gen_reg_rtx (SImode);
4658 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4659 operands[1] = gen_lowpart (HImode, reg);
4661 else if (!arm_arch4)
4663 if (GET_CODE (operands[1]) == MEM)
4666 rtx offset = const0_rtx;
4667 rtx reg = gen_reg_rtx (SImode);
4669 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4670 || (GET_CODE (base) == PLUS
4671 && (GET_CODE (offset = XEXP (base, 1))
4673 && ((INTVAL(offset) & 1) != 1)
4674 && GET_CODE (base = XEXP (base, 0)) == REG))
4675 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4677 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4680 new = gen_rtx_MEM (SImode,
4681 plus_constant (base, new_offset));
4682 MEM_COPY_ATTRIBUTES (new, operands[1]);
4683 emit_insn (gen_movsi (reg, new));
4684 if (((INTVAL (offset) & 2) != 0)
4685 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4687 rtx reg2 = gen_reg_rtx (SImode);
4689 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
4694 emit_insn (gen_movhi_bytes (reg, operands[1]));
4696 operands[1] = gen_lowpart (HImode, reg);
4700 /* Handle loading a large integer during reload. */
4701 else if (GET_CODE (operands[1]) == CONST_INT
4702 && !const_ok_for_arm (INTVAL (operands[1]))
4703 && !const_ok_for_arm (~INTVAL (operands[1])))
4705 /* Writing a constant to memory needs a scratch, which should
4706 be handled with SECONDARY_RELOADs. */
4707 if (GET_CODE (operands[0]) != REG)
4710 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4711 emit_insn (gen_movsi (operands[0], operands[1]));
4715 else /* TARGET_THUMB */
4717 if (!no_new_pseudos)
4719 if (GET_CODE (operands[0]) != REG)
4720 operands[1] = force_reg (HImode, operands[1]);
4722 /* ??? We shouldn't really get invalid addresses here, but this can
4723 happen if we are passed a SP (never OK for HImode/QImode) or
4724 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4725 HImode/QImode) relative address. */
4726 /* ??? This should perhaps be fixed elsewhere, for instance, in
4727 fixup_stack_1, by checking for other kinds of invalid addresses,
4728 e.g. a bare reference to a virtual register. This may confuse the
4729 alpha though, which must handle this case differently. */
4730 if (GET_CODE (operands[0]) == MEM
4731 && !memory_address_p (GET_MODE (operands[0]),
4732 XEXP (operands[0], 0)))
4734 = replace_equiv_address (operands[0],
4735 copy_to_reg (XEXP (operands[0], 0)));
4737 if (GET_CODE (operands[1]) == MEM
4738 && !memory_address_p (GET_MODE (operands[1]),
4739 XEXP (operands[1], 0)))
4741 = replace_equiv_address (operands[1],
4742 copy_to_reg (XEXP (operands[1], 0)));
4744 /* Handle loading a large integer during reload. */
4745 else if (GET_CODE (operands[1]) == CONST_INT
4746 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4748 /* Writing a constant to memory needs a scratch, which should
4749 be handled with SECONDARY_RELOADs. */
4750 if (GET_CODE (operands[0]) != REG)
4753 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4754 emit_insn (gen_movsi (operands[0], operands[1]));
4761 (define_insn "*thumb_movhi_insn"
4762 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4763 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4765 && ( register_operand (operands[0], HImode)
4766 || register_operand (operands[1], HImode))"
4768 switch (which_alternative)
4770 case 0: return \"add %0, %1, #0\";
4771 case 2: return \"strh %1, %0\";
4772 case 3: return \"mov %0, %1\";
4773 case 4: return \"mov %0, %1\";
4774 case 5: return \"mov %0, %1\";
4777 /* The stack pointer can end up being taken as an index register.
4778 Catch this case here and deal with it. */
4779 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4780 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4781 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4784 ops[0] = operands[0];
4785 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4787 output_asm_insn (\"mov %0, %1\", ops);
4789 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4792 return \"ldrh %0, %1\";
4794 [(set_attr "length" "2,4,2,2,2,2")
4795 (set_attr "type" "*,load1,store1,*,*,*")]
4799 (define_expand "movhi_bytes"
4800 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4802 (zero_extend:SI (match_dup 6)))
4803 (set (match_operand:SI 0 "" "")
4804 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4809 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4811 mem1 = gen_rtx_MEM (QImode, addr);
4812 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4813 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4814 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4815 operands[0] = gen_lowpart (SImode, operands[0]);
4817 operands[2] = gen_reg_rtx (SImode);
4818 operands[3] = gen_reg_rtx (SImode);
4821 if (BYTES_BIG_ENDIAN)
4823 operands[4] = operands[2];
4824 operands[5] = operands[3];
4828 operands[4] = operands[3];
4829 operands[5] = operands[2];
4834 (define_expand "movhi_bigend"
4836 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4839 (ashiftrt:SI (match_dup 2) (const_int 16)))
4840 (set (match_operand:HI 0 "s_register_operand" "")
4844 operands[2] = gen_reg_rtx (SImode);
4845 operands[3] = gen_reg_rtx (SImode);
4846 operands[4] = gen_lowpart (HImode, operands[3]);
4850 ;; Pattern to recognize insn generated default case above
4851 (define_insn "*movhi_insn_arch4"
4852 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4853 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4856 && (GET_CODE (operands[1]) != CONST_INT
4857 || const_ok_for_arm (INTVAL (operands[1]))
4858 || const_ok_for_arm (~INTVAL (operands[1])))"
4860 mov%?\\t%0, %1\\t%@ movhi
4861 mvn%?\\t%0, #%B1\\t%@ movhi
4862 str%?h\\t%1, %0\\t%@ movhi
4863 ldr%?h\\t%0, %1\\t%@ movhi"
4864 [(set_attr "type" "*,*,store1,load1")
4865 (set_attr "predicable" "yes")
4866 (set_attr "pool_range" "*,*,*,256")
4867 (set_attr "neg_pool_range" "*,*,*,244")]
4870 (define_insn "*movhi_bytes"
4871 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4872 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4875 mov%?\\t%0, %1\\t%@ movhi
4876 mvn%?\\t%0, #%B1\\t%@ movhi"
4877 [(set_attr "predicable" "yes")]
4880 (define_insn "thumb_movhi_clobber"
4881 [(set (match_operand:HI 0 "memory_operand" "=m")
4882 (match_operand:HI 1 "register_operand" "l"))
4883 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4889 ;; We use a DImode scratch because we may occasionally need an additional
4890 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4891 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4892 (define_expand "reload_outhi"
4893 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4894 (match_operand:HI 1 "s_register_operand" "r")
4895 (match_operand:DI 2 "s_register_operand" "=&l")])]
4898 arm_reload_out_hi (operands);
4900 thumb_reload_out_hi (operands);
4905 (define_expand "reload_inhi"
4906 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4907 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4908 (match_operand:DI 2 "s_register_operand" "=&r")])]
4912 arm_reload_in_hi (operands);
4914 thumb_reload_out_hi (operands);
4918 (define_expand "movqi"
4919 [(set (match_operand:QI 0 "general_operand" "")
4920 (match_operand:QI 1 "general_operand" ""))]
4925 /* Everything except mem = const or mem = mem can be done easily */
4927 if (!no_new_pseudos)
4929 if (GET_CODE (operands[1]) == CONST_INT)
4931 rtx reg = gen_reg_rtx (SImode);
4933 emit_insn (gen_movsi (reg, operands[1]));
4934 operands[1] = gen_lowpart (QImode, reg);
4936 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4938 rtx reg = gen_reg_rtx (SImode);
4940 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4941 operands[1] = gen_lowpart (QImode, reg);
4943 if (GET_CODE (operands[0]) == MEM)
4944 operands[1] = force_reg (QImode, operands[1]);
4947 else /* TARGET_THUMB */
4949 if (!no_new_pseudos)
4951 if (GET_CODE (operands[0]) != REG)
4952 operands[1] = force_reg (QImode, operands[1]);
4954 /* ??? We shouldn't really get invalid addresses here, but this can
4955 happen if we are passed a SP (never OK for HImode/QImode) or
4956 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4957 HImode/QImode) relative address. */
4958 /* ??? This should perhaps be fixed elsewhere, for instance, in
4959 fixup_stack_1, by checking for other kinds of invalid addresses,
4960 e.g. a bare reference to a virtual register. This may confuse the
4961 alpha though, which must handle this case differently. */
4962 if (GET_CODE (operands[0]) == MEM
4963 && !memory_address_p (GET_MODE (operands[0]),
4964 XEXP (operands[0], 0)))
4966 = replace_equiv_address (operands[0],
4967 copy_to_reg (XEXP (operands[0], 0)));
4968 if (GET_CODE (operands[1]) == MEM
4969 && !memory_address_p (GET_MODE (operands[1]),
4970 XEXP (operands[1], 0)))
4972 = replace_equiv_address (operands[1],
4973 copy_to_reg (XEXP (operands[1], 0)));
4975 /* Handle loading a large integer during reload. */
4976 else if (GET_CODE (operands[1]) == CONST_INT
4977 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
4979 /* Writing a constant to memory needs a scratch, which should
4980 be handled with SECONDARY_RELOADs. */
4981 if (GET_CODE (operands[0]) != REG)
4984 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4985 emit_insn (gen_movsi (operands[0], operands[1]));
4993 (define_insn "*arm_movqi_insn"
4994 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4995 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
4997 && ( register_operand (operands[0], QImode)
4998 || register_operand (operands[1], QImode))"
5004 [(set_attr "type" "*,*,load1,store1")
5005 (set_attr "predicable" "yes")]
5008 (define_insn "*thumb_movqi_insn"
5009 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5010 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5012 && ( register_operand (operands[0], QImode)
5013 || register_operand (operands[1], QImode))"
5021 [(set_attr "length" "2")
5022 (set_attr "type" "*,load1,store1,*,*,*")
5023 (set_attr "pool_range" "*,32,*,*,*,*")]
5026 (define_expand "movsf"
5027 [(set (match_operand:SF 0 "general_operand" "")
5028 (match_operand:SF 1 "general_operand" ""))]
5033 if (GET_CODE (operands[0]) == MEM)
5034 operands[1] = force_reg (SFmode, operands[1]);
5036 else /* TARGET_THUMB */
5038 if (!no_new_pseudos)
5040 if (GET_CODE (operands[0]) != REG)
5041 operands[1] = force_reg (SFmode, operands[1]);
5048 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5049 (match_operand:SF 1 "immediate_operand" ""))]
5051 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5053 && GET_CODE (operands[1]) == CONST_DOUBLE"
5054 [(set (match_dup 2) (match_dup 3))]
5056 operands[2] = gen_lowpart (SImode, operands[0]);
5057 operands[3] = gen_lowpart (SImode, operands[1]);
5058 if (operands[2] == 0 || operands[3] == 0)
5063 (define_insn "*arm_movsf_soft_insn"
5064 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5065 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5067 && TARGET_SOFT_FLOAT
5068 && (GET_CODE (operands[0]) != MEM
5069 || register_operand (operands[1], SFmode))"
5072 ldr%?\\t%0, %1\\t%@ float
5073 str%?\\t%1, %0\\t%@ float"
5074 [(set_attr "length" "4,4,4")
5075 (set_attr "predicable" "yes")
5076 (set_attr "type" "*,load1,store1")
5077 (set_attr "pool_range" "*,4096,*")
5078 (set_attr "neg_pool_range" "*,4084,*")]
5081 ;;; ??? This should have alternatives for constants.
5082 (define_insn "*thumb_movsf_insn"
5083 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5084 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5086 && ( register_operand (operands[0], SFmode)
5087 || register_operand (operands[1], SFmode))"
5096 [(set_attr "length" "2")
5097 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5098 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5101 (define_expand "movdf"
5102 [(set (match_operand:DF 0 "general_operand" "")
5103 (match_operand:DF 1 "general_operand" ""))]
5108 if (GET_CODE (operands[0]) == MEM)
5109 operands[1] = force_reg (DFmode, operands[1]);
5111 else /* TARGET_THUMB */
5113 if (!no_new_pseudos)
5115 if (GET_CODE (operands[0]) != REG)
5116 operands[1] = force_reg (DFmode, operands[1]);
5122 ;; Reloading a df mode value stored in integer regs to memory can require a
5124 (define_expand "reload_outdf"
5125 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5126 (match_operand:DF 1 "s_register_operand" "r")
5127 (match_operand:SI 2 "s_register_operand" "=&r")]
5131 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5134 operands[2] = XEXP (operands[0], 0);
5135 else if (code == POST_INC || code == PRE_DEC)
5137 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5138 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5139 emit_insn (gen_movdi (operands[0], operands[1]));
5142 else if (code == PRE_INC)
5144 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5146 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5149 else if (code == POST_DEC)
5150 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5152 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5153 XEXP (XEXP (operands[0], 0), 1)));
5155 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5158 if (code == POST_DEC)
5159 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5165 (define_insn "*movdf_soft_insn"
5166 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
5167 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
5168 "TARGET_ARM && TARGET_SOFT_FLOAT
5170 "* return output_move_double (operands);"
5171 [(set_attr "length" "8,8,8")
5172 (set_attr "type" "*,load2,store2")
5173 (set_attr "pool_range" "1020")
5174 (set_attr "neg_pool_range" "1008")]
5177 ;;; ??? This should have alternatives for constants.
5178 ;;; ??? This was originally identical to the movdi_insn pattern.
5179 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5180 ;;; thumb_reorg with a memory reference.
5181 (define_insn "*thumb_movdf_insn"
5182 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5183 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5185 && ( register_operand (operands[0], DFmode)
5186 || register_operand (operands[1], DFmode))"
5188 switch (which_alternative)
5192 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5193 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5194 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5196 return \"ldmia\\t%1, {%0, %H0}\";
5198 return \"stmia\\t%0, {%1, %H1}\";
5200 return thumb_load_double_from_address (operands);
5202 operands[2] = gen_rtx_MEM (SImode,
5203 plus_constant (XEXP (operands[0], 0), 4));
5204 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5207 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5208 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5209 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5212 [(set_attr "length" "4,2,2,6,4,4")
5213 (set_attr "type" "*,load2,store2,load2,store2,*")
5214 (set_attr "pool_range" "*,*,*,1020,*,*")]
5218 (define_expand "movv2si"
5219 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5220 (match_operand:V2SI 1 "general_operand" ""))]
5221 "TARGET_REALLY_IWMMXT"
5225 (define_expand "movv4hi"
5226 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5227 (match_operand:V4HI 1 "general_operand" ""))]
5228 "TARGET_REALLY_IWMMXT"
5232 (define_expand "movv8qi"
5233 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5234 (match_operand:V8QI 1 "general_operand" ""))]
5235 "TARGET_REALLY_IWMMXT"
5240 ;; load- and store-multiple insns
5241 ;; The arm can load/store any set of registers, provided that they are in
5242 ;; ascending order; but that is beyond GCC so stick with what it knows.
5244 (define_expand "load_multiple"
5245 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5246 (match_operand:SI 1 "" ""))
5247 (use (match_operand:SI 2 "" ""))])]
5250 HOST_WIDE_INT offset = 0;
5252 /* Support only fixed point registers. */
5253 if (GET_CODE (operands[2]) != CONST_INT
5254 || INTVAL (operands[2]) > 14
5255 || INTVAL (operands[2]) < 2
5256 || GET_CODE (operands[1]) != MEM
5257 || GET_CODE (operands[0]) != REG
5258 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5259 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5263 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5264 force_reg (SImode, XEXP (operands[1], 0)),
5265 TRUE, FALSE, operands[1], &offset);
5268 ;; Load multiple with write-back
5270 (define_insn "*ldmsi_postinc4"
5271 [(match_parallel 0 "load_multiple_operation"
5272 [(set (match_operand:SI 1 "s_register_operand" "=r")
5273 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5275 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5276 (mem:SI (match_dup 2)))
5277 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5278 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5279 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5280 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5281 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5282 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5283 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5284 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5285 [(set_attr "type" "load4")
5286 (set_attr "predicable" "yes")]
5289 (define_insn "*ldmsi_postinc3"
5290 [(match_parallel 0 "load_multiple_operation"
5291 [(set (match_operand:SI 1 "s_register_operand" "=r")
5292 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5294 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5295 (mem:SI (match_dup 2)))
5296 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5297 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5298 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5299 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5300 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5301 "ldm%?ia\\t%1!, {%3, %4, %5}"
5302 [(set_attr "type" "load3")
5303 (set_attr "predicable" "yes")]
5306 (define_insn "*ldmsi_postinc2"
5307 [(match_parallel 0 "load_multiple_operation"
5308 [(set (match_operand:SI 1 "s_register_operand" "=r")
5309 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5311 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5312 (mem:SI (match_dup 2)))
5313 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5314 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5315 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5316 "ldm%?ia\\t%1!, {%3, %4}"
5317 [(set_attr "type" "load2")
5318 (set_attr "predicable" "yes")]
5321 ;; Ordinary load multiple
5323 (define_insn "*ldmsi4"
5324 [(match_parallel 0 "load_multiple_operation"
5325 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5326 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5327 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5328 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5329 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5330 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5331 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5332 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5333 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5334 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5335 [(set_attr "type" "load4")
5336 (set_attr "predicable" "yes")]
5339 (define_insn "*ldmsi3"
5340 [(match_parallel 0 "load_multiple_operation"
5341 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5342 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5343 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5344 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5345 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5346 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5347 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5348 "ldm%?ia\\t%1, {%2, %3, %4}"
5349 [(set_attr "type" "load3")
5350 (set_attr "predicable" "yes")]
5353 (define_insn "*ldmsi2"
5354 [(match_parallel 0 "load_multiple_operation"
5355 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5356 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5357 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5358 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5359 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5360 "ldm%?ia\\t%1, {%2, %3}"
5361 [(set_attr "type" "load2")
5362 (set_attr "predicable" "yes")]
5365 (define_expand "store_multiple"
5366 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5367 (match_operand:SI 1 "" ""))
5368 (use (match_operand:SI 2 "" ""))])]
5371 HOST_WIDE_INT offset = 0;
5373 /* Support only fixed point registers. */
5374 if (GET_CODE (operands[2]) != CONST_INT
5375 || INTVAL (operands[2]) > 14
5376 || INTVAL (operands[2]) < 2
5377 || GET_CODE (operands[1]) != REG
5378 || GET_CODE (operands[0]) != MEM
5379 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5380 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5384 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5385 force_reg (SImode, XEXP (operands[0], 0)),
5386 TRUE, FALSE, operands[0], &offset);
5389 ;; Store multiple with write-back
5391 (define_insn "*stmsi_postinc4"
5392 [(match_parallel 0 "store_multiple_operation"
5393 [(set (match_operand:SI 1 "s_register_operand" "=r")
5394 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5396 (set (mem:SI (match_dup 2))
5397 (match_operand:SI 3 "arm_hard_register_operand" ""))
5398 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5399 (match_operand:SI 4 "arm_hard_register_operand" ""))
5400 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5401 (match_operand:SI 5 "arm_hard_register_operand" ""))
5402 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5403 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5404 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5405 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5406 [(set_attr "predicable" "yes")
5407 (set_attr "type" "store4")]
5410 (define_insn "*stmsi_postinc3"
5411 [(match_parallel 0 "store_multiple_operation"
5412 [(set (match_operand:SI 1 "s_register_operand" "=r")
5413 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5415 (set (mem:SI (match_dup 2))
5416 (match_operand:SI 3 "arm_hard_register_operand" ""))
5417 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5418 (match_operand:SI 4 "arm_hard_register_operand" ""))
5419 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5420 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5421 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5422 "stm%?ia\\t%1!, {%3, %4, %5}"
5423 [(set_attr "predicable" "yes")
5424 (set_attr "type" "store3")]
5427 (define_insn "*stmsi_postinc2"
5428 [(match_parallel 0 "store_multiple_operation"
5429 [(set (match_operand:SI 1 "s_register_operand" "=r")
5430 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5432 (set (mem:SI (match_dup 2))
5433 (match_operand:SI 3 "arm_hard_register_operand" ""))
5434 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5435 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5436 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5437 "stm%?ia\\t%1!, {%3, %4}"
5438 [(set_attr "predicable" "yes")
5439 (set_attr "type" "store2")]
5442 ;; Ordinary store multiple
5444 (define_insn "*stmsi4"
5445 [(match_parallel 0 "store_multiple_operation"
5446 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5447 (match_operand:SI 2 "arm_hard_register_operand" ""))
5448 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5449 (match_operand:SI 3 "arm_hard_register_operand" ""))
5450 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5451 (match_operand:SI 4 "arm_hard_register_operand" ""))
5452 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5453 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5454 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5455 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5456 [(set_attr "predicable" "yes")
5457 (set_attr "type" "store4")]
5460 (define_insn "*stmsi3"
5461 [(match_parallel 0 "store_multiple_operation"
5462 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5463 (match_operand:SI 2 "arm_hard_register_operand" ""))
5464 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5465 (match_operand:SI 3 "arm_hard_register_operand" ""))
5466 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5467 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5468 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5469 "stm%?ia\\t%1, {%2, %3, %4}"
5470 [(set_attr "predicable" "yes")
5471 (set_attr "type" "store3")]
5474 (define_insn "*stmsi2"
5475 [(match_parallel 0 "store_multiple_operation"
5476 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5477 (match_operand:SI 2 "arm_hard_register_operand" ""))
5478 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5479 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5480 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5481 "stm%?ia\\t%1, {%2, %3}"
5482 [(set_attr "predicable" "yes")
5483 (set_attr "type" "store2")]
5486 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5487 ;; We could let this apply for blocks of less than this, but it clobbers so
5488 ;; many registers that there is then probably a better way.
5490 (define_expand "movmemqi"
5491 [(match_operand:BLK 0 "general_operand" "")
5492 (match_operand:BLK 1 "general_operand" "")
5493 (match_operand:SI 2 "const_int_operand" "")
5494 (match_operand:SI 3 "const_int_operand" "")]
5499 if (arm_gen_movmemqi (operands))
5503 else /* TARGET_THUMB */
5505 if ( INTVAL (operands[3]) != 4
5506 || INTVAL (operands[2]) > 48)
5509 thumb_expand_movmemqi (operands);
5515 ;; Thumb block-move insns
5517 (define_insn "movmem12b"
5518 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5519 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5520 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5521 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5522 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5523 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5524 (set (match_operand:SI 0 "register_operand" "=l")
5525 (plus:SI (match_dup 2) (const_int 12)))
5526 (set (match_operand:SI 1 "register_operand" "=l")
5527 (plus:SI (match_dup 3) (const_int 12)))
5528 (clobber (match_scratch:SI 4 "=&l"))
5529 (clobber (match_scratch:SI 5 "=&l"))
5530 (clobber (match_scratch:SI 6 "=&l"))]
5532 "* return thumb_output_move_mem_multiple (3, operands);"
5533 [(set_attr "length" "4")
5534 ; This isn't entirely accurate... It loads as well, but in terms of
5535 ; scheduling the following insn it is better to consider it as a store
5536 (set_attr "type" "store3")]
5539 (define_insn "movmem8b"
5540 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5541 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5542 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5543 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5544 (set (match_operand:SI 0 "register_operand" "=l")
5545 (plus:SI (match_dup 2) (const_int 8)))
5546 (set (match_operand:SI 1 "register_operand" "=l")
5547 (plus:SI (match_dup 3) (const_int 8)))
5548 (clobber (match_scratch:SI 4 "=&l"))
5549 (clobber (match_scratch:SI 5 "=&l"))]
5551 "* return thumb_output_move_mem_multiple (2, operands);"
5552 [(set_attr "length" "4")
5553 ; This isn't entirely accurate... It loads as well, but in terms of
5554 ; scheduling the following insn it is better to consider it as a store
5555 (set_attr "type" "store2")]
5560 ;; Compare & branch insns
5561 ;; The range calculations are based as follows:
5562 ;; For forward branches, the address calculation returns the address of
5563 ;; the next instruction. This is 2 beyond the branch instruction.
5564 ;; For backward branches, the address calculation returns the address of
5565 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5566 ;; instruction for the shortest sequence, and 4 before the branch instruction
5567 ;; if we have to jump around an unconditional branch.
5568 ;; To the basic branch range the PC offset must be added (this is +4).
5569 ;; So for forward branches we have
5570 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5571 ;; And for backward branches we have
5572 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5574 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5575 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5577 (define_expand "cbranchsi4"
5578 [(set (pc) (if_then_else
5579 (match_operator 0 "arm_comparison_operator"
5580 [(match_operand:SI 1 "s_register_operand" "")
5581 (match_operand:SI 2 "nonmemory_operand" "")])
5582 (label_ref (match_operand 3 "" ""))
5586 if (thumb_cmpneg_operand (operands[2], SImode))
5588 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5589 operands[3], operands[0]));
5592 if (!thumb_cmp_operand (operands[2], SImode))
5593 operands[2] = force_reg (SImode, operands[2]);
5596 (define_insn "*cbranchsi4_insn"
5597 [(set (pc) (if_then_else
5598 (match_operator 0 "arm_comparison_operator"
5599 [(match_operand:SI 1 "s_register_operand" "l,*h")
5600 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5601 (label_ref (match_operand 3 "" ""))
5605 output_asm_insn (\"cmp\\t%1, %2\", operands);
5607 switch (get_attr_length (insn))
5609 case 4: return \"b%d0\\t%l3\";
5610 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5611 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5614 [(set (attr "far_jump")
5616 (eq_attr "length" "8")
5617 (const_string "yes")
5618 (const_string "no")))
5619 (set (attr "length")
5621 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5622 (le (minus (match_dup 3) (pc)) (const_int 256)))
5625 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5626 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5631 (define_insn "cbranchsi4_scratch"
5632 [(set (pc) (if_then_else
5633 (match_operator 4 "arm_comparison_operator"
5634 [(match_operand:SI 1 "s_register_operand" "l,0")
5635 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5636 (label_ref (match_operand 3 "" ""))
5638 (clobber (match_scratch:SI 0 "=l,l"))]
5641 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5643 switch (get_attr_length (insn))
5645 case 4: return \"b%d4\\t%l3\";
5646 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5647 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5650 [(set (attr "far_jump")
5652 (eq_attr "length" "8")
5653 (const_string "yes")
5654 (const_string "no")))
5655 (set (attr "length")
5657 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5658 (le (minus (match_dup 3) (pc)) (const_int 256)))
5661 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5662 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5666 (define_insn "*movsi_cbranchsi4"
5669 (match_operator 3 "arm_comparison_operator"
5670 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5672 (label_ref (match_operand 2 "" ""))
5674 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5678 if (which_alternative == 0)
5679 output_asm_insn (\"cmp\t%0, #0\", operands);
5680 else if (which_alternative == 1)
5681 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5684 output_asm_insn (\"cmp\t%1, #0\", operands);
5685 if (which_alternative == 2)
5686 output_asm_insn (\"mov\t%0, %1\", operands);
5688 output_asm_insn (\"str\t%1, %0\", operands);
5690 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5692 case 4: return \"b%d3\\t%l2\";
5693 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5694 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5697 [(set (attr "far_jump")
5699 (ior (and (gt (symbol_ref ("which_alternative"))
5701 (eq_attr "length" "8"))
5702 (eq_attr "length" "10"))
5703 (const_string "yes")
5704 (const_string "no")))
5705 (set (attr "length")
5707 (le (symbol_ref ("which_alternative"))
5710 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5711 (le (minus (match_dup 2) (pc)) (const_int 256)))
5714 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5715 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5719 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5720 (le (minus (match_dup 2) (pc)) (const_int 256)))
5723 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5724 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5729 (define_insn "*negated_cbranchsi4"
5732 (match_operator 0 "arm_comparison_operator"
5733 [(match_operand:SI 1 "s_register_operand" "l")
5734 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5735 (label_ref (match_operand 3 "" ""))
5739 output_asm_insn (\"cmn\\t%1, %2\", operands);
5740 switch (get_attr_length (insn))
5742 case 4: return \"b%d0\\t%l3\";
5743 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5744 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5747 [(set (attr "far_jump")
5749 (eq_attr "length" "8")
5750 (const_string "yes")
5751 (const_string "no")))
5752 (set (attr "length")
5754 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5755 (le (minus (match_dup 3) (pc)) (const_int 256)))
5758 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5759 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5764 (define_insn "*tbit_cbranch"
5767 (match_operator 0 "equality_operator"
5768 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5770 (match_operand:SI 2 "const_int_operand" "i"))
5772 (label_ref (match_operand 3 "" ""))
5774 (clobber (match_scratch:SI 4 "=l"))]
5779 op[0] = operands[4];
5780 op[1] = operands[1];
5781 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5783 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5784 switch (get_attr_length (insn))
5786 case 4: return \"b%d0\\t%l3\";
5787 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5788 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5791 [(set (attr "far_jump")
5793 (eq_attr "length" "8")
5794 (const_string "yes")
5795 (const_string "no")))
5796 (set (attr "length")
5798 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5799 (le (minus (match_dup 3) (pc)) (const_int 256)))
5802 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5803 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5808 (define_insn "*tstsi3_cbranch"
5811 (match_operator 3 "equality_operator"
5812 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5813 (match_operand:SI 1 "s_register_operand" "l"))
5815 (label_ref (match_operand 2 "" ""))
5820 output_asm_insn (\"tst\\t%0, %1\", operands);
5821 switch (get_attr_length (insn))
5823 case 4: return \"b%d3\\t%l2\";
5824 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5825 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5828 [(set (attr "far_jump")
5830 (eq_attr "length" "8")
5831 (const_string "yes")
5832 (const_string "no")))
5833 (set (attr "length")
5835 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5836 (le (minus (match_dup 2) (pc)) (const_int 256)))
5839 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5840 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5845 (define_insn "*andsi3_cbranch"
5848 (match_operator 5 "equality_operator"
5849 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5850 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5852 (label_ref (match_operand 4 "" ""))
5854 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5855 (and:SI (match_dup 2) (match_dup 3)))
5856 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5860 if (which_alternative == 0)
5861 output_asm_insn (\"and\\t%0, %3\", operands);
5862 else if (which_alternative == 1)
5864 output_asm_insn (\"and\\t%1, %3\", operands);
5865 output_asm_insn (\"mov\\t%0, %1\", operands);
5869 output_asm_insn (\"and\\t%1, %3\", operands);
5870 output_asm_insn (\"str\\t%1, %0\", operands);
5873 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5875 case 4: return \"b%d5\\t%l4\";
5876 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5877 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5880 [(set (attr "far_jump")
5882 (ior (and (eq (symbol_ref ("which_alternative"))
5884 (eq_attr "length" "8"))
5885 (eq_attr "length" "10"))
5886 (const_string "yes")
5887 (const_string "no")))
5888 (set (attr "length")
5890 (eq (symbol_ref ("which_alternative"))
5893 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5894 (le (minus (match_dup 4) (pc)) (const_int 256)))
5897 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
5898 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5902 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
5903 (le (minus (match_dup 4) (pc)) (const_int 256)))
5906 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
5907 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5912 (define_insn "*orrsi3_cbranch_scratch"
5915 (match_operator 4 "equality_operator"
5916 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
5917 (match_operand:SI 2 "s_register_operand" "l"))
5919 (label_ref (match_operand 3 "" ""))
5921 (clobber (match_scratch:SI 0 "=l"))]
5925 output_asm_insn (\"orr\\t%0, %2\", operands);
5926 switch (get_attr_length (insn))
5928 case 4: return \"b%d4\\t%l3\";
5929 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5930 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5933 [(set (attr "far_jump")
5935 (eq_attr "length" "8")
5936 (const_string "yes")
5937 (const_string "no")))
5938 (set (attr "length")
5940 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5941 (le (minus (match_dup 3) (pc)) (const_int 256)))
5944 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5945 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5950 (define_insn "*orrsi3_cbranch"
5953 (match_operator 5 "equality_operator"
5954 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5955 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5957 (label_ref (match_operand 4 "" ""))
5959 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5960 (ior:SI (match_dup 2) (match_dup 3)))
5961 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5965 if (which_alternative == 0)
5966 output_asm_insn (\"orr\\t%0, %3\", operands);
5967 else if (which_alternative == 1)
5969 output_asm_insn (\"orr\\t%1, %3\", operands);
5970 output_asm_insn (\"mov\\t%0, %1\", operands);
5974 output_asm_insn (\"orr\\t%1, %3\", operands);
5975 output_asm_insn (\"str\\t%1, %0\", operands);
5978 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5980 case 4: return \"b%d5\\t%l4\";
5981 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5982 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5985 [(set (attr "far_jump")
5987 (ior (and (eq (symbol_ref ("which_alternative"))
5989 (eq_attr "length" "8"))
5990 (eq_attr "length" "10"))
5991 (const_string "yes")
5992 (const_string "no")))
5993 (set (attr "length")
5995 (eq (symbol_ref ("which_alternative"))
5998 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5999 (le (minus (match_dup 4) (pc)) (const_int 256)))
6002 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6003 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6007 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6008 (le (minus (match_dup 4) (pc)) (const_int 256)))
6011 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6012 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6017 (define_insn "*xorsi3_cbranch_scratch"
6020 (match_operator 4 "equality_operator"
6021 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6022 (match_operand:SI 2 "s_register_operand" "l"))
6024 (label_ref (match_operand 3 "" ""))
6026 (clobber (match_scratch:SI 0 "=l"))]
6030 output_asm_insn (\"eor\\t%0, %2\", operands);
6031 switch (get_attr_length (insn))
6033 case 4: return \"b%d4\\t%l3\";
6034 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6035 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6038 [(set (attr "far_jump")
6040 (eq_attr "length" "8")
6041 (const_string "yes")
6042 (const_string "no")))
6043 (set (attr "length")
6045 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6046 (le (minus (match_dup 3) (pc)) (const_int 256)))
6049 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6050 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6055 (define_insn "*xorsi3_cbranch"
6058 (match_operator 5 "equality_operator"
6059 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6060 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6062 (label_ref (match_operand 4 "" ""))
6064 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6065 (xor:SI (match_dup 2) (match_dup 3)))
6066 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6070 if (which_alternative == 0)
6071 output_asm_insn (\"eor\\t%0, %3\", operands);
6072 else if (which_alternative == 1)
6074 output_asm_insn (\"eor\\t%1, %3\", operands);
6075 output_asm_insn (\"mov\\t%0, %1\", operands);
6079 output_asm_insn (\"eor\\t%1, %3\", operands);
6080 output_asm_insn (\"str\\t%1, %0\", operands);
6083 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6085 case 4: return \"b%d5\\t%l4\";
6086 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6087 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6090 [(set (attr "far_jump")
6092 (ior (and (eq (symbol_ref ("which_alternative"))
6094 (eq_attr "length" "8"))
6095 (eq_attr "length" "10"))
6096 (const_string "yes")
6097 (const_string "no")))
6098 (set (attr "length")
6100 (eq (symbol_ref ("which_alternative"))
6103 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6104 (le (minus (match_dup 4) (pc)) (const_int 256)))
6107 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6108 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6112 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6113 (le (minus (match_dup 4) (pc)) (const_int 256)))
6116 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6117 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6122 (define_insn "*bicsi3_cbranch_scratch"
6125 (match_operator 4 "equality_operator"
6126 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6127 (match_operand:SI 1 "s_register_operand" "0"))
6129 (label_ref (match_operand 3 "" ""))
6131 (clobber (match_scratch:SI 0 "=l"))]
6135 output_asm_insn (\"bic\\t%0, %2\", operands);
6136 switch (get_attr_length (insn))
6138 case 4: return \"b%d4\\t%l3\";
6139 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6140 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6143 [(set (attr "far_jump")
6145 (eq_attr "length" "8")
6146 (const_string "yes")
6147 (const_string "no")))
6148 (set (attr "length")
6150 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6151 (le (minus (match_dup 3) (pc)) (const_int 256)))
6154 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6155 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6160 (define_insn "*bicsi3_cbranch"
6163 (match_operator 5 "equality_operator"
6164 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
6165 (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
6167 (label_ref (match_operand 4 "" ""))
6169 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
6170 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6171 (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
6175 if (which_alternative == 0)
6176 output_asm_insn (\"bic\\t%0, %3\", operands);
6177 else if (which_alternative <= 2)
6179 output_asm_insn (\"bic\\t%1, %3\", operands);
6180 /* It's ok if OP0 is a lo-reg, even though the mov will set the
6181 conditions again, since we're only testing for equality. */
6182 output_asm_insn (\"mov\\t%0, %1\", operands);
6186 output_asm_insn (\"bic\\t%1, %3\", operands);
6187 output_asm_insn (\"str\\t%1, %0\", operands);
6190 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6192 case 4: return \"b%d5\\t%l4\";
6193 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6194 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6197 [(set (attr "far_jump")
6199 (ior (and (eq (symbol_ref ("which_alternative"))
6201 (eq_attr "length" "8"))
6202 (eq_attr "length" "10"))
6203 (const_string "yes")
6204 (const_string "no")))
6205 (set (attr "length")
6207 (eq (symbol_ref ("which_alternative"))
6210 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6211 (le (minus (match_dup 4) (pc)) (const_int 256)))
6214 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6215 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6219 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6220 (le (minus (match_dup 4) (pc)) (const_int 256)))
6223 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6224 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6229 (define_insn "*cbranchne_decr1"
6231 (if_then_else (match_operator 3 "equality_operator"
6232 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6234 (label_ref (match_operand 4 "" ""))
6236 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6237 (plus:SI (match_dup 2) (const_int -1)))
6238 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6243 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6245 VOIDmode, operands[2], const1_rtx);
6246 cond[1] = operands[4];
6248 if (which_alternative == 0)
6249 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6250 else if (which_alternative == 1)
6252 /* We must provide an alternative for a hi reg because reload
6253 cannot handle output reloads on a jump instruction, but we
6254 can't subtract into that. Fortunately a mov from lo to hi
6255 does not clobber the condition codes. */
6256 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6257 output_asm_insn (\"mov\\t%0, %1\", operands);
6261 /* Similarly, but the target is memory. */
6262 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6263 output_asm_insn (\"str\\t%1, %0\", operands);
6266 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6269 output_asm_insn (\"b%d0\\t%l1\", cond);
6272 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6273 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6275 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6276 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6280 [(set (attr "far_jump")
6282 (ior (and (eq (symbol_ref ("which_alternative"))
6284 (eq_attr "length" "8"))
6285 (eq_attr "length" "10"))
6286 (const_string "yes")
6287 (const_string "no")))
6288 (set_attr_alternative "length"
6292 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6293 (le (minus (match_dup 4) (pc)) (const_int 256)))
6296 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6297 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6302 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6303 (le (minus (match_dup 4) (pc)) (const_int 256)))
6306 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6307 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6312 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6313 (le (minus (match_dup 4) (pc)) (const_int 256)))
6316 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6317 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6322 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6323 (le (minus (match_dup 4) (pc)) (const_int 256)))
6326 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6327 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6332 (define_insn "*addsi3_cbranch"
6335 (match_operator 4 "comparison_operator"
6337 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6338 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6340 (label_ref (match_operand 5 "" ""))
6343 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6344 (plus:SI (match_dup 2) (match_dup 3)))
6345 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6347 && (GET_CODE (operands[4]) == EQ
6348 || GET_CODE (operands[4]) == NE
6349 || GET_CODE (operands[4]) == GE
6350 || GET_CODE (operands[4]) == LT)"
6356 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6357 cond[1] = operands[2];
6358 cond[2] = operands[3];
6360 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6361 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6363 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6365 if (which_alternative >= 3
6366 && which_alternative < 4)
6367 output_asm_insn (\"mov\\t%0, %1\", operands);
6368 else if (which_alternative >= 4)
6369 output_asm_insn (\"str\\t%1, %0\", operands);
6371 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6374 return \"b%d4\\t%l5\";
6376 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6378 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6382 [(set (attr "far_jump")
6384 (ior (and (lt (symbol_ref ("which_alternative"))
6386 (eq_attr "length" "8"))
6387 (eq_attr "length" "10"))
6388 (const_string "yes")
6389 (const_string "no")))
6390 (set (attr "length")
6392 (lt (symbol_ref ("which_alternative"))
6395 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6396 (le (minus (match_dup 5) (pc)) (const_int 256)))
6399 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6400 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6404 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6405 (le (minus (match_dup 5) (pc)) (const_int 256)))
6408 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6409 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6414 (define_insn "*addsi3_cbranch_scratch"
6417 (match_operator 3 "comparison_operator"
6419 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6420 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
6422 (label_ref (match_operand 4 "" ""))
6424 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6426 && (GET_CODE (operands[3]) == EQ
6427 || GET_CODE (operands[3]) == NE
6428 || GET_CODE (operands[3]) == GE
6429 || GET_CODE (operands[3]) == LT)"
6432 switch (which_alternative)
6435 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6438 output_asm_insn (\"cmn\t%1, %2\", operands);
6441 if (INTVAL (operands[2]) < 0)
6442 output_asm_insn (\"sub\t%0, %1, %2\", operands);
6444 output_asm_insn (\"add\t%0, %1, %2\", operands);
6447 if (INTVAL (operands[2]) < 0)
6448 output_asm_insn (\"sub\t%0, %0, %2\", operands);
6450 output_asm_insn (\"add\t%0, %0, %2\", operands);
6454 switch (get_attr_length (insn))
6457 return \"b%d3\\t%l4\";
6459 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6461 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6465 [(set (attr "far_jump")
6467 (eq_attr "length" "8")
6468 (const_string "yes")
6469 (const_string "no")))
6470 (set (attr "length")
6472 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6473 (le (minus (match_dup 4) (pc)) (const_int 256)))
6476 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6477 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6482 (define_insn "*subsi3_cbranch"
6485 (match_operator 4 "comparison_operator"
6487 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6488 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6490 (label_ref (match_operand 5 "" ""))
6492 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6493 (minus:SI (match_dup 2) (match_dup 3)))
6494 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6496 && (GET_CODE (operands[4]) == EQ
6497 || GET_CODE (operands[4]) == NE
6498 || GET_CODE (operands[4]) == GE
6499 || GET_CODE (operands[4]) == LT)"
6502 if (which_alternative == 0)
6503 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6504 else if (which_alternative == 1)
6506 /* We must provide an alternative for a hi reg because reload
6507 cannot handle output reloads on a jump instruction, but we
6508 can't subtract into that. Fortunately a mov from lo to hi
6509 does not clobber the condition codes. */
6510 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6511 output_asm_insn (\"mov\\t%0, %1\", operands);
6515 /* Similarly, but the target is memory. */
6516 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6517 output_asm_insn (\"str\\t%1, %0\", operands);
6520 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6523 return \"b%d4\\t%l5\";
6525 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6527 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6531 [(set (attr "far_jump")
6533 (ior (and (eq (symbol_ref ("which_alternative"))
6535 (eq_attr "length" "8"))
6536 (eq_attr "length" "10"))
6537 (const_string "yes")
6538 (const_string "no")))
6539 (set (attr "length")
6541 (eq (symbol_ref ("which_alternative"))
6544 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6545 (le (minus (match_dup 5) (pc)) (const_int 256)))
6548 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6549 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6553 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6554 (le (minus (match_dup 5) (pc)) (const_int 256)))
6557 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6558 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6563 (define_insn "*subsi3_cbranch_scratch"
6566 (match_operator 0 "arm_comparison_operator"
6567 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6568 (match_operand:SI 2 "nonmemory_operand" "l"))
6570 (label_ref (match_operand 3 "" ""))
6573 && (GET_CODE (operands[0]) == EQ
6574 || GET_CODE (operands[0]) == NE
6575 || GET_CODE (operands[0]) == GE
6576 || GET_CODE (operands[0]) == LT)"
6578 output_asm_insn (\"cmp\\t%1, %2\", operands);
6579 switch (get_attr_length (insn))
6581 case 4: return \"b%d0\\t%l3\";
6582 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6583 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6586 [(set (attr "far_jump")
6588 (eq_attr "length" "8")
6589 (const_string "yes")
6590 (const_string "no")))
6591 (set (attr "length")
6593 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6594 (le (minus (match_dup 3) (pc)) (const_int 256)))
6597 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6598 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6603 ;; Comparison and test insns
6605 (define_expand "cmpsi"
6606 [(match_operand:SI 0 "s_register_operand" "")
6607 (match_operand:SI 1 "arm_add_operand" "")]
6610 arm_compare_op0 = operands[0];
6611 arm_compare_op1 = operands[1];
6616 (define_expand "cmpsf"
6617 [(match_operand:SF 0 "s_register_operand" "")
6618 (match_operand:SF 1 "arm_float_compare_operand" "")]
6619 "TARGET_ARM && TARGET_HARD_FLOAT"
6621 arm_compare_op0 = operands[0];
6622 arm_compare_op1 = operands[1];
6627 (define_expand "cmpdf"
6628 [(match_operand:DF 0 "s_register_operand" "")
6629 (match_operand:DF 1 "arm_float_compare_operand" "")]
6630 "TARGET_ARM && TARGET_HARD_FLOAT"
6632 arm_compare_op0 = operands[0];
6633 arm_compare_op1 = operands[1];
6638 (define_insn "*arm_cmpsi_insn"
6639 [(set (reg:CC CC_REGNUM)
6640 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6641 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6646 [(set_attr "conds" "set")]
6649 (define_insn "*cmpsi_shiftsi"
6650 [(set (reg:CC CC_REGNUM)
6651 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6652 (match_operator:SI 3 "shift_operator"
6653 [(match_operand:SI 1 "s_register_operand" "r")
6654 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6657 [(set_attr "conds" "set")
6658 (set_attr "shift" "1")
6659 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6660 (const_string "alu_shift")
6661 (const_string "alu_shift_reg")))]
6664 (define_insn "*cmpsi_shiftsi_swp"
6665 [(set (reg:CC_SWP CC_REGNUM)
6666 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6667 [(match_operand:SI 1 "s_register_operand" "r")
6668 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6669 (match_operand:SI 0 "s_register_operand" "r")))]
6672 [(set_attr "conds" "set")
6673 (set_attr "shift" "1")
6674 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6675 (const_string "alu_shift")
6676 (const_string "alu_shift_reg")))]
6679 (define_insn "*cmpsi_neg_shiftsi"
6680 [(set (reg:CC CC_REGNUM)
6681 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6682 (neg:SI (match_operator:SI 3 "shift_operator"
6683 [(match_operand:SI 1 "s_register_operand" "r")
6684 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
6687 [(set_attr "conds" "set")
6688 (set_attr "shift" "1")
6689 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6690 (const_string "alu_shift")
6691 (const_string "alu_shift_reg")))]
6694 ;; Cirrus SF compare instruction
6695 (define_insn "*cirrus_cmpsf"
6696 [(set (reg:CCFP CC_REGNUM)
6697 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6698 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6699 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6700 "cfcmps%?\\tr15, %V0, %V1"
6701 [(set_attr "type" "mav_farith")
6702 (set_attr "cirrus" "compare")]
6705 ;; Cirrus DF compare instruction
6706 (define_insn "*cirrus_cmpdf"
6707 [(set (reg:CCFP CC_REGNUM)
6708 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6709 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6710 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6711 "cfcmpd%?\\tr15, %V0, %V1"
6712 [(set_attr "type" "mav_farith")
6713 (set_attr "cirrus" "compare")]
6716 ;; Cirrus DI compare instruction
6717 (define_expand "cmpdi"
6718 [(match_operand:DI 0 "cirrus_fp_register" "")
6719 (match_operand:DI 1 "cirrus_fp_register" "")]
6720 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6722 arm_compare_op0 = operands[0];
6723 arm_compare_op1 = operands[1];
6727 (define_insn "*cirrus_cmpdi"
6728 [(set (reg:CC CC_REGNUM)
6729 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6730 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6731 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6732 "cfcmp64%?\\tr15, %V0, %V1"
6733 [(set_attr "type" "mav_farith")
6734 (set_attr "cirrus" "compare")]
6737 ; This insn allows redundant compares to be removed by cse, nothing should
6738 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6739 ; is deleted later on. The match_dup will match the mode here, so that
6740 ; mode changes of the condition codes aren't lost by this even though we don't
6741 ; specify what they are.
6743 (define_insn "*deleted_compare"
6744 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6746 "\\t%@ deleted compare"
6747 [(set_attr "conds" "set")
6748 (set_attr "length" "0")]
6752 ;; Conditional branch insns
6754 (define_expand "beq"
6756 (if_then_else (eq (match_dup 1) (const_int 0))
6757 (label_ref (match_operand 0 "" ""))
6760 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6763 (define_expand "bne"
6765 (if_then_else (ne (match_dup 1) (const_int 0))
6766 (label_ref (match_operand 0 "" ""))
6769 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6772 (define_expand "bgt"
6774 (if_then_else (gt (match_dup 1) (const_int 0))
6775 (label_ref (match_operand 0 "" ""))
6778 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6781 (define_expand "ble"
6783 (if_then_else (le (match_dup 1) (const_int 0))
6784 (label_ref (match_operand 0 "" ""))
6787 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6790 (define_expand "bge"
6792 (if_then_else (ge (match_dup 1) (const_int 0))
6793 (label_ref (match_operand 0 "" ""))
6796 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6799 (define_expand "blt"
6801 (if_then_else (lt (match_dup 1) (const_int 0))
6802 (label_ref (match_operand 0 "" ""))
6805 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6808 (define_expand "bgtu"
6810 (if_then_else (gtu (match_dup 1) (const_int 0))
6811 (label_ref (match_operand 0 "" ""))
6814 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6817 (define_expand "bleu"
6819 (if_then_else (leu (match_dup 1) (const_int 0))
6820 (label_ref (match_operand 0 "" ""))
6823 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6826 (define_expand "bgeu"
6828 (if_then_else (geu (match_dup 1) (const_int 0))
6829 (label_ref (match_operand 0 "" ""))
6832 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6835 (define_expand "bltu"
6837 (if_then_else (ltu (match_dup 1) (const_int 0))
6838 (label_ref (match_operand 0 "" ""))
6841 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6844 (define_expand "bunordered"
6846 (if_then_else (unordered (match_dup 1) (const_int 0))
6847 (label_ref (match_operand 0 "" ""))
6849 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6850 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6854 (define_expand "bordered"
6856 (if_then_else (ordered (match_dup 1) (const_int 0))
6857 (label_ref (match_operand 0 "" ""))
6859 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6860 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6864 (define_expand "bungt"
6866 (if_then_else (ungt (match_dup 1) (const_int 0))
6867 (label_ref (match_operand 0 "" ""))
6869 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6870 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
6873 (define_expand "bunlt"
6875 (if_then_else (unlt (match_dup 1) (const_int 0))
6876 (label_ref (match_operand 0 "" ""))
6878 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6879 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6882 (define_expand "bunge"
6884 (if_then_else (unge (match_dup 1) (const_int 0))
6885 (label_ref (match_operand 0 "" ""))
6887 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6888 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6891 (define_expand "bunle"
6893 (if_then_else (unle (match_dup 1) (const_int 0))
6894 (label_ref (match_operand 0 "" ""))
6896 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6897 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
6900 ;; The following two patterns need two branch instructions, since there is
6901 ;; no single instruction that will handle all cases.
6902 (define_expand "buneq"
6904 (if_then_else (uneq (match_dup 1) (const_int 0))
6905 (label_ref (match_operand 0 "" ""))
6907 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6908 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
6911 (define_expand "bltgt"
6913 (if_then_else (ltgt (match_dup 1) (const_int 0))
6914 (label_ref (match_operand 0 "" ""))
6916 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6917 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
6921 ;; Patterns to match conditional branch insns.
6924 ; Special pattern to match UNEQ.
6925 (define_insn "*arm_buneq"
6927 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6928 (label_ref (match_operand 0 "" ""))
6930 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6932 if (arm_ccfsm_state != 0)
6935 return \"bvs\\t%l0\;beq\\t%l0\";
6937 [(set_attr "conds" "jump_clob")
6938 (set_attr "length" "8")]
6941 ; Special pattern to match LTGT.
6942 (define_insn "*arm_bltgt"
6944 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
6945 (label_ref (match_operand 0 "" ""))
6947 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6949 if (arm_ccfsm_state != 0)
6952 return \"bmi\\t%l0\;bgt\\t%l0\";
6954 [(set_attr "conds" "jump_clob")
6955 (set_attr "length" "8")]
6958 (define_insn "*arm_cond_branch"
6960 (if_then_else (match_operator 1 "arm_comparison_operator"
6961 [(match_operand 2 "cc_register" "") (const_int 0)])
6962 (label_ref (match_operand 0 "" ""))
6966 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6968 arm_ccfsm_state += 2;
6971 return \"b%d1\\t%l0\";
6973 [(set_attr "conds" "use")
6974 (set_attr "type" "branch")]
6977 ; Special pattern to match reversed UNEQ.
6978 (define_insn "*arm_buneq_reversed"
6980 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6982 (label_ref (match_operand 0 "" ""))))]
6983 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6985 if (arm_ccfsm_state != 0)
6988 return \"bmi\\t%l0\;bgt\\t%l0\";
6990 [(set_attr "conds" "jump_clob")
6991 (set_attr "length" "8")]
6994 ; Special pattern to match reversed LTGT.
6995 (define_insn "*arm_bltgt_reversed"
6997 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
6999 (label_ref (match_operand 0 "" ""))))]
7000 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7002 if (arm_ccfsm_state != 0)
7005 return \"bvs\\t%l0\;beq\\t%l0\";
7007 [(set_attr "conds" "jump_clob")
7008 (set_attr "length" "8")]
7011 (define_insn "*arm_cond_branch_reversed"
7013 (if_then_else (match_operator 1 "arm_comparison_operator"
7014 [(match_operand 2 "cc_register" "") (const_int 0)])
7016 (label_ref (match_operand 0 "" ""))))]
7019 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7021 arm_ccfsm_state += 2;
7024 return \"b%D1\\t%l0\";
7026 [(set_attr "conds" "use")
7027 (set_attr "type" "branch")]
7034 (define_expand "seq"
7035 [(set (match_operand:SI 0 "s_register_operand" "")
7036 (eq:SI (match_dup 1) (const_int 0)))]
7038 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7041 (define_expand "sne"
7042 [(set (match_operand:SI 0 "s_register_operand" "")
7043 (ne:SI (match_dup 1) (const_int 0)))]
7045 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7048 (define_expand "sgt"
7049 [(set (match_operand:SI 0 "s_register_operand" "")
7050 (gt:SI (match_dup 1) (const_int 0)))]
7052 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7055 (define_expand "sle"
7056 [(set (match_operand:SI 0 "s_register_operand" "")
7057 (le:SI (match_dup 1) (const_int 0)))]
7059 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7062 (define_expand "sge"
7063 [(set (match_operand:SI 0 "s_register_operand" "")
7064 (ge:SI (match_dup 1) (const_int 0)))]
7066 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7069 (define_expand "slt"
7070 [(set (match_operand:SI 0 "s_register_operand" "")
7071 (lt:SI (match_dup 1) (const_int 0)))]
7073 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7076 (define_expand "sgtu"
7077 [(set (match_operand:SI 0 "s_register_operand" "")
7078 (gtu:SI (match_dup 1) (const_int 0)))]
7080 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7083 (define_expand "sleu"
7084 [(set (match_operand:SI 0 "s_register_operand" "")
7085 (leu:SI (match_dup 1) (const_int 0)))]
7087 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7090 (define_expand "sgeu"
7091 [(set (match_operand:SI 0 "s_register_operand" "")
7092 (geu:SI (match_dup 1) (const_int 0)))]
7094 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7097 (define_expand "sltu"
7098 [(set (match_operand:SI 0 "s_register_operand" "")
7099 (ltu:SI (match_dup 1) (const_int 0)))]
7101 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7104 (define_expand "sunordered"
7105 [(set (match_operand:SI 0 "s_register_operand" "")
7106 (unordered:SI (match_dup 1) (const_int 0)))]
7107 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7108 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7112 (define_expand "sordered"
7113 [(set (match_operand:SI 0 "s_register_operand" "")
7114 (ordered:SI (match_dup 1) (const_int 0)))]
7115 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7116 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7120 (define_expand "sungt"
7121 [(set (match_operand:SI 0 "s_register_operand" "")
7122 (ungt:SI (match_dup 1) (const_int 0)))]
7123 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7124 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7128 (define_expand "sunge"
7129 [(set (match_operand:SI 0 "s_register_operand" "")
7130 (unge:SI (match_dup 1) (const_int 0)))]
7131 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7132 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7136 (define_expand "sunlt"
7137 [(set (match_operand:SI 0 "s_register_operand" "")
7138 (unlt:SI (match_dup 1) (const_int 0)))]
7139 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7140 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7144 (define_expand "sunle"
7145 [(set (match_operand:SI 0 "s_register_operand" "")
7146 (unle:SI (match_dup 1) (const_int 0)))]
7147 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7148 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7152 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7153 ;;; simple ARM instructions.
7155 ; (define_expand "suneq"
7156 ; [(set (match_operand:SI 0 "s_register_operand" "")
7157 ; (uneq:SI (match_dup 1) (const_int 0)))]
7158 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7162 ; (define_expand "sltgt"
7163 ; [(set (match_operand:SI 0 "s_register_operand" "")
7164 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7165 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7169 (define_insn "*mov_scc"
7170 [(set (match_operand:SI 0 "s_register_operand" "=r")
7171 (match_operator:SI 1 "arm_comparison_operator"
7172 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7174 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7175 [(set_attr "conds" "use")
7176 (set_attr "length" "8")]
7179 (define_insn "*mov_negscc"
7180 [(set (match_operand:SI 0 "s_register_operand" "=r")
7181 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7182 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7184 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7185 [(set_attr "conds" "use")
7186 (set_attr "length" "8")]
7189 (define_insn "*mov_notscc"
7190 [(set (match_operand:SI 0 "s_register_operand" "=r")
7191 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7192 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7194 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7195 [(set_attr "conds" "use")
7196 (set_attr "length" "8")]
7200 ;; Conditional move insns
7202 (define_expand "movsicc"
7203 [(set (match_operand:SI 0 "s_register_operand" "")
7204 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7205 (match_operand:SI 2 "arm_not_operand" "")
7206 (match_operand:SI 3 "arm_not_operand" "")))]
7210 enum rtx_code code = GET_CODE (operands[1]);
7213 if (code == UNEQ || code == LTGT)
7216 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7217 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7221 (define_expand "movsfcc"
7222 [(set (match_operand:SF 0 "s_register_operand" "")
7223 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7224 (match_operand:SF 2 "s_register_operand" "")
7225 (match_operand:SF 3 "nonmemory_operand" "")))]
7229 enum rtx_code code = GET_CODE (operands[1]);
7232 if (code == UNEQ || code == LTGT)
7235 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7236 Otherwise, ensure it is a valid FP add operand */
7237 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7238 || (!arm_float_add_operand (operands[3], SFmode)))
7239 operands[3] = force_reg (SFmode, operands[3]);
7241 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7242 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7246 (define_expand "movdfcc"
7247 [(set (match_operand:DF 0 "s_register_operand" "")
7248 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7249 (match_operand:DF 2 "s_register_operand" "")
7250 (match_operand:DF 3 "arm_float_add_operand" "")))]
7251 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7254 enum rtx_code code = GET_CODE (operands[1]);
7257 if (code == UNEQ || code == LTGT)
7260 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7261 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7265 (define_insn "*movsicc_insn"
7266 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7268 (match_operator 3 "arm_comparison_operator"
7269 [(match_operand 4 "cc_register" "") (const_int 0)])
7270 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7271 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7278 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7279 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7280 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7281 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7282 [(set_attr "length" "4,4,4,4,8,8,8,8")
7283 (set_attr "conds" "use")]
7286 (define_insn "*movsfcc_soft_insn"
7287 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7288 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7289 [(match_operand 4 "cc_register" "") (const_int 0)])
7290 (match_operand:SF 1 "s_register_operand" "0,r")
7291 (match_operand:SF 2 "s_register_operand" "r,0")))]
7292 "TARGET_ARM && TARGET_SOFT_FLOAT"
7296 [(set_attr "conds" "use")]
7300 ;; Jump and linkage insns
7302 (define_expand "jump"
7304 (label_ref (match_operand 0 "" "")))]
7309 (define_insn "*arm_jump"
7311 (label_ref (match_operand 0 "" "")))]
7315 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7317 arm_ccfsm_state += 2;
7320 return \"b%?\\t%l0\";
7323 [(set_attr "predicable" "yes")]
7326 (define_insn "*thumb_jump"
7328 (label_ref (match_operand 0 "" "")))]
7331 if (get_attr_length (insn) == 2)
7333 return \"bl\\t%l0\\t%@ far jump\";
7335 [(set (attr "far_jump")
7337 (eq_attr "length" "4")
7338 (const_string "yes")
7339 (const_string "no")))
7340 (set (attr "length")
7342 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7343 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7348 (define_expand "call"
7349 [(parallel [(call (match_operand 0 "memory_operand" "")
7350 (match_operand 1 "general_operand" ""))
7351 (use (match_operand 2 "" ""))
7352 (clobber (reg:SI LR_REGNUM))])]
7358 /* In an untyped call, we can get NULL for operand 2. */
7359 if (operands[2] == NULL_RTX)
7360 operands[2] = const0_rtx;
7362 /* This is to decide if we should generate indirect calls by loading the
7363 32 bit address of the callee into a register before performing the
7364 branch and link. operand[2] encodes the long_call/short_call
7365 attribute of the function being called. This attribute is set whenever
7366 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7367 is used, and the short_call attribute can also be set if function is
7368 declared as static or if it has already been defined in the current
7369 compilation unit. See arm.c and arm.h for info about this. The third
7370 parameter to arm_is_longcall_p is used to tell it which pattern
7372 callee = XEXP (operands[0], 0);
7374 if (GET_CODE (callee) != REG
7375 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7376 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7380 (define_insn "*call_reg_armv5"
7381 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7382 (match_operand 1 "" ""))
7383 (use (match_operand 2 "" ""))
7384 (clobber (reg:SI LR_REGNUM))]
7385 "TARGET_ARM && arm_arch5"
7387 [(set_attr "type" "call")]
7390 (define_insn "*call_reg_arm"
7391 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7392 (match_operand 1 "" ""))
7393 (use (match_operand 2 "" ""))
7394 (clobber (reg:SI LR_REGNUM))]
7395 "TARGET_ARM && !arm_arch5"
7397 return output_call (operands);
7399 ;; length is worst case, normally it is only two
7400 [(set_attr "length" "12")
7401 (set_attr "type" "call")]
7404 (define_insn "*call_mem"
7405 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7406 (match_operand 1 "" ""))
7407 (use (match_operand 2 "" ""))
7408 (clobber (reg:SI LR_REGNUM))]
7411 return output_call_mem (operands);
7413 [(set_attr "length" "12")
7414 (set_attr "type" "call")]
7417 (define_insn "*call_reg_thumb_v5"
7418 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7419 (match_operand 1 "" ""))
7420 (use (match_operand 2 "" ""))
7421 (clobber (reg:SI LR_REGNUM))]
7422 "TARGET_THUMB && arm_arch5"
7424 [(set_attr "length" "2")
7425 (set_attr "type" "call")]
7428 (define_insn "*call_reg_thumb"
7429 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7430 (match_operand 1 "" ""))
7431 (use (match_operand 2 "" ""))
7432 (clobber (reg:SI LR_REGNUM))]
7433 "TARGET_THUMB && !arm_arch5"
7436 if (TARGET_CALLER_INTERWORKING)
7437 return \"bl\\t%__interwork_call_via_%0\";
7439 return \"bl\\t%__call_via_%0\";
7441 [(set_attr "type" "call")]
7444 (define_expand "call_value"
7445 [(parallel [(set (match_operand 0 "" "")
7446 (call (match_operand 1 "memory_operand" "")
7447 (match_operand 2 "general_operand" "")))
7448 (use (match_operand 3 "" ""))
7449 (clobber (reg:SI LR_REGNUM))])]
7453 rtx callee = XEXP (operands[1], 0);
7455 /* In an untyped call, we can get NULL for operand 2. */
7456 if (operands[3] == 0)
7457 operands[3] = const0_rtx;
7459 /* See the comment in define_expand \"call\". */
7460 if (GET_CODE (callee) != REG
7461 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7462 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7466 (define_insn "*call_value_reg_armv5"
7467 [(set (match_operand 0 "" "")
7468 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7469 (match_operand 2 "" "")))
7470 (use (match_operand 3 "" ""))
7471 (clobber (reg:SI LR_REGNUM))]
7472 "TARGET_ARM && arm_arch5"
7474 [(set_attr "type" "call")]
7477 (define_insn "*call_value_reg_arm"
7478 [(set (match_operand 0 "" "")
7479 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7480 (match_operand 2 "" "")))
7481 (use (match_operand 3 "" ""))
7482 (clobber (reg:SI LR_REGNUM))]
7483 "TARGET_ARM && !arm_arch5"
7485 return output_call (&operands[1]);
7487 [(set_attr "length" "12")
7488 (set_attr "type" "call")]
7491 (define_insn "*call_value_mem"
7492 [(set (match_operand 0 "" "")
7493 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7494 (match_operand 2 "" "")))
7495 (use (match_operand 3 "" ""))
7496 (clobber (reg:SI LR_REGNUM))]
7497 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7499 return output_call_mem (&operands[1]);
7501 [(set_attr "length" "12")
7502 (set_attr "type" "call")]
7505 (define_insn "*call_value_reg_thumb_v5"
7506 [(set (match_operand 0 "" "")
7507 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7508 (match_operand 2 "" "")))
7509 (use (match_operand 3 "" ""))
7510 (clobber (reg:SI LR_REGNUM))]
7511 "TARGET_THUMB && arm_arch5"
7513 [(set_attr "length" "2")
7514 (set_attr "type" "call")]
7517 (define_insn "*call_value_reg_thumb"
7518 [(set (match_operand 0 "" "")
7519 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7520 (match_operand 2 "" "")))
7521 (use (match_operand 3 "" ""))
7522 (clobber (reg:SI LR_REGNUM))]
7523 "TARGET_THUMB && !arm_arch5"
7526 if (TARGET_CALLER_INTERWORKING)
7527 return \"bl\\t%__interwork_call_via_%1\";
7529 return \"bl\\t%__call_via_%1\";
7531 [(set_attr "type" "call")]
7534 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7535 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7537 (define_insn "*call_symbol"
7538 [(call (mem:SI (match_operand:SI 0 "" ""))
7539 (match_operand 1 "" ""))
7540 (use (match_operand 2 "" ""))
7541 (clobber (reg:SI LR_REGNUM))]
7543 && (GET_CODE (operands[0]) == SYMBOL_REF)
7544 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7547 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7549 [(set_attr "type" "call")]
7552 (define_insn "*call_value_symbol"
7553 [(set (match_operand 0 "s_register_operand" "")
7554 (call (mem:SI (match_operand:SI 1 "" ""))
7555 (match_operand:SI 2 "" "")))
7556 (use (match_operand 3 "" ""))
7557 (clobber (reg:SI LR_REGNUM))]
7559 && (GET_CODE (operands[1]) == SYMBOL_REF)
7560 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7563 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7565 [(set_attr "type" "call")]
7568 (define_insn "*call_insn"
7569 [(call (mem:SI (match_operand:SI 0 "" ""))
7570 (match_operand:SI 1 "" ""))
7571 (use (match_operand 2 "" ""))
7572 (clobber (reg:SI LR_REGNUM))]
7574 && GET_CODE (operands[0]) == SYMBOL_REF
7575 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7577 [(set_attr "length" "4")
7578 (set_attr "type" "call")]
7581 (define_insn "*call_value_insn"
7582 [(set (match_operand 0 "register_operand" "")
7583 (call (mem:SI (match_operand 1 "" ""))
7584 (match_operand 2 "" "")))
7585 (use (match_operand 3 "" ""))
7586 (clobber (reg:SI LR_REGNUM))]
7588 && GET_CODE (operands[1]) == SYMBOL_REF
7589 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7591 [(set_attr "length" "4")
7592 (set_attr "type" "call")]
7595 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7596 (define_expand "sibcall"
7597 [(parallel [(call (match_operand 0 "memory_operand" "")
7598 (match_operand 1 "general_operand" ""))
7600 (use (match_operand 2 "" ""))])]
7604 if (operands[2] == NULL_RTX)
7605 operands[2] = const0_rtx;
7609 (define_expand "sibcall_value"
7610 [(parallel [(set (match_operand 0 "register_operand" "")
7611 (call (match_operand 1 "memory_operand" "")
7612 (match_operand 2 "general_operand" "")))
7614 (use (match_operand 3 "" ""))])]
7618 if (operands[3] == NULL_RTX)
7619 operands[3] = const0_rtx;
7623 (define_insn "*sibcall_insn"
7624 [(call (mem:SI (match_operand:SI 0 "" "X"))
7625 (match_operand 1 "" ""))
7627 (use (match_operand 2 "" ""))]
7628 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7630 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7632 [(set_attr "type" "call")]
7635 (define_insn "*sibcall_value_insn"
7636 [(set (match_operand 0 "s_register_operand" "")
7637 (call (mem:SI (match_operand:SI 1 "" "X"))
7638 (match_operand 2 "" "")))
7640 (use (match_operand 3 "" ""))]
7641 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7643 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7645 [(set_attr "type" "call")]
7648 ;; Often the return insn will be the same as loading from memory, so set attr
7649 (define_insn "return"
7651 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7654 if (arm_ccfsm_state == 2)
7656 arm_ccfsm_state += 2;
7659 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7661 [(set_attr "type" "load1")
7662 (set_attr "length" "12")
7663 (set_attr "predicable" "yes")]
7666 (define_insn "*cond_return"
7668 (if_then_else (match_operator 0 "arm_comparison_operator"
7669 [(match_operand 1 "cc_register" "") (const_int 0)])
7672 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7675 if (arm_ccfsm_state == 2)
7677 arm_ccfsm_state += 2;
7680 return output_return_instruction (operands[0], TRUE, FALSE);
7682 [(set_attr "conds" "use")
7683 (set_attr "length" "12")
7684 (set_attr "type" "load1")]
7687 (define_insn "*cond_return_inverted"
7689 (if_then_else (match_operator 0 "arm_comparison_operator"
7690 [(match_operand 1 "cc_register" "") (const_int 0)])
7693 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7696 if (arm_ccfsm_state == 2)
7698 arm_ccfsm_state += 2;
7701 return output_return_instruction (operands[0], TRUE, TRUE);
7703 [(set_attr "conds" "use")
7704 (set_attr "length" "12")
7705 (set_attr "type" "load1")]
7708 ;; Generate a sequence of instructions to determine if the processor is
7709 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7712 (define_expand "return_addr_mask"
7714 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7716 (set (match_operand:SI 0 "s_register_operand" "")
7717 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7719 (const_int 67108860)))] ; 0x03fffffc
7722 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7725 (define_insn "*check_arch2"
7726 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7727 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7730 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7731 [(set_attr "length" "8")
7732 (set_attr "conds" "set")]
7735 ;; Call subroutine returning any type.
7737 (define_expand "untyped_call"
7738 [(parallel [(call (match_operand 0 "" "")
7740 (match_operand 1 "" "")
7741 (match_operand 2 "" "")])]
7747 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7749 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7751 rtx set = XVECEXP (operands[2], 0, i);
7753 emit_move_insn (SET_DEST (set), SET_SRC (set));
7756 /* The optimizer does not know that the call sets the function value
7757 registers we stored in the result block. We avoid problems by
7758 claiming that all hard registers are used and clobbered at this
7760 emit_insn (gen_blockage ());
7766 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7767 ;; all of memory. This blocks insns from being moved across this point.
7769 (define_insn "blockage"
7770 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7773 [(set_attr "length" "0")
7774 (set_attr "type" "block")]
7777 (define_expand "casesi"
7778 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7779 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7780 (match_operand:SI 2 "const_int_operand" "") ; total range
7781 (match_operand:SI 3 "" "") ; table label
7782 (match_operand:SI 4 "" "")] ; Out of range label
7787 if (operands[1] != const0_rtx)
7789 reg = gen_reg_rtx (SImode);
7791 emit_insn (gen_addsi3 (reg, operands[0],
7792 GEN_INT (-INTVAL (operands[1]))));
7796 if (!const_ok_for_arm (INTVAL (operands[2])))
7797 operands[2] = force_reg (SImode, operands[2]);
7799 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
7805 ;; The USE in this pattern is needed to tell flow analysis that this is
7806 ;; a CASESI insn. It has no other purpose.
7807 (define_insn "casesi_internal"
7808 [(parallel [(set (pc)
7810 (leu (match_operand:SI 0 "s_register_operand" "r")
7811 (match_operand:SI 1 "arm_rhs_operand" "rI"))
7812 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
7813 (label_ref (match_operand 2 "" ""))))
7814 (label_ref (match_operand 3 "" ""))))
7815 (clobber (reg:CC CC_REGNUM))
7816 (use (label_ref (match_dup 2)))])]
7820 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
7821 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
7823 [(set_attr "conds" "clob")
7824 (set_attr "length" "12")]
7827 (define_expand "indirect_jump"
7829 (match_operand:SI 0 "s_register_operand" ""))]
7834 ;; NB Never uses BX.
7835 (define_insn "*arm_indirect_jump"
7837 (match_operand:SI 0 "s_register_operand" "r"))]
7839 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
7840 [(set_attr "predicable" "yes")]
7843 (define_insn "*load_indirect_jump"
7845 (match_operand:SI 0 "memory_operand" "m"))]
7847 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
7848 [(set_attr "type" "load1")
7849 (set_attr "pool_range" "4096")
7850 (set_attr "neg_pool_range" "4084")
7851 (set_attr "predicable" "yes")]
7854 ;; NB Never uses BX.
7855 (define_insn "*thumb_indirect_jump"
7857 (match_operand:SI 0 "register_operand" "l*r"))]
7860 [(set_attr "conds" "clob")
7861 (set_attr "length" "2")]
7872 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
7873 return \"mov\\tr8, r8\";
7875 [(set (attr "length")
7876 (if_then_else (eq_attr "is_thumb" "yes")
7882 ;; Patterns to allow combination of arithmetic, cond code and shifts
7884 (define_insn "*arith_shiftsi"
7885 [(set (match_operand:SI 0 "s_register_operand" "=r")
7886 (match_operator:SI 1 "shiftable_operator"
7887 [(match_operator:SI 3 "shift_operator"
7888 [(match_operand:SI 4 "s_register_operand" "r")
7889 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7890 (match_operand:SI 2 "s_register_operand" "r")]))]
7892 "%i1%?\\t%0, %2, %4%S3"
7893 [(set_attr "predicable" "yes")
7894 (set_attr "shift" "4")
7895 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7896 (const_string "alu_shift")
7897 (const_string "alu_shift_reg")))]
7901 [(set (match_operand:SI 0 "s_register_operand" "")
7902 (match_operator:SI 1 "shiftable_operator"
7903 [(match_operator:SI 2 "shiftable_operator"
7904 [(match_operator:SI 3 "shift_operator"
7905 [(match_operand:SI 4 "s_register_operand" "")
7906 (match_operand:SI 5 "reg_or_int_operand" "")])
7907 (match_operand:SI 6 "s_register_operand" "")])
7908 (match_operand:SI 7 "arm_rhs_operand" "")]))
7909 (clobber (match_operand:SI 8 "s_register_operand" ""))]
7912 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7915 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
7918 (define_insn "*arith_shiftsi_compare0"
7919 [(set (reg:CC_NOOV CC_REGNUM)
7920 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7921 [(match_operator:SI 3 "shift_operator"
7922 [(match_operand:SI 4 "s_register_operand" "r")
7923 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7924 (match_operand:SI 2 "s_register_operand" "r")])
7926 (set (match_operand:SI 0 "s_register_operand" "=r")
7927 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7930 "%i1%?s\\t%0, %2, %4%S3"
7931 [(set_attr "conds" "set")
7932 (set_attr "shift" "4")
7933 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7934 (const_string "alu_shift")
7935 (const_string "alu_shift_reg")))]
7938 (define_insn "*arith_shiftsi_compare0_scratch"
7939 [(set (reg:CC_NOOV CC_REGNUM)
7940 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7941 [(match_operator:SI 3 "shift_operator"
7942 [(match_operand:SI 4 "s_register_operand" "r")
7943 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7944 (match_operand:SI 2 "s_register_operand" "r")])
7946 (clobber (match_scratch:SI 0 "=r"))]
7948 "%i1%?s\\t%0, %2, %4%S3"
7949 [(set_attr "conds" "set")
7950 (set_attr "shift" "4")
7951 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7952 (const_string "alu_shift")
7953 (const_string "alu_shift_reg")))]
7956 (define_insn "*sub_shiftsi"
7957 [(set (match_operand:SI 0 "s_register_operand" "=r")
7958 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7959 (match_operator:SI 2 "shift_operator"
7960 [(match_operand:SI 3 "s_register_operand" "r")
7961 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
7963 "sub%?\\t%0, %1, %3%S2"
7964 [(set_attr "predicable" "yes")
7965 (set_attr "shift" "3")
7966 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7967 (const_string "alu_shift")
7968 (const_string "alu_shift_reg")))]
7971 (define_insn "*sub_shiftsi_compare0"
7972 [(set (reg:CC_NOOV CC_REGNUM)
7974 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7975 (match_operator:SI 2 "shift_operator"
7976 [(match_operand:SI 3 "s_register_operand" "r")
7977 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7979 (set (match_operand:SI 0 "s_register_operand" "=r")
7980 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
7983 "sub%?s\\t%0, %1, %3%S2"
7984 [(set_attr "conds" "set")
7985 (set_attr "shift" "3")
7986 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7987 (const_string "alu_shift")
7988 (const_string "alu_shift_reg")))]
7991 (define_insn "*sub_shiftsi_compare0_scratch"
7992 [(set (reg:CC_NOOV CC_REGNUM)
7994 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7995 (match_operator:SI 2 "shift_operator"
7996 [(match_operand:SI 3 "s_register_operand" "r")
7997 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7999 (clobber (match_scratch:SI 0 "=r"))]
8001 "sub%?s\\t%0, %1, %3%S2"
8002 [(set_attr "conds" "set")
8003 (set_attr "shift" "3")
8004 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8005 (const_string "alu_shift")
8006 (const_string "alu_shift_reg")))]
8011 (define_insn "*and_scc"
8012 [(set (match_operand:SI 0 "s_register_operand" "=r")
8013 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8014 [(match_operand 3 "cc_register" "") (const_int 0)])
8015 (match_operand:SI 2 "s_register_operand" "r")))]
8017 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8018 [(set_attr "conds" "use")
8019 (set_attr "length" "8")]
8022 (define_insn "*ior_scc"
8023 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8024 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8025 [(match_operand 3 "cc_register" "") (const_int 0)])
8026 (match_operand:SI 1 "s_register_operand" "0,?r")))]
8030 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8031 [(set_attr "conds" "use")
8032 (set_attr "length" "4,8")]
8035 (define_insn "*compare_scc"
8036 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8037 (match_operator:SI 1 "arm_comparison_operator"
8038 [(match_operand:SI 2 "s_register_operand" "r,r")
8039 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8040 (clobber (reg:CC CC_REGNUM))]
8043 if (operands[3] == const0_rtx)
8045 if (GET_CODE (operands[1]) == LT)
8046 return \"mov\\t%0, %2, lsr #31\";
8048 if (GET_CODE (operands[1]) == GE)
8049 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8051 if (GET_CODE (operands[1]) == EQ)
8052 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8055 if (GET_CODE (operands[1]) == NE)
8057 if (which_alternative == 1)
8058 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8059 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8061 if (which_alternative == 1)
8062 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8064 output_asm_insn (\"cmp\\t%2, %3\", operands);
8065 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8067 [(set_attr "conds" "clob")
8068 (set_attr "length" "12")]
8071 (define_insn "*cond_move"
8072 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8073 (if_then_else:SI (match_operator 3 "equality_operator"
8074 [(match_operator 4 "arm_comparison_operator"
8075 [(match_operand 5 "cc_register" "") (const_int 0)])
8077 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8078 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8081 if (GET_CODE (operands[3]) == NE)
8083 if (which_alternative != 1)
8084 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8085 if (which_alternative != 0)
8086 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8089 if (which_alternative != 0)
8090 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8091 if (which_alternative != 1)
8092 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8095 [(set_attr "conds" "use")
8096 (set_attr "length" "4,4,8")]
8099 (define_insn "*cond_arith"
8100 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8101 (match_operator:SI 5 "shiftable_operator"
8102 [(match_operator:SI 4 "arm_comparison_operator"
8103 [(match_operand:SI 2 "s_register_operand" "r,r")
8104 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8105 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8106 (clobber (reg:CC CC_REGNUM))]
8109 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8110 return \"%i5\\t%0, %1, %2, lsr #31\";
8112 output_asm_insn (\"cmp\\t%2, %3\", operands);
8113 if (GET_CODE (operands[5]) == AND)
8114 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8115 else if (GET_CODE (operands[5]) == MINUS)
8116 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8117 else if (which_alternative != 0)
8118 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8119 return \"%i5%d4\\t%0, %1, #1\";
8121 [(set_attr "conds" "clob")
8122 (set_attr "length" "12")]
8125 (define_insn "*cond_sub"
8126 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8127 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8128 (match_operator:SI 4 "arm_comparison_operator"
8129 [(match_operand:SI 2 "s_register_operand" "r,r")
8130 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8131 (clobber (reg:CC CC_REGNUM))]
8134 output_asm_insn (\"cmp\\t%2, %3\", operands);
8135 if (which_alternative != 0)
8136 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8137 return \"sub%d4\\t%0, %1, #1\";
8139 [(set_attr "conds" "clob")
8140 (set_attr "length" "8,12")]
8143 (define_insn "*cmp_ite0"
8144 [(set (match_operand 6 "dominant_cc_register" "")
8147 (match_operator 4 "arm_comparison_operator"
8148 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8149 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8150 (match_operator:SI 5 "arm_comparison_operator"
8151 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8152 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8158 static const char * const opcodes[4][2] =
8160 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8161 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8162 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8163 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8164 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8165 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8166 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8167 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8170 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8172 return opcodes[which_alternative][swap];
8174 [(set_attr "conds" "set")
8175 (set_attr "length" "8")]
8178 (define_insn "*cmp_ite1"
8179 [(set (match_operand 6 "dominant_cc_register" "")
8182 (match_operator 4 "arm_comparison_operator"
8183 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8184 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8185 (match_operator:SI 5 "arm_comparison_operator"
8186 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8187 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8193 static const char * const opcodes[4][2] =
8195 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8196 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8197 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8198 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8199 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8200 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8201 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8202 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8205 comparison_dominates_p (GET_CODE (operands[5]),
8206 reverse_condition (GET_CODE (operands[4])));
8208 return opcodes[which_alternative][swap];
8210 [(set_attr "conds" "set")
8211 (set_attr "length" "8")]
8214 (define_insn "*cmp_and"
8215 [(set (match_operand 6 "dominant_cc_register" "")
8218 (match_operator 4 "arm_comparison_operator"
8219 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8220 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8221 (match_operator:SI 5 "arm_comparison_operator"
8222 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8223 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8228 static const char *const opcodes[4][2] =
8230 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8231 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8232 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8233 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8234 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8235 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8236 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8237 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8240 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8242 return opcodes[which_alternative][swap];
8244 [(set_attr "conds" "set")
8245 (set_attr "predicable" "no")
8246 (set_attr "length" "8")]
8249 (define_insn "*cmp_ior"
8250 [(set (match_operand 6 "dominant_cc_register" "")
8253 (match_operator 4 "arm_comparison_operator"
8254 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8255 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8256 (match_operator:SI 5 "arm_comparison_operator"
8257 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8258 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8263 static const char *const opcodes[4][2] =
8265 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8266 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8267 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8268 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8269 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8270 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8271 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8272 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8275 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8277 return opcodes[which_alternative][swap];
8280 [(set_attr "conds" "set")
8281 (set_attr "length" "8")]
8284 (define_insn_and_split "*ior_scc_scc"
8285 [(set (match_operand:SI 0 "s_register_operand" "=r")
8286 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8287 [(match_operand:SI 1 "s_register_operand" "r")
8288 (match_operand:SI 2 "arm_add_operand" "rIL")])
8289 (match_operator:SI 6 "arm_comparison_operator"
8290 [(match_operand:SI 4 "s_register_operand" "r")
8291 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8292 (clobber (reg:CC CC_REGNUM))]
8294 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8297 "TARGET_ARM && reload_completed"
8301 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8302 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8304 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8306 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8309 [(set_attr "conds" "clob")
8310 (set_attr "length" "16")])
8312 ; If the above pattern is followed by a CMP insn, then the compare is
8313 ; redundant, since we can rework the conditional instruction that follows.
8314 (define_insn_and_split "*ior_scc_scc_cmp"
8315 [(set (match_operand 0 "dominant_cc_register" "")
8316 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8317 [(match_operand:SI 1 "s_register_operand" "r")
8318 (match_operand:SI 2 "arm_add_operand" "rIL")])
8319 (match_operator:SI 6 "arm_comparison_operator"
8320 [(match_operand:SI 4 "s_register_operand" "r")
8321 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8323 (set (match_operand:SI 7 "s_register_operand" "=r")
8324 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8325 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8328 "TARGET_ARM && reload_completed"
8332 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8333 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8335 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8337 [(set_attr "conds" "set")
8338 (set_attr "length" "16")])
8340 (define_insn_and_split "*and_scc_scc"
8341 [(set (match_operand:SI 0 "s_register_operand" "=r")
8342 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8343 [(match_operand:SI 1 "s_register_operand" "r")
8344 (match_operand:SI 2 "arm_add_operand" "rIL")])
8345 (match_operator:SI 6 "arm_comparison_operator"
8346 [(match_operand:SI 4 "s_register_operand" "r")
8347 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8348 (clobber (reg:CC CC_REGNUM))]
8350 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8353 "TARGET_ARM && reload_completed
8354 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8359 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8360 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8362 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8364 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8367 [(set_attr "conds" "clob")
8368 (set_attr "length" "16")])
8370 ; If the above pattern is followed by a CMP insn, then the compare is
8371 ; redundant, since we can rework the conditional instruction that follows.
8372 (define_insn_and_split "*and_scc_scc_cmp"
8373 [(set (match_operand 0 "dominant_cc_register" "")
8374 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8375 [(match_operand:SI 1 "s_register_operand" "r")
8376 (match_operand:SI 2 "arm_add_operand" "rIL")])
8377 (match_operator:SI 6 "arm_comparison_operator"
8378 [(match_operand:SI 4 "s_register_operand" "r")
8379 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8381 (set (match_operand:SI 7 "s_register_operand" "=r")
8382 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8383 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8386 "TARGET_ARM && reload_completed"
8390 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8391 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8393 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8395 [(set_attr "conds" "set")
8396 (set_attr "length" "16")])
8398 ;; If there is no dominance in the comparison, then we can still save an
8399 ;; instruction in the AND case, since we can know that the second compare
8400 ;; need only zero the value if false (if true, then the value is already
8402 (define_insn_and_split "*and_scc_scc_nodom"
8403 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8404 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8405 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8406 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8407 (match_operator:SI 6 "arm_comparison_operator"
8408 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8409 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8410 (clobber (reg:CC CC_REGNUM))]
8412 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8415 "TARGET_ARM && reload_completed"
8416 [(parallel [(set (match_dup 0)
8417 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8418 (clobber (reg:CC CC_REGNUM))])
8419 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8421 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8424 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8425 operands[4], operands[5]),
8427 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8429 [(set_attr "conds" "clob")
8430 (set_attr "length" "20")])
8433 [(set (reg:CC_NOOV CC_REGNUM)
8434 (compare:CC_NOOV (ior:SI
8435 (and:SI (match_operand:SI 0 "s_register_operand" "")
8437 (match_operator:SI 1 "comparison_operator"
8438 [(match_operand:SI 2 "s_register_operand" "")
8439 (match_operand:SI 3 "arm_add_operand" "")]))
8441 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8444 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8446 (set (reg:CC_NOOV CC_REGNUM)
8447 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8452 [(set (reg:CC_NOOV CC_REGNUM)
8453 (compare:CC_NOOV (ior:SI
8454 (match_operator:SI 1 "comparison_operator"
8455 [(match_operand:SI 2 "s_register_operand" "")
8456 (match_operand:SI 3 "arm_add_operand" "")])
8457 (and:SI (match_operand:SI 0 "s_register_operand" "")
8460 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8463 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8465 (set (reg:CC_NOOV CC_REGNUM)
8466 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8470 (define_insn "*negscc"
8471 [(set (match_operand:SI 0 "s_register_operand" "=r")
8472 (neg:SI (match_operator 3 "arm_comparison_operator"
8473 [(match_operand:SI 1 "s_register_operand" "r")
8474 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8475 (clobber (reg:CC CC_REGNUM))]
8478 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8479 return \"mov\\t%0, %1, asr #31\";
8481 if (GET_CODE (operands[3]) == NE)
8482 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8484 if (GET_CODE (operands[3]) == GT)
8485 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8487 output_asm_insn (\"cmp\\t%1, %2\", operands);
8488 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8489 return \"mvn%d3\\t%0, #0\";
8491 [(set_attr "conds" "clob")
8492 (set_attr "length" "12")]
8495 (define_insn "movcond"
8496 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8498 (match_operator 5 "arm_comparison_operator"
8499 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8500 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8501 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8502 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8503 (clobber (reg:CC CC_REGNUM))]
8506 if (GET_CODE (operands[5]) == LT
8507 && (operands[4] == const0_rtx))
8509 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8511 if (operands[2] == const0_rtx)
8512 return \"and\\t%0, %1, %3, asr #31\";
8513 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8515 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8517 if (operands[1] == const0_rtx)
8518 return \"bic\\t%0, %2, %3, asr #31\";
8519 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8521 /* The only case that falls through to here is when both ops 1 & 2
8525 if (GET_CODE (operands[5]) == GE
8526 && (operands[4] == const0_rtx))
8528 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8530 if (operands[2] == const0_rtx)
8531 return \"bic\\t%0, %1, %3, asr #31\";
8532 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8534 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8536 if (operands[1] == const0_rtx)
8537 return \"and\\t%0, %2, %3, asr #31\";
8538 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8540 /* The only case that falls through to here is when both ops 1 & 2
8543 if (GET_CODE (operands[4]) == CONST_INT
8544 && !const_ok_for_arm (INTVAL (operands[4])))
8545 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8547 output_asm_insn (\"cmp\\t%3, %4\", operands);
8548 if (which_alternative != 0)
8549 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8550 if (which_alternative != 1)
8551 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8554 [(set_attr "conds" "clob")
8555 (set_attr "length" "8,8,12")]
8558 (define_insn "*ifcompare_plus_move"
8559 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8560 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8561 [(match_operand:SI 4 "s_register_operand" "r,r")
8562 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8564 (match_operand:SI 2 "s_register_operand" "r,r")
8565 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8566 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8567 (clobber (reg:CC CC_REGNUM))]
8570 [(set_attr "conds" "clob")
8571 (set_attr "length" "8,12")]
8574 (define_insn "*if_plus_move"
8575 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8577 (match_operator 4 "arm_comparison_operator"
8578 [(match_operand 5 "cc_register" "") (const_int 0)])
8580 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8581 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8582 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8586 sub%d4\\t%0, %2, #%n3
8587 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8588 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8589 [(set_attr "conds" "use")
8590 (set_attr "length" "4,4,8,8")
8591 (set_attr "type" "*,*,*,*")]
8594 (define_insn "*ifcompare_move_plus"
8595 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8596 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8597 [(match_operand:SI 4 "s_register_operand" "r,r")
8598 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8599 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8601 (match_operand:SI 2 "s_register_operand" "r,r")
8602 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8603 (clobber (reg:CC CC_REGNUM))]
8606 [(set_attr "conds" "clob")
8607 (set_attr "length" "8,12")]
8610 (define_insn "*if_move_plus"
8611 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8613 (match_operator 4 "arm_comparison_operator"
8614 [(match_operand 5 "cc_register" "") (const_int 0)])
8615 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8617 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8618 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8622 sub%D4\\t%0, %2, #%n3
8623 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8624 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8625 [(set_attr "conds" "use")
8626 (set_attr "length" "4,4,8,8")
8627 (set_attr "type" "*,*,*,*")]
8630 (define_insn "*ifcompare_arith_arith"
8631 [(set (match_operand:SI 0 "s_register_operand" "=r")
8632 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8633 [(match_operand:SI 5 "s_register_operand" "r")
8634 (match_operand:SI 6 "arm_add_operand" "rIL")])
8635 (match_operator:SI 8 "shiftable_operator"
8636 [(match_operand:SI 1 "s_register_operand" "r")
8637 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8638 (match_operator:SI 7 "shiftable_operator"
8639 [(match_operand:SI 3 "s_register_operand" "r")
8640 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8641 (clobber (reg:CC CC_REGNUM))]
8644 [(set_attr "conds" "clob")
8645 (set_attr "length" "12")]
8648 (define_insn "*if_arith_arith"
8649 [(set (match_operand:SI 0 "s_register_operand" "=r")
8650 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8651 [(match_operand 8 "cc_register" "") (const_int 0)])
8652 (match_operator:SI 6 "shiftable_operator"
8653 [(match_operand:SI 1 "s_register_operand" "r")
8654 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8655 (match_operator:SI 7 "shiftable_operator"
8656 [(match_operand:SI 3 "s_register_operand" "r")
8657 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8659 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8660 [(set_attr "conds" "use")
8661 (set_attr "length" "8")]
8664 (define_insn "*ifcompare_arith_move"
8665 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8666 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8667 [(match_operand:SI 2 "s_register_operand" "r,r")
8668 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8669 (match_operator:SI 7 "shiftable_operator"
8670 [(match_operand:SI 4 "s_register_operand" "r,r")
8671 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8672 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8673 (clobber (reg:CC CC_REGNUM))]
8676 /* If we have an operation where (op x 0) is the identity operation and
8677 the conditional operator is LT or GE and we are comparing against zero and
8678 everything is in registers then we can do this in two instructions. */
8679 if (operands[3] == const0_rtx
8680 && GET_CODE (operands[7]) != AND
8681 && GET_CODE (operands[5]) == REG
8682 && GET_CODE (operands[1]) == REG
8683 && REGNO (operands[1]) == REGNO (operands[4])
8684 && REGNO (operands[4]) != REGNO (operands[0]))
8686 if (GET_CODE (operands[6]) == LT)
8687 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8688 else if (GET_CODE (operands[6]) == GE)
8689 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8691 if (GET_CODE (operands[3]) == CONST_INT
8692 && !const_ok_for_arm (INTVAL (operands[3])))
8693 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8695 output_asm_insn (\"cmp\\t%2, %3\", operands);
8696 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8697 if (which_alternative != 0)
8698 return \"mov%D6\\t%0, %1\";
8701 [(set_attr "conds" "clob")
8702 (set_attr "length" "8,12")]
8705 (define_insn "*if_arith_move"
8706 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8707 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8708 [(match_operand 6 "cc_register" "") (const_int 0)])
8709 (match_operator:SI 5 "shiftable_operator"
8710 [(match_operand:SI 2 "s_register_operand" "r,r")
8711 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8712 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8716 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8717 [(set_attr "conds" "use")
8718 (set_attr "length" "4,8")
8719 (set_attr "type" "*,*")]
8722 (define_insn "*ifcompare_move_arith"
8723 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8724 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8725 [(match_operand:SI 4 "s_register_operand" "r,r")
8726 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8727 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8728 (match_operator:SI 7 "shiftable_operator"
8729 [(match_operand:SI 2 "s_register_operand" "r,r")
8730 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8731 (clobber (reg:CC CC_REGNUM))]
8734 /* If we have an operation where (op x 0) is the identity operation and
8735 the conditional operator is LT or GE and we are comparing against zero and
8736 everything is in registers then we can do this in two instructions */
8737 if (operands[5] == const0_rtx
8738 && GET_CODE (operands[7]) != AND
8739 && GET_CODE (operands[3]) == REG
8740 && GET_CODE (operands[1]) == REG
8741 && REGNO (operands[1]) == REGNO (operands[2])
8742 && REGNO (operands[2]) != REGNO (operands[0]))
8744 if (GET_CODE (operands[6]) == GE)
8745 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8746 else if (GET_CODE (operands[6]) == LT)
8747 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8750 if (GET_CODE (operands[5]) == CONST_INT
8751 && !const_ok_for_arm (INTVAL (operands[5])))
8752 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8754 output_asm_insn (\"cmp\\t%4, %5\", operands);
8756 if (which_alternative != 0)
8757 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8758 return \"%I7%D6\\t%0, %2, %3\";
8760 [(set_attr "conds" "clob")
8761 (set_attr "length" "8,12")]
8764 (define_insn "*if_move_arith"
8765 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8767 (match_operator 4 "arm_comparison_operator"
8768 [(match_operand 6 "cc_register" "") (const_int 0)])
8769 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8770 (match_operator:SI 5 "shiftable_operator"
8771 [(match_operand:SI 2 "s_register_operand" "r,r")
8772 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8776 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8777 [(set_attr "conds" "use")
8778 (set_attr "length" "4,8")
8779 (set_attr "type" "*,*")]
8782 (define_insn "*ifcompare_move_not"
8783 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8785 (match_operator 5 "arm_comparison_operator"
8786 [(match_operand:SI 3 "s_register_operand" "r,r")
8787 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8788 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8790 (match_operand:SI 2 "s_register_operand" "r,r"))))
8791 (clobber (reg:CC CC_REGNUM))]
8794 [(set_attr "conds" "clob")
8795 (set_attr "length" "8,12")]
8798 (define_insn "*if_move_not"
8799 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8801 (match_operator 4 "arm_comparison_operator"
8802 [(match_operand 3 "cc_register" "") (const_int 0)])
8803 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8804 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
8808 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
8809 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8810 [(set_attr "conds" "use")
8811 (set_attr "length" "4,8,8")]
8814 (define_insn "*ifcompare_not_move"
8815 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8817 (match_operator 5 "arm_comparison_operator"
8818 [(match_operand:SI 3 "s_register_operand" "r,r")
8819 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8821 (match_operand:SI 2 "s_register_operand" "r,r"))
8822 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8823 (clobber (reg:CC CC_REGNUM))]
8826 [(set_attr "conds" "clob")
8827 (set_attr "length" "8,12")]
8830 (define_insn "*if_not_move"
8831 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8833 (match_operator 4 "arm_comparison_operator"
8834 [(match_operand 3 "cc_register" "") (const_int 0)])
8835 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
8836 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8840 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
8841 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8842 [(set_attr "conds" "use")
8843 (set_attr "length" "4,8,8")]
8846 (define_insn "*ifcompare_shift_move"
8847 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8849 (match_operator 6 "arm_comparison_operator"
8850 [(match_operand:SI 4 "s_register_operand" "r,r")
8851 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8852 (match_operator:SI 7 "shift_operator"
8853 [(match_operand:SI 2 "s_register_operand" "r,r")
8854 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
8855 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8856 (clobber (reg:CC CC_REGNUM))]
8859 [(set_attr "conds" "clob")
8860 (set_attr "length" "8,12")]
8863 (define_insn "*if_shift_move"
8864 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8866 (match_operator 5 "arm_comparison_operator"
8867 [(match_operand 6 "cc_register" "") (const_int 0)])
8868 (match_operator:SI 4 "shift_operator"
8869 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8870 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
8871 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8875 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
8876 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8877 [(set_attr "conds" "use")
8878 (set_attr "shift" "2")
8879 (set_attr "length" "4,8,8")
8880 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8881 (const_string "alu_shift")
8882 (const_string "alu_shift_reg")))]
8885 (define_insn "*ifcompare_move_shift"
8886 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8888 (match_operator 6 "arm_comparison_operator"
8889 [(match_operand:SI 4 "s_register_operand" "r,r")
8890 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8891 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8892 (match_operator:SI 7 "shift_operator"
8893 [(match_operand:SI 2 "s_register_operand" "r,r")
8894 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
8895 (clobber (reg:CC CC_REGNUM))]
8898 [(set_attr "conds" "clob")
8899 (set_attr "length" "8,12")]
8902 (define_insn "*if_move_shift"
8903 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8905 (match_operator 5 "arm_comparison_operator"
8906 [(match_operand 6 "cc_register" "") (const_int 0)])
8907 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8908 (match_operator:SI 4 "shift_operator"
8909 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8910 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
8914 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
8915 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8916 [(set_attr "conds" "use")
8917 (set_attr "shift" "2")
8918 (set_attr "length" "4,8,8")
8919 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8920 (const_string "alu_shift")
8921 (const_string "alu_shift_reg")))]
8924 (define_insn "*ifcompare_shift_shift"
8925 [(set (match_operand:SI 0 "s_register_operand" "=r")
8927 (match_operator 7 "arm_comparison_operator"
8928 [(match_operand:SI 5 "s_register_operand" "r")
8929 (match_operand:SI 6 "arm_add_operand" "rIL")])
8930 (match_operator:SI 8 "shift_operator"
8931 [(match_operand:SI 1 "s_register_operand" "r")
8932 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8933 (match_operator:SI 9 "shift_operator"
8934 [(match_operand:SI 3 "s_register_operand" "r")
8935 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
8936 (clobber (reg:CC CC_REGNUM))]
8939 [(set_attr "conds" "clob")
8940 (set_attr "length" "12")]
8943 (define_insn "*if_shift_shift"
8944 [(set (match_operand:SI 0 "s_register_operand" "=r")
8946 (match_operator 5 "arm_comparison_operator"
8947 [(match_operand 8 "cc_register" "") (const_int 0)])
8948 (match_operator:SI 6 "shift_operator"
8949 [(match_operand:SI 1 "s_register_operand" "r")
8950 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8951 (match_operator:SI 7 "shift_operator"
8952 [(match_operand:SI 3 "s_register_operand" "r")
8953 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
8955 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8956 [(set_attr "conds" "use")
8957 (set_attr "shift" "1")
8958 (set_attr "length" "8")
8959 (set (attr "type") (if_then_else
8960 (and (match_operand 2 "const_int_operand" "")
8961 (match_operand 4 "const_int_operand" ""))
8962 (const_string "alu_shift")
8963 (const_string "alu_shift_reg")))]
8966 (define_insn "*ifcompare_not_arith"
8967 [(set (match_operand:SI 0 "s_register_operand" "=r")
8969 (match_operator 6 "arm_comparison_operator"
8970 [(match_operand:SI 4 "s_register_operand" "r")
8971 (match_operand:SI 5 "arm_add_operand" "rIL")])
8972 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8973 (match_operator:SI 7 "shiftable_operator"
8974 [(match_operand:SI 2 "s_register_operand" "r")
8975 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
8976 (clobber (reg:CC CC_REGNUM))]
8979 [(set_attr "conds" "clob")
8980 (set_attr "length" "12")]
8983 (define_insn "*if_not_arith"
8984 [(set (match_operand:SI 0 "s_register_operand" "=r")
8986 (match_operator 5 "arm_comparison_operator"
8987 [(match_operand 4 "cc_register" "") (const_int 0)])
8988 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8989 (match_operator:SI 6 "shiftable_operator"
8990 [(match_operand:SI 2 "s_register_operand" "r")
8991 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
8993 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8994 [(set_attr "conds" "use")
8995 (set_attr "length" "8")]
8998 (define_insn "*ifcompare_arith_not"
8999 [(set (match_operand:SI 0 "s_register_operand" "=r")
9001 (match_operator 6 "arm_comparison_operator"
9002 [(match_operand:SI 4 "s_register_operand" "r")
9003 (match_operand:SI 5 "arm_add_operand" "rIL")])
9004 (match_operator:SI 7 "shiftable_operator"
9005 [(match_operand:SI 2 "s_register_operand" "r")
9006 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9007 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9008 (clobber (reg:CC CC_REGNUM))]
9011 [(set_attr "conds" "clob")
9012 (set_attr "length" "12")]
9015 (define_insn "*if_arith_not"
9016 [(set (match_operand:SI 0 "s_register_operand" "=r")
9018 (match_operator 5 "arm_comparison_operator"
9019 [(match_operand 4 "cc_register" "") (const_int 0)])
9020 (match_operator:SI 6 "shiftable_operator"
9021 [(match_operand:SI 2 "s_register_operand" "r")
9022 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9023 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9025 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9026 [(set_attr "conds" "use")
9027 (set_attr "length" "8")]
9030 (define_insn "*ifcompare_neg_move"
9031 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9033 (match_operator 5 "arm_comparison_operator"
9034 [(match_operand:SI 3 "s_register_operand" "r,r")
9035 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9036 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9037 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9038 (clobber (reg:CC CC_REGNUM))]
9041 [(set_attr "conds" "clob")
9042 (set_attr "length" "8,12")]
9045 (define_insn "*if_neg_move"
9046 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9048 (match_operator 4 "arm_comparison_operator"
9049 [(match_operand 3 "cc_register" "") (const_int 0)])
9050 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9051 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9055 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9056 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9057 [(set_attr "conds" "use")
9058 (set_attr "length" "4,8,8")]
9061 (define_insn "*ifcompare_move_neg"
9062 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9064 (match_operator 5 "arm_comparison_operator"
9065 [(match_operand:SI 3 "s_register_operand" "r,r")
9066 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9067 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9068 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9069 (clobber (reg:CC CC_REGNUM))]
9072 [(set_attr "conds" "clob")
9073 (set_attr "length" "8,12")]
9076 (define_insn "*if_move_neg"
9077 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9079 (match_operator 4 "arm_comparison_operator"
9080 [(match_operand 3 "cc_register" "") (const_int 0)])
9081 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9082 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9086 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9087 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9088 [(set_attr "conds" "use")
9089 (set_attr "length" "4,8,8")]
9092 (define_insn "*arith_adjacentmem"
9093 [(set (match_operand:SI 0 "s_register_operand" "=r")
9094 (match_operator:SI 1 "shiftable_operator"
9095 [(match_operand:SI 2 "memory_operand" "m")
9096 (match_operand:SI 3 "memory_operand" "m")]))
9097 (clobber (match_scratch:SI 4 "=r"))]
9098 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9103 int val1 = 0, val2 = 0;
9105 if (REGNO (operands[0]) > REGNO (operands[4]))
9107 ldm[1] = operands[4];
9108 ldm[2] = operands[0];
9112 ldm[1] = operands[0];
9113 ldm[2] = operands[4];
9115 if (GET_CODE (XEXP (operands[2], 0)) != REG)
9116 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
9117 if (GET_CODE (XEXP (operands[3], 0)) != REG)
9118 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9119 arith[0] = operands[0];
9120 arith[3] = operands[1];
9134 ldm[0] = ops[0] = operands[4];
9135 ops[1] = XEXP (XEXP (operands[2], 0), 0);
9136 ops[2] = XEXP (XEXP (operands[2], 0), 1);
9137 output_add_immediate (ops);
9139 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9141 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9145 ldm[0] = XEXP (operands[3], 0);
9147 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9149 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9153 ldm[0] = XEXP (operands[2], 0);
9155 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9157 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9159 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9162 [(set_attr "length" "12")
9163 (set_attr "predicable" "yes")
9164 (set_attr "type" "load1")]
9167 ;; the arm can support extended pre-inc instructions
9169 ;; In all these cases, we use operands 0 and 1 for the register being
9170 ;; incremented because those are the operands that local-alloc will
9171 ;; tie and these are the pair most likely to be tieable (and the ones
9172 ;; that will benefit the most).
9174 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9175 ;; elimination will cause too many headaches.
9177 (define_insn "*strqi_preinc"
9178 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9179 (match_operand:SI 2 "index_operand" "rJ")))
9180 (match_operand:QI 3 "s_register_operand" "r"))
9181 (set (match_operand:SI 0 "s_register_operand" "=r")
9182 (plus:SI (match_dup 1) (match_dup 2)))]
9184 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9185 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9186 && (GET_CODE (operands[2]) != REG
9187 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9188 "str%?b\\t%3, [%0, %2]!"
9189 [(set_attr "type" "store1")
9190 (set_attr "predicable" "yes")]
9193 (define_insn "*strqi_predec"
9194 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9195 (match_operand:SI 2 "s_register_operand" "r")))
9196 (match_operand:QI 3 "s_register_operand" "r"))
9197 (set (match_operand:SI 0 "s_register_operand" "=r")
9198 (minus:SI (match_dup 1) (match_dup 2)))]
9200 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9201 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9202 && (GET_CODE (operands[2]) != REG
9203 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9204 "str%?b\\t%3, [%0, -%2]!"
9205 [(set_attr "type" "store1")
9206 (set_attr "predicable" "yes")]
9209 (define_insn "*loadqi_preinc"
9210 [(set (match_operand:QI 3 "s_register_operand" "=r")
9211 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9212 (match_operand:SI 2 "index_operand" "rJ"))))
9213 (set (match_operand:SI 0 "s_register_operand" "=r")
9214 (plus:SI (match_dup 1) (match_dup 2)))]
9216 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9217 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9218 && (GET_CODE (operands[2]) != REG
9219 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9220 "ldr%?b\\t%3, [%0, %2]!"
9221 [(set_attr "type" "load_byte")
9222 (set_attr "predicable" "yes")]
9225 (define_insn "*loadqi_predec"
9226 [(set (match_operand:QI 3 "s_register_operand" "=r")
9227 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9228 (match_operand:SI 2 "s_register_operand" "r"))))
9229 (set (match_operand:SI 0 "s_register_operand" "=r")
9230 (minus:SI (match_dup 1) (match_dup 2)))]
9232 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9233 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9234 && (GET_CODE (operands[2]) != REG
9235 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9236 "ldr%?b\\t%3, [%0, -%2]!"
9237 [(set_attr "type" "load_byte")
9238 (set_attr "predicable" "yes")]
9241 (define_insn "*loadqisi_preinc"
9242 [(set (match_operand:SI 3 "s_register_operand" "=r")
9244 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9245 (match_operand:SI 2 "index_operand" "rJ")))))
9246 (set (match_operand:SI 0 "s_register_operand" "=r")
9247 (plus:SI (match_dup 1) (match_dup 2)))]
9249 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9250 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9251 && (GET_CODE (operands[2]) != REG
9252 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9253 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9254 [(set_attr "type" "load_byte")
9255 (set_attr "predicable" "yes")]
9258 (define_insn "*loadqisi_predec"
9259 [(set (match_operand:SI 3 "s_register_operand" "=r")
9261 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9262 (match_operand:SI 2 "s_register_operand" "r")))))
9263 (set (match_operand:SI 0 "s_register_operand" "=r")
9264 (minus:SI (match_dup 1) (match_dup 2)))]
9266 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9267 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9268 && (GET_CODE (operands[2]) != REG
9269 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9270 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9271 [(set_attr "type" "load_byte")
9272 (set_attr "predicable" "yes")]
9275 (define_insn "*strsi_preinc"
9276 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9277 (match_operand:SI 2 "index_operand" "rJ")))
9278 (match_operand:SI 3 "s_register_operand" "r"))
9279 (set (match_operand:SI 0 "s_register_operand" "=r")
9280 (plus:SI (match_dup 1) (match_dup 2)))]
9282 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9283 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9284 && (GET_CODE (operands[2]) != REG
9285 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9286 "str%?\\t%3, [%0, %2]!"
9287 [(set_attr "type" "store1")
9288 (set_attr "predicable" "yes")]
9291 (define_insn "*strsi_predec"
9292 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9293 (match_operand:SI 2 "s_register_operand" "r")))
9294 (match_operand:SI 3 "s_register_operand" "r"))
9295 (set (match_operand:SI 0 "s_register_operand" "=r")
9296 (minus:SI (match_dup 1) (match_dup 2)))]
9298 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9299 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9300 && (GET_CODE (operands[2]) != REG
9301 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9302 "str%?\\t%3, [%0, -%2]!"
9303 [(set_attr "type" "store1")
9304 (set_attr "predicable" "yes")]
9307 (define_insn "*loadsi_preinc"
9308 [(set (match_operand:SI 3 "s_register_operand" "=r")
9309 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9310 (match_operand:SI 2 "index_operand" "rJ"))))
9311 (set (match_operand:SI 0 "s_register_operand" "=r")
9312 (plus:SI (match_dup 1) (match_dup 2)))]
9314 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9315 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9316 && (GET_CODE (operands[2]) != REG
9317 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9318 "ldr%?\\t%3, [%0, %2]!"
9319 [(set_attr "type" "load1")
9320 (set_attr "predicable" "yes")]
9323 (define_insn "*loadsi_predec"
9324 [(set (match_operand:SI 3 "s_register_operand" "=r")
9325 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9326 (match_operand:SI 2 "s_register_operand" "r"))))
9327 (set (match_operand:SI 0 "s_register_operand" "=r")
9328 (minus:SI (match_dup 1) (match_dup 2)))]
9330 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9331 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9332 && (GET_CODE (operands[2]) != REG
9333 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9334 "ldr%?\\t%3, [%0, -%2]!"
9335 [(set_attr "type" "load1")
9336 (set_attr "predicable" "yes")]
9339 (define_insn "*strqi_shiftpreinc"
9340 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9341 [(match_operand:SI 3 "s_register_operand" "r")
9342 (match_operand:SI 4 "const_shift_operand" "n")])
9343 (match_operand:SI 1 "s_register_operand" "0")))
9344 (match_operand:QI 5 "s_register_operand" "r"))
9345 (set (match_operand:SI 0 "s_register_operand" "=r")
9346 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9349 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9350 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9351 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9352 "str%?b\\t%5, [%0, %3%S2]!"
9353 [(set_attr "type" "store1")
9354 (set_attr "predicable" "yes")]
9357 (define_insn "*strqi_shiftpredec"
9358 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9359 (match_operator:SI 2 "shift_operator"
9360 [(match_operand:SI 3 "s_register_operand" "r")
9361 (match_operand:SI 4 "const_shift_operand" "n")])))
9362 (match_operand:QI 5 "s_register_operand" "r"))
9363 (set (match_operand:SI 0 "s_register_operand" "=r")
9364 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9367 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9368 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9369 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9370 "str%?b\\t%5, [%0, -%3%S2]!"
9371 [(set_attr "type" "store1")
9372 (set_attr "predicable" "yes")]
9375 (define_insn "*loadqi_shiftpreinc"
9376 [(set (match_operand:QI 5 "s_register_operand" "=r")
9377 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9378 [(match_operand:SI 3 "s_register_operand" "r")
9379 (match_operand:SI 4 "const_shift_operand" "n")])
9380 (match_operand:SI 1 "s_register_operand" "0"))))
9381 (set (match_operand:SI 0 "s_register_operand" "=r")
9382 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9385 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9386 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9387 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9388 "ldr%?b\\t%5, [%0, %3%S2]!"
9389 [(set_attr "type" "load_byte")
9390 (set_attr "predicable" "yes")]
9393 (define_insn "*loadqi_shiftpredec"
9394 [(set (match_operand:QI 5 "s_register_operand" "=r")
9395 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9396 (match_operator:SI 2 "shift_operator"
9397 [(match_operand:SI 3 "s_register_operand" "r")
9398 (match_operand:SI 4 "const_shift_operand" "n")]))))
9399 (set (match_operand:SI 0 "s_register_operand" "=r")
9400 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9403 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9404 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9405 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9406 "ldr%?b\\t%5, [%0, -%3%S2]!"
9407 [(set_attr "type" "load_byte")
9408 (set_attr "predicable" "yes")]
9411 (define_insn "*strsi_shiftpreinc"
9412 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9413 [(match_operand:SI 3 "s_register_operand" "r")
9414 (match_operand:SI 4 "const_shift_operand" "n")])
9415 (match_operand:SI 1 "s_register_operand" "0")))
9416 (match_operand:SI 5 "s_register_operand" "r"))
9417 (set (match_operand:SI 0 "s_register_operand" "=r")
9418 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9421 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9422 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9423 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9424 "str%?\\t%5, [%0, %3%S2]!"
9425 [(set_attr "type" "store1")
9426 (set_attr "predicable" "yes")]
9429 (define_insn "*strsi_shiftpredec"
9430 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9431 (match_operator:SI 2 "shift_operator"
9432 [(match_operand:SI 3 "s_register_operand" "r")
9433 (match_operand:SI 4 "const_shift_operand" "n")])))
9434 (match_operand:SI 5 "s_register_operand" "r"))
9435 (set (match_operand:SI 0 "s_register_operand" "=r")
9436 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9439 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9440 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9441 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9442 "str%?\\t%5, [%0, -%3%S2]!"
9443 [(set_attr "type" "store1")
9444 (set_attr "predicable" "yes")]
9447 (define_insn "*loadsi_shiftpreinc"
9448 [(set (match_operand:SI 5 "s_register_operand" "=r")
9449 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9450 [(match_operand:SI 3 "s_register_operand" "r")
9451 (match_operand:SI 4 "const_shift_operand" "n")])
9452 (match_operand:SI 1 "s_register_operand" "0"))))
9453 (set (match_operand:SI 0 "s_register_operand" "=r")
9454 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9457 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9458 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9459 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9460 "ldr%?\\t%5, [%0, %3%S2]!"
9461 [(set_attr "type" "load1")
9462 (set_attr "predicable" "yes")]
9465 (define_insn "*loadsi_shiftpredec"
9466 [(set (match_operand:SI 5 "s_register_operand" "=r")
9467 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9468 (match_operator:SI 2 "shift_operator"
9469 [(match_operand:SI 3 "s_register_operand" "r")
9470 (match_operand:SI 4 "const_shift_operand" "n")]))))
9471 (set (match_operand:SI 0 "s_register_operand" "=r")
9472 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9475 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9476 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9477 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9478 "ldr%?\\t%5, [%0, -%3%S2]!"
9479 [(set_attr "type" "load1")
9480 (set_attr "predicable" "yes")])
9482 ; It can also support extended post-inc expressions, but combine doesn't
9484 ; It doesn't seem worth adding peepholes for anything but the most common
9485 ; cases since, unlike combine, the increment must immediately follow the load
9486 ; for this pattern to match.
9487 ; We must watch to see that the source/destination register isn't also the
9488 ; same as the base address register, and that if the index is a register,
9489 ; that it is not the same as the base address register. In such cases the
9490 ; instruction that we would generate would have UNPREDICTABLE behavior so
9494 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9495 (match_operand:QI 2 "s_register_operand" "r"))
9497 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9499 && (REGNO (operands[2]) != REGNO (operands[0]))
9500 && (GET_CODE (operands[1]) != REG
9501 || (REGNO (operands[1]) != REGNO (operands[0])))"
9502 "str%?b\\t%2, [%0], %1"
9506 [(set (match_operand:QI 0 "s_register_operand" "=r")
9507 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9509 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9511 && REGNO (operands[0]) != REGNO(operands[1])
9512 && (GET_CODE (operands[2]) != REG
9513 || REGNO(operands[0]) != REGNO (operands[2]))"
9514 "ldr%?b\\t%0, [%1], %2"
9518 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9519 (match_operand:SI 2 "s_register_operand" "r"))
9521 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9523 && (REGNO (operands[2]) != REGNO (operands[0]))
9524 && (GET_CODE (operands[1]) != REG
9525 || (REGNO (operands[1]) != REGNO (operands[0])))"
9526 "str%?\\t%2, [%0], %1"
9530 [(set (match_operand:SI 0 "s_register_operand" "=r")
9531 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9533 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9535 && REGNO (operands[0]) != REGNO(operands[1])
9536 && (GET_CODE (operands[2]) != REG
9537 || REGNO(operands[0]) != REGNO (operands[2]))"
9538 "ldr%?\\t%0, [%1], %2"
9542 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9543 (match_operand:SI 1 "index_operand" "rJ")))
9544 (match_operand:QI 2 "s_register_operand" "r"))
9545 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9547 && (REGNO (operands[2]) != REGNO (operands[0]))
9548 && (GET_CODE (operands[1]) != REG
9549 || (REGNO (operands[1]) != REGNO (operands[0])))"
9550 "str%?b\\t%2, [%0, %1]!"
9554 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9555 [(match_operand:SI 0 "s_register_operand" "r")
9556 (match_operand:SI 1 "const_int_operand" "n")])
9557 (match_operand:SI 2 "s_register_operand" "+r")))
9558 (match_operand:QI 3 "s_register_operand" "r"))
9559 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9562 && (REGNO (operands[3]) != REGNO (operands[2]))
9563 && (REGNO (operands[0]) != REGNO (operands[2]))"
9564 "str%?b\\t%3, [%2, %0%S4]!"
9567 ; This pattern is never tried by combine, so do it as a peephole
9570 [(set (match_operand:SI 0 "arm_general_register_operand" "")
9571 (match_operand:SI 1 "arm_general_register_operand" ""))
9572 (set (reg:CC CC_REGNUM)
9573 (compare:CC (match_dup 1) (const_int 0)))]
9575 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9576 (set (match_dup 0) (match_dup 1))])]
9580 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9581 ; reversed, check that the memory references aren't volatile.
9584 [(set (match_operand:SI 0 "s_register_operand" "=r")
9585 (match_operand:SI 4 "memory_operand" "m"))
9586 (set (match_operand:SI 1 "s_register_operand" "=r")
9587 (match_operand:SI 5 "memory_operand" "m"))
9588 (set (match_operand:SI 2 "s_register_operand" "=r")
9589 (match_operand:SI 6 "memory_operand" "m"))
9590 (set (match_operand:SI 3 "s_register_operand" "=r")
9591 (match_operand:SI 7 "memory_operand" "m"))]
9592 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9594 return emit_ldm_seq (operands, 4);
9599 [(set (match_operand:SI 0 "s_register_operand" "=r")
9600 (match_operand:SI 3 "memory_operand" "m"))
9601 (set (match_operand:SI 1 "s_register_operand" "=r")
9602 (match_operand:SI 4 "memory_operand" "m"))
9603 (set (match_operand:SI 2 "s_register_operand" "=r")
9604 (match_operand:SI 5 "memory_operand" "m"))]
9605 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9607 return emit_ldm_seq (operands, 3);
9612 [(set (match_operand:SI 0 "s_register_operand" "=r")
9613 (match_operand:SI 2 "memory_operand" "m"))
9614 (set (match_operand:SI 1 "s_register_operand" "=r")
9615 (match_operand:SI 3 "memory_operand" "m"))]
9616 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9618 return emit_ldm_seq (operands, 2);
9623 [(set (match_operand:SI 4 "memory_operand" "=m")
9624 (match_operand:SI 0 "s_register_operand" "r"))
9625 (set (match_operand:SI 5 "memory_operand" "=m")
9626 (match_operand:SI 1 "s_register_operand" "r"))
9627 (set (match_operand:SI 6 "memory_operand" "=m")
9628 (match_operand:SI 2 "s_register_operand" "r"))
9629 (set (match_operand:SI 7 "memory_operand" "=m")
9630 (match_operand:SI 3 "s_register_operand" "r"))]
9631 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9633 return emit_stm_seq (operands, 4);
9638 [(set (match_operand:SI 3 "memory_operand" "=m")
9639 (match_operand:SI 0 "s_register_operand" "r"))
9640 (set (match_operand:SI 4 "memory_operand" "=m")
9641 (match_operand:SI 1 "s_register_operand" "r"))
9642 (set (match_operand:SI 5 "memory_operand" "=m")
9643 (match_operand:SI 2 "s_register_operand" "r"))]
9644 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9646 return emit_stm_seq (operands, 3);
9651 [(set (match_operand:SI 2 "memory_operand" "=m")
9652 (match_operand:SI 0 "s_register_operand" "r"))
9653 (set (match_operand:SI 3 "memory_operand" "=m")
9654 (match_operand:SI 1 "s_register_operand" "r"))]
9655 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9657 return emit_stm_seq (operands, 2);
9662 [(set (match_operand:SI 0 "s_register_operand" "")
9663 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9665 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9666 [(match_operand:SI 3 "s_register_operand" "")
9667 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9668 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9670 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9671 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9676 ;; This split can be used because CC_Z mode implies that the following
9677 ;; branch will be an equality, or an unsigned inequality, so the sign
9678 ;; extension is not needed.
9681 [(set (reg:CC_Z CC_REGNUM)
9683 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9685 (match_operand 1 "const_int_operand" "")))
9686 (clobber (match_scratch:SI 2 ""))]
9688 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9689 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9690 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9691 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9693 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9697 (define_expand "prologue"
9698 [(clobber (const_int 0))]
9701 arm_expand_prologue ();
9703 thumb_expand_prologue ();
9708 (define_expand "epilogue"
9709 [(clobber (const_int 0))]
9712 if (current_function_calls_eh_return)
9713 emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
9715 thumb_expand_epilogue ();
9716 else if (USE_RETURN_INSN (FALSE))
9718 emit_jump_insn (gen_return ());
9721 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9723 gen_rtx_RETURN (VOIDmode)),
9729 ;; Note - although unspec_volatile's USE all hard registers,
9730 ;; USEs are ignored after relaod has completed. Thus we need
9731 ;; to add an unspec of the link register to ensure that flow
9732 ;; does not think that it is unused by the sibcall branch that
9733 ;; will replace the standard function epilogue.
9734 (define_insn "sibcall_epilogue"
9735 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9736 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9739 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9740 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9741 return arm_output_epilogue (next_nonnote_insn (insn));
9743 ;; Length is absolute worst case
9744 [(set_attr "length" "44")
9745 (set_attr "type" "block")
9746 ;; We don't clobber the conditions, but the potential length of this
9747 ;; operation is sufficient to make conditionalizing the sequence
9748 ;; unlikely to be profitable.
9749 (set_attr "conds" "clob")]
9752 (define_insn "*epilogue_insns"
9753 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9757 return arm_output_epilogue (NULL);
9758 else /* TARGET_THUMB */
9759 return thumb_unexpanded_epilogue ();
9761 ; Length is absolute worst case
9762 [(set_attr "length" "44")
9763 (set_attr "type" "block")
9764 ;; We don't clobber the conditions, but the potential length of this
9765 ;; operation is sufficient to make conditionalizing the sequence
9766 ;; unlikely to be profitable.
9767 (set_attr "conds" "clob")]
9770 (define_expand "eh_epilogue"
9771 [(use (match_operand:SI 0 "register_operand" ""))
9772 (use (match_operand:SI 1 "register_operand" ""))
9773 (use (match_operand:SI 2 "register_operand" ""))]
9777 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9778 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9780 rtx ra = gen_rtx_REG (Pmode, 2);
9782 emit_move_insn (ra, operands[2]);
9785 /* This is a hack -- we may have crystalized the function type too
9787 cfun->machine->func_type = 0;
9791 ;; This split is only used during output to reduce the number of patterns
9792 ;; that need assembler instructions adding to them. We allowed the setting
9793 ;; of the conditions to be implicit during rtl generation so that
9794 ;; the conditional compare patterns would work. However this conflicts to
9795 ;; some extent with the conditional data operations, so we have to split them
9799 [(set (match_operand:SI 0 "s_register_operand" "")
9800 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9801 [(match_operand 2 "" "") (match_operand 3 "" "")])
9803 (match_operand 4 "" "")))
9804 (clobber (reg:CC CC_REGNUM))]
9805 "TARGET_ARM && reload_completed"
9806 [(set (match_dup 5) (match_dup 6))
9807 (cond_exec (match_dup 7)
9808 (set (match_dup 0) (match_dup 4)))]
9811 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9812 operands[2], operands[3]);
9813 enum rtx_code rc = GET_CODE (operands[1]);
9815 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9816 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9817 if (mode == CCFPmode || mode == CCFPEmode)
9818 rc = reverse_condition_maybe_unordered (rc);
9820 rc = reverse_condition (rc);
9822 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
9827 [(set (match_operand:SI 0 "s_register_operand" "")
9828 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9829 [(match_operand 2 "" "") (match_operand 3 "" "")])
9830 (match_operand 4 "" "")
9832 (clobber (reg:CC CC_REGNUM))]
9833 "TARGET_ARM && reload_completed"
9834 [(set (match_dup 5) (match_dup 6))
9835 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
9836 (set (match_dup 0) (match_dup 4)))]
9839 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9840 operands[2], operands[3]);
9842 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9843 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9848 [(set (match_operand:SI 0 "s_register_operand" "")
9849 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9850 [(match_operand 2 "" "") (match_operand 3 "" "")])
9851 (match_operand 4 "" "")
9852 (match_operand 5 "" "")))
9853 (clobber (reg:CC CC_REGNUM))]
9854 "TARGET_ARM && reload_completed"
9855 [(set (match_dup 6) (match_dup 7))
9856 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9857 (set (match_dup 0) (match_dup 4)))
9858 (cond_exec (match_dup 8)
9859 (set (match_dup 0) (match_dup 5)))]
9862 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9863 operands[2], operands[3]);
9864 enum rtx_code rc = GET_CODE (operands[1]);
9866 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9867 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9868 if (mode == CCFPmode || mode == CCFPEmode)
9869 rc = reverse_condition_maybe_unordered (rc);
9871 rc = reverse_condition (rc);
9873 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9878 [(set (match_operand:SI 0 "s_register_operand" "")
9879 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9880 [(match_operand:SI 2 "s_register_operand" "")
9881 (match_operand:SI 3 "arm_add_operand" "")])
9882 (match_operand:SI 4 "arm_rhs_operand" "")
9884 (match_operand:SI 5 "s_register_operand" ""))))
9885 (clobber (reg:CC CC_REGNUM))]
9886 "TARGET_ARM && reload_completed"
9887 [(set (match_dup 6) (match_dup 7))
9888 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9889 (set (match_dup 0) (match_dup 4)))
9890 (cond_exec (match_dup 8)
9891 (set (match_dup 0) (not:SI (match_dup 5))))]
9894 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9895 operands[2], operands[3]);
9896 enum rtx_code rc = GET_CODE (operands[1]);
9898 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9899 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9900 if (mode == CCFPmode || mode == CCFPEmode)
9901 rc = reverse_condition_maybe_unordered (rc);
9903 rc = reverse_condition (rc);
9905 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9909 (define_insn "*cond_move_not"
9910 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9911 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9912 [(match_operand 3 "cc_register" "") (const_int 0)])
9913 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9915 (match_operand:SI 2 "s_register_operand" "r,r"))))]
9919 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
9920 [(set_attr "conds" "use")
9921 (set_attr "length" "4,8")]
9924 ;; The next two patterns occur when an AND operation is followed by a
9925 ;; scc insn sequence
9927 (define_insn "*sign_extract_onebit"
9928 [(set (match_operand:SI 0 "s_register_operand" "=r")
9929 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
9931 (match_operand:SI 2 "const_int_operand" "n")))
9932 (clobber (reg:CC CC_REGNUM))]
9935 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9936 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
9937 return \"mvnne\\t%0, #0\";
9939 [(set_attr "conds" "clob")
9940 (set_attr "length" "8")]
9943 (define_insn "*not_signextract_onebit"
9944 [(set (match_operand:SI 0 "s_register_operand" "=r")
9946 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
9948 (match_operand:SI 2 "const_int_operand" "n"))))
9949 (clobber (reg:CC CC_REGNUM))]
9952 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9953 output_asm_insn (\"tst\\t%1, %2\", operands);
9954 output_asm_insn (\"mvneq\\t%0, #0\", operands);
9955 return \"movne\\t%0, #0\";
9957 [(set_attr "conds" "clob")
9958 (set_attr "length" "12")]
9961 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
9962 ;; expressions. For simplicity, the first register is also in the unspec
9964 (define_insn "*push_multi"
9965 [(match_parallel 2 "multi_register_push"
9966 [(set (match_operand:BLK 0 "memory_operand" "=m")
9967 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
9968 UNSPEC_PUSH_MULT))])]
9972 int num_saves = XVECLEN (operands[2], 0);
9974 /* For the StrongARM at least it is faster to
9975 use STR to store only a single register. */
9977 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
9983 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
9985 for (i = 1; i < num_saves; i++)
9987 strcat (pattern, \", %|\");
9989 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
9992 strcat (pattern, \"}\");
9993 output_asm_insn (pattern, operands);
9998 [(set_attr "type" "store4")]
10001 (define_insn "stack_tie"
10002 [(set (mem:BLK (scratch))
10003 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10004 (match_operand:SI 1 "s_register_operand" "r")]
10008 [(set_attr "length" "0")]
10011 ;; Similarly for the floating point registers
10012 (define_insn "*push_fp_multi"
10013 [(match_parallel 2 "multi_register_push"
10014 [(set (match_operand:BLK 0 "memory_operand" "=m")
10015 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10016 UNSPEC_PUSH_MULT))])]
10017 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10022 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10023 output_asm_insn (pattern, operands);
10026 [(set_attr "type" "f_store")]
10029 ;; Special patterns for dealing with the constant pool
10031 (define_insn "align_4"
10032 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10035 assemble_align (32);
10040 (define_insn "align_8"
10041 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10044 assemble_align (64);
10049 (define_insn "consttable_end"
10050 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10053 making_const_table = FALSE;
10058 (define_insn "consttable_1"
10059 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10062 making_const_table = TRUE;
10063 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10064 assemble_zeros (3);
10067 [(set_attr "length" "4")]
10070 (define_insn "consttable_2"
10071 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10074 making_const_table = TRUE;
10075 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10076 assemble_zeros (2);
10079 [(set_attr "length" "4")]
10082 (define_insn "consttable_4"
10083 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10087 making_const_table = TRUE;
10088 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10093 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10094 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10098 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10103 [(set_attr "length" "4")]
10106 (define_insn "consttable_8"
10107 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10111 making_const_table = TRUE;
10112 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10117 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10118 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10122 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10127 [(set_attr "length" "8")]
10130 ;; Miscellaneous Thumb patterns
10132 (define_expand "tablejump"
10133 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10134 (use (label_ref (match_operand 1 "" "")))])]
10139 /* Hopefully, CSE will eliminate this copy. */
10140 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10141 rtx reg2 = gen_reg_rtx (SImode);
10143 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10144 operands[0] = reg2;
10149 ;; NB never uses BX.
10150 (define_insn "*thumb_tablejump"
10151 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10152 (use (label_ref (match_operand 1 "" "")))]
10155 [(set_attr "length" "2")]
10158 ;; V5 Instructions,
10160 (define_insn "clzsi2"
10161 [(set (match_operand:SI 0 "s_register_operand" "=r")
10162 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10163 "TARGET_ARM && arm_arch5"
10165 [(set_attr "predicable" "yes")])
10167 (define_expand "ffssi2"
10168 [(set (match_operand:SI 0 "s_register_operand" "")
10169 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10170 "TARGET_ARM && arm_arch5"
10175 t1 = gen_reg_rtx (SImode);
10176 t2 = gen_reg_rtx (SImode);
10177 t3 = gen_reg_rtx (SImode);
10179 emit_insn (gen_negsi2 (t1, operands[1]));
10180 emit_insn (gen_andsi3 (t2, operands[1], t1));
10181 emit_insn (gen_clzsi2 (t3, t2));
10182 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10187 (define_expand "ctzsi2"
10188 [(set (match_operand:SI 0 "s_register_operand" "")
10189 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10190 "TARGET_ARM && arm_arch5"
10195 t1 = gen_reg_rtx (SImode);
10196 t2 = gen_reg_rtx (SImode);
10197 t3 = gen_reg_rtx (SImode);
10199 emit_insn (gen_negsi2 (t1, operands[1]));
10200 emit_insn (gen_andsi3 (t2, operands[1], t1));
10201 emit_insn (gen_clzsi2 (t3, t2));
10202 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10207 ;; V5E instructions.
10209 (define_insn "prefetch"
10210 [(prefetch (match_operand:SI 0 "address_operand" "p")
10211 (match_operand:SI 1 "" "")
10212 (match_operand:SI 2 "" ""))]
10213 "TARGET_ARM && arm_arch5e"
10216 ;; General predication pattern
10219 [(match_operator 0 "arm_comparison_operator"
10220 [(match_operand 1 "cc_register" "")
10226 (define_insn "prologue_use"
10227 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10229 "%@ %0 needed for prologue"
10233 ;; Patterns for exception handling
10235 (define_expand "eh_return"
10236 [(use (match_operand 0 "general_operand" ""))]
10241 emit_insn (gen_arm_eh_return (operands[0]));
10243 emit_insn (gen_thumb_eh_return (operands[0]));
10248 ;; We can't expand this before we know where the link register is stored.
10249 (define_insn_and_split "arm_eh_return"
10250 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10252 (clobber (match_scratch:SI 1 "=&r"))]
10255 "&& reload_completed"
10259 arm_set_return_address (operands[0], operands[1]);
10264 (define_insn_and_split "thumb_eh_return"
10265 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
10267 (clobber (match_scratch:SI 1 "=&l"))]
10270 "&& reload_completed"
10274 thumb_set_return_address (operands[0], operands[1]);
10279 ;; Load the FPA co-processor patterns
10281 ;; Load the Maverick co-processor patterns
10282 (include "cirrus.md")
10283 ;; Load the Intel Wireless Multimedia Extension patterns
10284 (include "iwmmxt.md")
10285 ;; Load the VFP co-processor patterns