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, 2005 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 [(R0_REGNUM 0) ; First CORE register
34 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (CC_REGNUM 24) ; Condition code pseudo register
39 (LAST_ARM_REGNUM 15) ;
40 (FPA_F0_REGNUM 16) ; FIRST_FPA_REGNUM
41 (FPA_F7_REGNUM 23) ; LAST_FPA_REGNUM
44 ;; 3rd operand to select_dominance_cc_mode
53 ;; Note: sin and cos are no-longer used.
56 [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT):
57 ; operand 0 is the result,
58 ; operand 1 the parameter.
59 (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT):
60 ; operand 0 is the result,
61 ; operand 1 the parameter.
62 (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
63 ; operand 0 is the first register,
64 ; subsequent registers are in parallel (use ...)
66 (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
67 ; usage, that is, we will add the pic_register
68 ; value to it before trying to dereference it.
69 (UNSPEC_PIC_BASE 4) ; Adding the PC value to the offset to the
70 ; GLOBAL_OFFSET_TABLE. The operation is fully
71 ; described by the RTL but must be wrapped to
72 ; prevent combine from trying to rip it apart.
73 (UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
74 ; being scheduled before the stack adjustment insn.
75 (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
76 ; this unspec is used to prevent the deletion of
77 ; instructions setting registers for EH handling
78 ; and stack frame generation. Operand 0 is the
80 (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
81 (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
82 (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
83 (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
84 (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
85 (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
86 (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
87 (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
88 (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
89 (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
90 (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
91 (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
92 (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
96 ;; UNSPEC_VOLATILE Usage:
99 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
101 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
102 ; instruction epilogue sequence that isn't expanded
103 ; into normal RTL. Used for both normal and sibcall
105 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
106 ; for inlined constants.
107 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
109 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
111 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
113 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
115 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
117 (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
118 (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
119 (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
120 (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
121 (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
122 (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
123 (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
128 ;;---------------------------------------------------------------------------
131 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
132 ; generating ARM code. This is used to control the length of some insn
133 ; patterns that share the same RTL in both ARM and Thumb code.
134 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
136 ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
137 ; scheduling decisions for the load unit and the multiplier.
138 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
140 ; IS_XSCALE is set to 'yes' when compiling for XScale.
141 (define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
143 ;; Operand number of an input operand that is shifted. Zero if the
144 ;; given instruction does not shift one of its input operands.
145 (define_attr "shift" "" (const_int 0))
147 ; Floating Point Unit. If we only have floating point emulation, then there
148 ; is no point in scheduling the floating point insns. (Well, for best
149 ; performance we should try and group them together).
150 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
151 (const (symbol_ref "arm_fpu_attr")))
153 ; LENGTH of an instruction (in bytes)
154 (define_attr "length" "" (const_int 4))
156 ; POOL_RANGE is how far away from a constant pool entry that this insn
157 ; can be placed. If the distance is zero, then this insn will never
158 ; reference the pool.
159 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
160 ; before its address.
161 (define_attr "pool_range" "" (const_int 0))
162 (define_attr "neg_pool_range" "" (const_int 0))
164 ; An assembler sequence may clobber the condition codes without us knowing.
165 ; If such an insn references the pool, then we have no way of knowing how,
166 ; so use the most conservative value for pool_range.
167 (define_asm_attributes
168 [(set_attr "conds" "clob")
169 (set_attr "length" "4")
170 (set_attr "pool_range" "250")])
172 ;; The instruction used to implement a particular pattern. This
173 ;; information is used by pipeline descriptions to provide accurate
174 ;; scheduling information.
177 "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"
178 (const_string "other"))
180 ; TYPE attribute is used to detect floating point instructions which, if
181 ; running on a co-processor can run in parallel with other, basic instructions
182 ; If write-buffer scheduling is enabled then it can also be used in the
183 ; scheduling of writes.
185 ; Classification of each insn
186 ; alu any alu instruction that doesn't hit memory or fp
187 ; regs or have a shifted source operand
188 ; alu_shift any data instruction that doesn't hit memory or fp
189 ; regs, but has a source operand shifted by a constant
190 ; alu_shift_reg any data instruction that doesn't hit memory or fp
191 ; regs, but has a source operand shifted by a register value
192 ; mult a multiply instruction
193 ; block blockage insn, this blocks all functional units
194 ; float a floating point arithmetic operation (subject to expansion)
195 ; fdivd DFmode floating point division
196 ; fdivs SFmode floating point division
197 ; fmul Floating point multiply
198 ; ffmul Fast floating point multiply
199 ; farith Floating point arithmetic (4 cycle)
200 ; ffarith Fast floating point arithmetic (2 cycle)
201 ; float_em a floating point arithmetic operation that is normally emulated
202 ; even on a machine with an fpa.
203 ; f_load a floating point load from memory
204 ; f_store a floating point store to memory
205 ; f_mem_r a transfer of a floating point register to a real reg via mem
206 ; r_mem_f the reverse of f_mem_r
207 ; f_2_r fast transfer float to arm (no memory needed)
208 ; r_2_f fast transfer arm to float
210 ; call a subroutine call
211 ; load_byte load byte(s) from memory to arm registers
212 ; load1 load 1 word from memory to arm registers
213 ; load2 load 2 words from memory to arm registers
214 ; load3 load 3 words from memory to arm registers
215 ; load4 load 4 words from memory to arm registers
216 ; store store 1 word to memory from arm registers
217 ; store2 store 2 words
218 ; store3 store 3 words
219 ; store4 store 4 (or more) words
220 ; Additions for Cirrus Maverick co-processor:
221 ; mav_farith Floating point arithmetic (4 cycle)
222 ; mav_dmult Double multiplies (7 cycle)
225 "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"
227 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
228 (const_string "mult")
229 (const_string "alu")))
231 ; Load scheduling, set from the arm_ld_sched variable
232 ; initialized by arm_override_options()
233 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
235 ; condition codes: this one is used by final_prescan_insn to speed up
236 ; conditionalizing instructions. It saves having to scan the rtl to see if
237 ; it uses or alters the condition codes.
239 ; USE means that the condition codes are used by the insn in the process of
240 ; outputting code, this means (at present) that we can't use the insn in
243 ; SET means that the purpose of the insn is to set the condition codes in a
244 ; well defined manner.
246 ; CLOB means that the condition codes are altered in an undefined manner, if
247 ; they are altered at all
249 ; JUMP_CLOB is used when the condition cannot be represented by a single
250 ; instruction (UNEQ and LTGT). These cannot be predicated.
252 ; NOCOND means that the condition codes are neither altered nor affect the
253 ; output of this insn
255 (define_attr "conds" "use,set,clob,jump_clob,nocond"
256 (if_then_else (eq_attr "type" "call")
257 (const_string "clob")
258 (const_string "nocond")))
260 ; Predicable means that the insn can be conditionally executed based on
261 ; an automatically added predicate (additional patterns are generated by
262 ; gen...). We default to 'no' because no Thumb patterns match this rule
263 ; and not all ARM patterns do.
264 (define_attr "predicable" "no,yes" (const_string "no"))
266 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
267 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
268 ; suffer blockages enough to warrant modelling this (and it can adversely
269 ; affect the schedule).
270 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
272 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
273 ; to stall the processor. Used with model_wbuf above.
274 (define_attr "write_conflict" "no,yes"
275 (if_then_else (eq_attr "type"
276 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
278 (const_string "no")))
280 ; Classify the insns into those that take one cycle and those that take more
281 ; than one on the main cpu execution unit.
282 (define_attr "core_cycles" "single,multi"
283 (if_then_else (eq_attr "type"
284 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
285 (const_string "single")
286 (const_string "multi")))
288 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
289 ;; distant label. Only applicable to Thumb code.
290 (define_attr "far_jump" "yes,no" (const_string "no"))
292 (include "predicates.md")
294 ;;---------------------------------------------------------------------------
295 ;; Pipeline descriptions
297 ;; Processor type. This is created automatically from arm-cores.def.
298 (include "arm-tune.md")
300 ;; True if the generic scheduling description should be used.
302 (define_attr "generic_sched" "yes,no"
304 (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
306 (const_string "yes"))))
308 (include "arm-generic.md")
309 (include "arm926ejs.md")
310 (include "arm1026ejs.md")
311 (include "arm1136jfs.md")
314 ;;---------------------------------------------------------------------------
319 ;; Note: For DImode insns, there is normally no reason why operands should
320 ;; not be in the same register, what we don't want is for something being
321 ;; written to partially overlap something that is an input.
322 ;; Cirrus 64bit additions should not be split because we have a native
323 ;; 64bit addition instructions.
325 (define_expand "adddi3"
327 [(set (match_operand:DI 0 "s_register_operand" "")
328 (plus:DI (match_operand:DI 1 "s_register_operand" "")
329 (match_operand:DI 2 "s_register_operand" "")))
330 (clobber (reg:CC CC_REGNUM))])]
333 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
335 if (!cirrus_fp_register (operands[0], DImode))
336 operands[0] = force_reg (DImode, operands[0]);
337 if (!cirrus_fp_register (operands[1], DImode))
338 operands[1] = force_reg (DImode, operands[1]);
339 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
345 if (GET_CODE (operands[1]) != REG)
346 operands[1] = force_reg (SImode, operands[1]);
347 if (GET_CODE (operands[2]) != REG)
348 operands[2] = force_reg (SImode, operands[2]);
353 (define_insn "*thumb_adddi3"
354 [(set (match_operand:DI 0 "register_operand" "=l")
355 (plus:DI (match_operand:DI 1 "register_operand" "%0")
356 (match_operand:DI 2 "register_operand" "l")))
357 (clobber (reg:CC CC_REGNUM))
360 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
361 [(set_attr "length" "4")]
364 (define_insn_and_split "*arm_adddi3"
365 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
366 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
367 (match_operand:DI 2 "s_register_operand" "r, 0")))
368 (clobber (reg:CC CC_REGNUM))]
369 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
371 "TARGET_ARM && reload_completed"
372 [(parallel [(set (reg:CC_C CC_REGNUM)
373 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
375 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
376 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
377 (plus:SI (match_dup 4) (match_dup 5))))]
380 operands[3] = gen_highpart (SImode, operands[0]);
381 operands[0] = gen_lowpart (SImode, operands[0]);
382 operands[4] = gen_highpart (SImode, operands[1]);
383 operands[1] = gen_lowpart (SImode, operands[1]);
384 operands[5] = gen_highpart (SImode, operands[2]);
385 operands[2] = gen_lowpart (SImode, operands[2]);
387 [(set_attr "conds" "clob")
388 (set_attr "length" "8")]
391 (define_insn_and_split "*adddi_sesidi_di"
392 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
393 (plus:DI (sign_extend:DI
394 (match_operand:SI 2 "s_register_operand" "r,r"))
395 (match_operand:DI 1 "s_register_operand" "r,0")))
396 (clobber (reg:CC CC_REGNUM))]
397 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
399 "TARGET_ARM && reload_completed"
400 [(parallel [(set (reg:CC_C CC_REGNUM)
401 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
403 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
404 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
405 (plus:SI (ashiftrt:SI (match_dup 2)
410 operands[3] = gen_highpart (SImode, operands[0]);
411 operands[0] = gen_lowpart (SImode, operands[0]);
412 operands[4] = gen_highpart (SImode, operands[1]);
413 operands[1] = gen_lowpart (SImode, operands[1]);
414 operands[2] = gen_lowpart (SImode, operands[2]);
416 [(set_attr "conds" "clob")
417 (set_attr "length" "8")]
420 (define_insn_and_split "*adddi_zesidi_di"
421 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
422 (plus:DI (zero_extend:DI
423 (match_operand:SI 2 "s_register_operand" "r,r"))
424 (match_operand:DI 1 "s_register_operand" "r,0")))
425 (clobber (reg:CC CC_REGNUM))]
426 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
428 "TARGET_ARM && reload_completed"
429 [(parallel [(set (reg:CC_C CC_REGNUM)
430 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
432 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
433 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
434 (plus:SI (match_dup 4) (const_int 0))))]
437 operands[3] = gen_highpart (SImode, operands[0]);
438 operands[0] = gen_lowpart (SImode, operands[0]);
439 operands[4] = gen_highpart (SImode, operands[1]);
440 operands[1] = gen_lowpart (SImode, operands[1]);
441 operands[2] = gen_lowpart (SImode, operands[2]);
443 [(set_attr "conds" "clob")
444 (set_attr "length" "8")]
447 (define_expand "addsi3"
448 [(set (match_operand:SI 0 "s_register_operand" "")
449 (plus:SI (match_operand:SI 1 "s_register_operand" "")
450 (match_operand:SI 2 "reg_or_int_operand" "")))]
453 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
455 arm_split_constant (PLUS, SImode, NULL_RTX,
456 INTVAL (operands[2]), operands[0], operands[1],
457 optimize && !no_new_pseudos);
463 ; If there is a scratch available, this will be faster than synthesizing the
466 [(match_scratch:SI 3 "r")
467 (set (match_operand:SI 0 "arm_general_register_operand" "")
468 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
469 (match_operand:SI 2 "const_int_operand" "")))]
471 !(const_ok_for_arm (INTVAL (operands[2]))
472 || const_ok_for_arm (-INTVAL (operands[2])))
473 && const_ok_for_arm (~INTVAL (operands[2]))"
474 [(set (match_dup 3) (match_dup 2))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
479 (define_insn_and_split "*arm_addsi3"
480 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
481 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
482 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
489 GET_CODE (operands[2]) == CONST_INT
490 && !(const_ok_for_arm (INTVAL (operands[2]))
491 || const_ok_for_arm (-INTVAL (operands[2])))"
492 [(clobber (const_int 0))]
494 arm_split_constant (PLUS, SImode, curr_insn,
495 INTVAL (operands[2]), operands[0],
499 [(set_attr "length" "4,4,16")
500 (set_attr "predicable" "yes")]
503 ;; Register group 'k' is a single register group containing only the stack
504 ;; register. Trying to reload it will always fail catastrophically,
505 ;; so never allow those alternatives to match if reloading is needed.
507 (define_insn "*thumb_addsi3"
508 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
509 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
510 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
513 static const char * const asms[] =
515 \"add\\t%0, %0, %2\",
516 \"sub\\t%0, %0, #%n2\",
517 \"add\\t%0, %1, %2\",
518 \"add\\t%0, %0, %2\",
519 \"add\\t%0, %0, %2\",
520 \"add\\t%0, %1, %2\",
523 if ((which_alternative == 2 || which_alternative == 6)
524 && GET_CODE (operands[2]) == CONST_INT
525 && INTVAL (operands[2]) < 0)
526 return \"sub\\t%0, %1, #%n2\";
527 return asms[which_alternative];
529 [(set_attr "length" "2")]
532 ;; Reloading and elimination of the frame pointer can
533 ;; sometimes cause this optimization to be missed.
535 [(set (match_operand:SI 0 "arm_general_register_operand" "")
536 (match_operand:SI 1 "const_int_operand" ""))
538 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
540 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
541 && (INTVAL (operands[1]) & 3) == 0"
542 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
546 (define_insn "*addsi3_compare0"
547 [(set (reg:CC_NOOV CC_REGNUM)
549 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
550 (match_operand:SI 2 "arm_add_operand" "rI,L"))
552 (set (match_operand:SI 0 "s_register_operand" "=r,r")
553 (plus:SI (match_dup 1) (match_dup 2)))]
557 sub%?s\\t%0, %1, #%n2"
558 [(set_attr "conds" "set")]
561 (define_insn "*addsi3_compare0_scratch"
562 [(set (reg:CC_NOOV CC_REGNUM)
564 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
565 (match_operand:SI 1 "arm_add_operand" "rI,L"))
571 [(set_attr "conds" "set")]
574 ;; These patterns are the same ones as the two regular addsi3_compare0
575 ;; patterns, except we write them slightly different - the combiner
576 ;; tends to generate them this way.
577 (define_insn "*addsi3_compare0_for_combiner"
578 [(set (reg:CC CC_REGNUM)
580 (match_operand:SI 1 "s_register_operand" "r,r")
581 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
582 (set (match_operand:SI 0 "s_register_operand" "=r,r")
583 (plus:SI (match_dup 1) (match_dup 2)))]
587 sub%?s\\t%0, %1, #%n2"
588 [(set_attr "conds" "set")]
591 (define_insn "*addsi3_compare0_scratch_for_combiner"
592 [(set (reg:CC CC_REGNUM)
594 (match_operand:SI 0 "s_register_operand" "r,r")
595 (neg:SI (match_operand:SI 1 "arm_add_operand" "rI,L"))))]
600 [(set_attr "conds" "set")]
603 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
604 ;; addend is a constant.
605 (define_insn "*cmpsi2_addneg"
606 [(set (reg:CC CC_REGNUM)
608 (match_operand:SI 1 "s_register_operand" "r,r")
609 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
610 (set (match_operand:SI 0 "s_register_operand" "=r,r")
611 (plus:SI (match_dup 1)
612 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
613 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
616 add%?s\\t%0, %1, #%n2"
617 [(set_attr "conds" "set")]
620 ;; Convert the sequence
622 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
626 ;; bcs dest ((unsigned)rn >= 1)
627 ;; similarly for the beq variant using bcc.
628 ;; This is a common looping idiom (while (n--))
630 [(set (match_operand:SI 0 "arm_general_register_operand" "")
631 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
633 (set (match_operand 2 "cc_register" "")
634 (compare (match_dup 0) (const_int -1)))
636 (if_then_else (match_operator 3 "equality_operator"
637 [(match_dup 2) (const_int 0)])
638 (match_operand 4 "" "")
639 (match_operand 5 "" "")))]
640 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
644 (match_dup 1) (const_int 1)))
645 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
647 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
650 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
651 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
654 operands[2], const0_rtx);"
657 ;; The next four insns work because they compare the result with one of
658 ;; the operands, and we know that the use of the condition code is
659 ;; either GEU or LTU, so we can use the carry flag from the addition
660 ;; instead of doing the compare a second time.
661 (define_insn "*addsi3_compare_op1"
662 [(set (reg:CC_C CC_REGNUM)
664 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
665 (match_operand:SI 2 "arm_add_operand" "rI,L"))
667 (set (match_operand:SI 0 "s_register_operand" "=r,r")
668 (plus:SI (match_dup 1) (match_dup 2)))]
672 sub%?s\\t%0, %1, #%n2"
673 [(set_attr "conds" "set")]
676 (define_insn "*addsi3_compare_op2"
677 [(set (reg:CC_C CC_REGNUM)
679 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
680 (match_operand:SI 2 "arm_add_operand" "rI,L"))
682 (set (match_operand:SI 0 "s_register_operand" "=r,r")
683 (plus:SI (match_dup 1) (match_dup 2)))]
687 sub%?s\\t%0, %1, #%n2"
688 [(set_attr "conds" "set")]
691 (define_insn "*compare_addsi2_op0"
692 [(set (reg:CC_C CC_REGNUM)
694 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
695 (match_operand:SI 1 "arm_add_operand" "rI,L"))
701 [(set_attr "conds" "set")]
704 (define_insn "*compare_addsi2_op1"
705 [(set (reg:CC_C CC_REGNUM)
707 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
708 (match_operand:SI 1 "arm_add_operand" "rI,L"))
714 [(set_attr "conds" "set")]
717 (define_insn "*addsi3_carryin"
718 [(set (match_operand:SI 0 "s_register_operand" "=r")
719 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
720 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
721 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
724 [(set_attr "conds" "use")]
727 (define_insn "*addsi3_carryin_shift"
728 [(set (match_operand:SI 0 "s_register_operand" "=r")
729 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
731 (match_operator:SI 2 "shift_operator"
732 [(match_operand:SI 3 "s_register_operand" "r")
733 (match_operand:SI 4 "reg_or_int_operand" "rM")])
734 (match_operand:SI 1 "s_register_operand" "r"))))]
736 "adc%?\\t%0, %1, %3%S2"
737 [(set_attr "conds" "use")
738 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
739 (const_string "alu_shift")
740 (const_string "alu_shift_reg")))]
743 (define_insn "*addsi3_carryin_alt1"
744 [(set (match_operand:SI 0 "s_register_operand" "=r")
745 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
746 (match_operand:SI 2 "arm_rhs_operand" "rI"))
747 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
750 [(set_attr "conds" "use")]
753 (define_insn "*addsi3_carryin_alt2"
754 [(set (match_operand:SI 0 "s_register_operand" "=r")
755 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
756 (match_operand:SI 1 "s_register_operand" "r"))
757 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
760 [(set_attr "conds" "use")]
763 (define_insn "*addsi3_carryin_alt3"
764 [(set (match_operand:SI 0 "s_register_operand" "=r")
765 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
766 (match_operand:SI 2 "arm_rhs_operand" "rI"))
767 (match_operand:SI 1 "s_register_operand" "r")))]
770 [(set_attr "conds" "use")]
773 (define_insn "incscc"
774 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
775 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
776 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
777 (match_operand:SI 1 "s_register_operand" "0,?r")))]
781 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
782 [(set_attr "conds" "use")
783 (set_attr "length" "4,8")]
786 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
788 [(set (match_operand:SI 0 "s_register_operand" "")
789 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
790 (match_operand:SI 2 "s_register_operand" ""))
792 (clobber (match_operand:SI 3 "s_register_operand" ""))]
794 [(set (match_dup 3) (match_dup 1))
795 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
797 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
800 (define_expand "addsf3"
801 [(set (match_operand:SF 0 "s_register_operand" "")
802 (plus:SF (match_operand:SF 1 "s_register_operand" "")
803 (match_operand:SF 2 "arm_float_add_operand" "")))]
804 "TARGET_ARM && TARGET_HARD_FLOAT"
807 && !cirrus_fp_register (operands[2], SFmode))
808 operands[2] = force_reg (SFmode, operands[2]);
811 (define_expand "adddf3"
812 [(set (match_operand:DF 0 "s_register_operand" "")
813 (plus:DF (match_operand:DF 1 "s_register_operand" "")
814 (match_operand:DF 2 "arm_float_add_operand" "")))]
815 "TARGET_ARM && TARGET_HARD_FLOAT"
818 && !cirrus_fp_register (operands[2], DFmode))
819 operands[2] = force_reg (DFmode, operands[2]);
822 (define_expand "subdi3"
824 [(set (match_operand:DI 0 "s_register_operand" "")
825 (minus:DI (match_operand:DI 1 "s_register_operand" "")
826 (match_operand:DI 2 "s_register_operand" "")))
827 (clobber (reg:CC CC_REGNUM))])]
830 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
832 && cirrus_fp_register (operands[0], DImode)
833 && cirrus_fp_register (operands[1], DImode))
835 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
841 if (GET_CODE (operands[1]) != REG)
842 operands[1] = force_reg (SImode, operands[1]);
843 if (GET_CODE (operands[2]) != REG)
844 operands[2] = force_reg (SImode, operands[2]);
849 (define_insn "*arm_subdi3"
850 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
851 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
852 (match_operand:DI 2 "s_register_operand" "r,0,0")))
853 (clobber (reg:CC CC_REGNUM))]
855 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
856 [(set_attr "conds" "clob")
857 (set_attr "length" "8")]
860 (define_insn "*thumb_subdi3"
861 [(set (match_operand:DI 0 "register_operand" "=l")
862 (minus:DI (match_operand:DI 1 "register_operand" "0")
863 (match_operand:DI 2 "register_operand" "l")))
864 (clobber (reg:CC CC_REGNUM))]
866 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
867 [(set_attr "length" "4")]
870 (define_insn "*subdi_di_zesidi"
871 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
872 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
874 (match_operand:SI 2 "s_register_operand" "r,r"))))
875 (clobber (reg:CC CC_REGNUM))]
877 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
878 [(set_attr "conds" "clob")
879 (set_attr "length" "8")]
882 (define_insn "*subdi_di_sesidi"
883 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
884 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
886 (match_operand:SI 2 "s_register_operand" "r,r"))))
887 (clobber (reg:CC CC_REGNUM))]
889 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
890 [(set_attr "conds" "clob")
891 (set_attr "length" "8")]
894 (define_insn "*subdi_zesidi_di"
895 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
896 (minus:DI (zero_extend:DI
897 (match_operand:SI 2 "s_register_operand" "r,r"))
898 (match_operand:DI 1 "s_register_operand" "?r,0")))
899 (clobber (reg:CC CC_REGNUM))]
901 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
902 [(set_attr "conds" "clob")
903 (set_attr "length" "8")]
906 (define_insn "*subdi_sesidi_di"
907 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
908 (minus:DI (sign_extend:DI
909 (match_operand:SI 2 "s_register_operand" "r,r"))
910 (match_operand:DI 1 "s_register_operand" "?r,0")))
911 (clobber (reg:CC CC_REGNUM))]
913 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
914 [(set_attr "conds" "clob")
915 (set_attr "length" "8")]
918 (define_insn "*subdi_zesidi_zesidi"
919 [(set (match_operand:DI 0 "s_register_operand" "=r")
920 (minus:DI (zero_extend:DI
921 (match_operand:SI 1 "s_register_operand" "r"))
923 (match_operand:SI 2 "s_register_operand" "r"))))
924 (clobber (reg:CC CC_REGNUM))]
926 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
927 [(set_attr "conds" "clob")
928 (set_attr "length" "8")]
931 (define_expand "subsi3"
932 [(set (match_operand:SI 0 "s_register_operand" "")
933 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
934 (match_operand:SI 2 "s_register_operand" "")))]
937 if (GET_CODE (operands[1]) == CONST_INT)
941 arm_split_constant (MINUS, SImode, NULL_RTX,
942 INTVAL (operands[1]), operands[0],
943 operands[2], optimize && !no_new_pseudos);
946 else /* TARGET_THUMB */
947 operands[1] = force_reg (SImode, operands[1]);
952 (define_insn "*thumb_subsi3_insn"
953 [(set (match_operand:SI 0 "register_operand" "=l")
954 (minus:SI (match_operand:SI 1 "register_operand" "l")
955 (match_operand:SI 2 "register_operand" "l")))]
958 [(set_attr "length" "2")]
961 (define_insn_and_split "*arm_subsi3_insn"
962 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
963 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
964 (match_operand:SI 2 "s_register_operand" "r,r")))]
970 && GET_CODE (operands[1]) == CONST_INT
971 && !const_ok_for_arm (INTVAL (operands[1]))"
972 [(clobber (const_int 0))]
974 arm_split_constant (MINUS, SImode, curr_insn,
975 INTVAL (operands[1]), operands[0], operands[2], 0);
978 [(set_attr "length" "4,16")
979 (set_attr "predicable" "yes")]
983 [(match_scratch:SI 3 "r")
984 (set (match_operand:SI 0 "arm_general_register_operand" "")
985 (minus:SI (match_operand:SI 1 "const_int_operand" "")
986 (match_operand:SI 2 "arm_general_register_operand" "")))]
988 && !const_ok_for_arm (INTVAL (operands[1]))
989 && const_ok_for_arm (~INTVAL (operands[1]))"
990 [(set (match_dup 3) (match_dup 1))
991 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
995 (define_insn "*subsi3_compare0"
996 [(set (reg:CC_NOOV CC_REGNUM)
998 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
999 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1001 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1002 (minus:SI (match_dup 1) (match_dup 2)))]
1006 rsb%?s\\t%0, %2, %1"
1007 [(set_attr "conds" "set")]
1010 (define_insn "decscc"
1011 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1012 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1013 (match_operator:SI 2 "arm_comparison_operator"
1014 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1018 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1019 [(set_attr "conds" "use")
1020 (set_attr "length" "*,8")]
1023 (define_expand "subsf3"
1024 [(set (match_operand:SF 0 "s_register_operand" "")
1025 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1026 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1027 "TARGET_ARM && TARGET_HARD_FLOAT"
1029 if (TARGET_MAVERICK)
1031 if (!cirrus_fp_register (operands[1], SFmode))
1032 operands[1] = force_reg (SFmode, operands[1]);
1033 if (!cirrus_fp_register (operands[2], SFmode))
1034 operands[2] = force_reg (SFmode, operands[2]);
1038 (define_expand "subdf3"
1039 [(set (match_operand:DF 0 "s_register_operand" "")
1040 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1041 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1042 "TARGET_ARM && TARGET_HARD_FLOAT"
1044 if (TARGET_MAVERICK)
1046 if (!cirrus_fp_register (operands[1], DFmode))
1047 operands[1] = force_reg (DFmode, operands[1]);
1048 if (!cirrus_fp_register (operands[2], DFmode))
1049 operands[2] = force_reg (DFmode, operands[2]);
1054 ;; Multiplication insns
1056 (define_expand "mulsi3"
1057 [(set (match_operand:SI 0 "s_register_operand" "")
1058 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1059 (match_operand:SI 1 "s_register_operand" "")))]
1064 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1065 (define_insn "*arm_mulsi3"
1066 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1067 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1068 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1070 "mul%?\\t%0, %2, %1"
1071 [(set_attr "insn" "mul")
1072 (set_attr "predicable" "yes")]
1075 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1076 ; 1 and 2; are the same, because reload will make operand 0 match
1077 ; operand 1 without realizing that this conflicts with operand 2. We fix
1078 ; this by adding another alternative to match this case, and then `reload'
1079 ; it ourselves. This alternative must come first.
1080 (define_insn "*thumb_mulsi3"
1081 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1082 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1083 (match_operand:SI 2 "register_operand" "l,l,l")))]
1086 if (which_alternative < 2)
1087 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1089 return \"mul\\t%0, %0, %2\";
1091 [(set_attr "length" "4,4,2")
1092 (set_attr "insn" "mul")]
1095 (define_insn "*mulsi3_compare0"
1096 [(set (reg:CC_NOOV CC_REGNUM)
1097 (compare:CC_NOOV (mult:SI
1098 (match_operand:SI 2 "s_register_operand" "r,r")
1099 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1101 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1102 (mult:SI (match_dup 2) (match_dup 1)))]
1104 "mul%?s\\t%0, %2, %1"
1105 [(set_attr "conds" "set")
1106 (set_attr "insn" "muls")]
1109 (define_insn "*mulsi_compare0_scratch"
1110 [(set (reg:CC_NOOV CC_REGNUM)
1111 (compare:CC_NOOV (mult:SI
1112 (match_operand:SI 2 "s_register_operand" "r,r")
1113 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1115 (clobber (match_scratch:SI 0 "=&r,&r"))]
1117 "mul%?s\\t%0, %2, %1"
1118 [(set_attr "conds" "set")
1119 (set_attr "insn" "muls")]
1122 ;; Unnamed templates to match MLA instruction.
1124 (define_insn "*mulsi3addsi"
1125 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1127 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1128 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1129 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1131 "mla%?\\t%0, %2, %1, %3"
1132 [(set_attr "insn" "mla")
1133 (set_attr "predicable" "yes")]
1136 (define_insn "*mulsi3addsi_compare0"
1137 [(set (reg:CC_NOOV CC_REGNUM)
1140 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1141 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1142 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1144 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1145 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1148 "mla%?s\\t%0, %2, %1, %3"
1149 [(set_attr "conds" "set")
1150 (set_attr "insn" "mlas")]
1153 (define_insn "*mulsi3addsi_compare0_scratch"
1154 [(set (reg:CC_NOOV CC_REGNUM)
1157 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1158 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1159 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1161 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1163 "mla%?s\\t%0, %2, %1, %3"
1164 [(set_attr "conds" "set")
1165 (set_attr "insn" "mlas")]
1168 ;; Unnamed template to match long long multiply-accumulate (smlal)
1170 (define_insn "*mulsidi3adddi"
1171 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1174 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1175 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1176 (match_operand:DI 1 "s_register_operand" "0")))]
1177 "TARGET_ARM && arm_arch3m"
1178 "smlal%?\\t%Q0, %R0, %3, %2"
1179 [(set_attr "insn" "smlal")
1180 (set_attr "predicable" "yes")]
1183 (define_insn "mulsidi3"
1184 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1186 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1187 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1188 "TARGET_ARM && arm_arch3m"
1189 "smull%?\\t%Q0, %R0, %1, %2"
1190 [(set_attr "insn" "smull")
1191 (set_attr "predicable" "yes")]
1194 (define_insn "umulsidi3"
1195 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1197 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1198 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1199 "TARGET_ARM && arm_arch3m"
1200 "umull%?\\t%Q0, %R0, %1, %2"
1201 [(set_attr "insn" "umull")
1202 (set_attr "predicable" "yes")]
1205 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1207 (define_insn "*umulsidi3adddi"
1208 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1211 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1212 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1213 (match_operand:DI 1 "s_register_operand" "0")))]
1214 "TARGET_ARM && arm_arch3m"
1215 "umlal%?\\t%Q0, %R0, %3, %2"
1216 [(set_attr "insn" "umlal")
1217 (set_attr "predicable" "yes")]
1220 (define_insn "smulsi3_highpart"
1221 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1225 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1226 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1228 (clobber (match_scratch:SI 3 "=&r,&r"))]
1229 "TARGET_ARM && arm_arch3m"
1230 "smull%?\\t%3, %0, %2, %1"
1231 [(set_attr "insn" "smull")
1232 (set_attr "predicable" "yes")]
1235 (define_insn "umulsi3_highpart"
1236 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1240 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1241 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1243 (clobber (match_scratch:SI 3 "=&r,&r"))]
1244 "TARGET_ARM && arm_arch3m"
1245 "umull%?\\t%3, %0, %2, %1"
1246 [(set_attr "insn" "umull")
1247 (set_attr "predicable" "yes")]
1250 (define_insn "mulhisi3"
1251 [(set (match_operand:SI 0 "s_register_operand" "=r")
1252 (mult:SI (sign_extend:SI
1253 (match_operand:HI 1 "s_register_operand" "%r"))
1255 (match_operand:HI 2 "s_register_operand" "r"))))]
1256 "TARGET_ARM && arm_arch5e"
1257 "smulbb%?\\t%0, %1, %2"
1258 [(set_attr "insn" "smulxy")
1259 (set_attr "predicable" "yes")]
1262 (define_insn "*mulhisi3tb"
1263 [(set (match_operand:SI 0 "s_register_operand" "=r")
1264 (mult:SI (ashiftrt:SI
1265 (match_operand:SI 1 "s_register_operand" "r")
1268 (match_operand:HI 2 "s_register_operand" "r"))))]
1269 "TARGET_ARM && arm_arch5e"
1270 "smultb%?\\t%0, %1, %2"
1271 [(set_attr "insn" "smulxy")
1272 (set_attr "predicable" "yes")]
1275 (define_insn "*mulhisi3bt"
1276 [(set (match_operand:SI 0 "s_register_operand" "=r")
1277 (mult:SI (sign_extend:SI
1278 (match_operand:HI 1 "s_register_operand" "r"))
1280 (match_operand:SI 2 "s_register_operand" "r")
1282 "TARGET_ARM && arm_arch5e"
1283 "smulbt%?\\t%0, %1, %2"
1284 [(set_attr "insn" "smulxy")
1285 (set_attr "predicable" "yes")]
1288 (define_insn "*mulhisi3tt"
1289 [(set (match_operand:SI 0 "s_register_operand" "=r")
1290 (mult:SI (ashiftrt:SI
1291 (match_operand:SI 1 "s_register_operand" "r")
1294 (match_operand:SI 2 "s_register_operand" "r")
1296 "TARGET_ARM && arm_arch5e"
1297 "smultt%?\\t%0, %1, %2"
1298 [(set_attr "insn" "smulxy")
1299 (set_attr "predicable" "yes")]
1302 (define_insn "*mulhisi3addsi"
1303 [(set (match_operand:SI 0 "s_register_operand" "=r")
1304 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1305 (mult:SI (sign_extend:SI
1306 (match_operand:HI 2 "s_register_operand" "%r"))
1308 (match_operand:HI 3 "s_register_operand" "r")))))]
1309 "TARGET_ARM && arm_arch5e"
1310 "smlabb%?\\t%0, %2, %3, %1"
1311 [(set_attr "insn" "smlaxy")
1312 (set_attr "predicable" "yes")]
1315 (define_insn "*mulhidi3adddi"
1316 [(set (match_operand:DI 0 "s_register_operand" "=r")
1318 (match_operand:DI 1 "s_register_operand" "0")
1319 (mult:DI (sign_extend:DI
1320 (match_operand:HI 2 "s_register_operand" "%r"))
1322 (match_operand:HI 3 "s_register_operand" "r")))))]
1323 "TARGET_ARM && arm_arch5e"
1324 "smlalbb%?\\t%Q0, %R0, %2, %3"
1325 [(set_attr "insn" "smlalxy")
1326 (set_attr "predicable" "yes")])
1328 (define_expand "mulsf3"
1329 [(set (match_operand:SF 0 "s_register_operand" "")
1330 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1331 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1332 "TARGET_ARM && TARGET_HARD_FLOAT"
1335 && !cirrus_fp_register (operands[2], SFmode))
1336 operands[2] = force_reg (SFmode, operands[2]);
1339 (define_expand "muldf3"
1340 [(set (match_operand:DF 0 "s_register_operand" "")
1341 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1342 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1343 "TARGET_ARM && TARGET_HARD_FLOAT"
1346 && !cirrus_fp_register (operands[2], DFmode))
1347 operands[2] = force_reg (DFmode, operands[2]);
1352 (define_expand "divsf3"
1353 [(set (match_operand:SF 0 "s_register_operand" "")
1354 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1355 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1356 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1359 (define_expand "divdf3"
1360 [(set (match_operand:DF 0 "s_register_operand" "")
1361 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1362 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1363 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1368 (define_expand "modsf3"
1369 [(set (match_operand:SF 0 "s_register_operand" "")
1370 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1371 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1372 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1375 (define_expand "moddf3"
1376 [(set (match_operand:DF 0 "s_register_operand" "")
1377 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1378 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1379 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1382 ;; Boolean and,ior,xor insns
1384 ;; Split up double word logical operations
1386 ;; Split up simple DImode logical operations. Simply perform the logical
1387 ;; operation on the upper and lower halves of the registers.
1389 [(set (match_operand:DI 0 "s_register_operand" "")
1390 (match_operator:DI 6 "logical_binary_operator"
1391 [(match_operand:DI 1 "s_register_operand" "")
1392 (match_operand:DI 2 "s_register_operand" "")]))]
1393 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1394 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1395 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1398 operands[3] = gen_highpart (SImode, operands[0]);
1399 operands[0] = gen_lowpart (SImode, operands[0]);
1400 operands[4] = gen_highpart (SImode, operands[1]);
1401 operands[1] = gen_lowpart (SImode, operands[1]);
1402 operands[5] = gen_highpart (SImode, operands[2]);
1403 operands[2] = gen_lowpart (SImode, operands[2]);
1408 [(set (match_operand:DI 0 "s_register_operand" "")
1409 (match_operator:DI 6 "logical_binary_operator"
1410 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1411 (match_operand:DI 1 "s_register_operand" "")]))]
1412 "TARGET_ARM && reload_completed"
1413 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1414 (set (match_dup 3) (match_op_dup:SI 6
1415 [(ashiftrt:SI (match_dup 2) (const_int 31))
1419 operands[3] = gen_highpart (SImode, operands[0]);
1420 operands[0] = gen_lowpart (SImode, operands[0]);
1421 operands[4] = gen_highpart (SImode, operands[1]);
1422 operands[1] = gen_lowpart (SImode, operands[1]);
1423 operands[5] = gen_highpart (SImode, operands[2]);
1424 operands[2] = gen_lowpart (SImode, operands[2]);
1428 ;; The zero extend of operand 2 means we can just copy the high part of
1429 ;; operand1 into operand0.
1431 [(set (match_operand:DI 0 "s_register_operand" "")
1433 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1434 (match_operand:DI 1 "s_register_operand" "")))]
1435 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1436 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1437 (set (match_dup 3) (match_dup 4))]
1440 operands[4] = gen_highpart (SImode, operands[1]);
1441 operands[3] = gen_highpart (SImode, operands[0]);
1442 operands[0] = gen_lowpart (SImode, operands[0]);
1443 operands[1] = gen_lowpart (SImode, operands[1]);
1447 ;; The zero extend of operand 2 means we can just copy the high part of
1448 ;; operand1 into operand0.
1450 [(set (match_operand:DI 0 "s_register_operand" "")
1452 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1453 (match_operand:DI 1 "s_register_operand" "")))]
1454 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1455 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1456 (set (match_dup 3) (match_dup 4))]
1459 operands[4] = gen_highpart (SImode, operands[1]);
1460 operands[3] = gen_highpart (SImode, operands[0]);
1461 operands[0] = gen_lowpart (SImode, operands[0]);
1462 operands[1] = gen_lowpart (SImode, operands[1]);
1466 (define_insn "anddi3"
1467 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1468 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1469 (match_operand:DI 2 "s_register_operand" "r,r")))]
1470 "TARGET_ARM && ! TARGET_IWMMXT"
1472 [(set_attr "length" "8")]
1475 (define_insn_and_split "*anddi_zesidi_di"
1476 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1477 (and:DI (zero_extend:DI
1478 (match_operand:SI 2 "s_register_operand" "r,r"))
1479 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1482 "TARGET_ARM && reload_completed"
1483 ; The zero extend of operand 2 clears the high word of the output
1485 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1486 (set (match_dup 3) (const_int 0))]
1489 operands[3] = gen_highpart (SImode, operands[0]);
1490 operands[0] = gen_lowpart (SImode, operands[0]);
1491 operands[1] = gen_lowpart (SImode, operands[1]);
1493 [(set_attr "length" "8")]
1496 (define_insn "*anddi_sesdi_di"
1497 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1498 (and:DI (sign_extend:DI
1499 (match_operand:SI 2 "s_register_operand" "r,r"))
1500 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1503 [(set_attr "length" "8")]
1506 (define_expand "andsi3"
1507 [(set (match_operand:SI 0 "s_register_operand" "")
1508 (and:SI (match_operand:SI 1 "s_register_operand" "")
1509 (match_operand:SI 2 "reg_or_int_operand" "")))]
1514 if (GET_CODE (operands[2]) == CONST_INT)
1516 arm_split_constant (AND, SImode, NULL_RTX,
1517 INTVAL (operands[2]), operands[0],
1518 operands[1], optimize && !no_new_pseudos);
1523 else /* TARGET_THUMB */
1525 if (GET_CODE (operands[2]) != CONST_INT)
1526 operands[2] = force_reg (SImode, operands[2]);
1531 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1533 operands[2] = force_reg (SImode,
1534 GEN_INT (~INTVAL (operands[2])));
1536 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1541 for (i = 9; i <= 31; i++)
1543 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1545 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1549 else if ((((HOST_WIDE_INT) 1) << i) - 1
1550 == ~INTVAL (operands[2]))
1552 rtx shift = GEN_INT (i);
1553 rtx reg = gen_reg_rtx (SImode);
1555 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1556 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1562 operands[2] = force_reg (SImode, operands[2]);
1568 (define_insn_and_split "*arm_andsi3_insn"
1569 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1570 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1571 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1575 bic%?\\t%0, %1, #%B2
1578 && GET_CODE (operands[2]) == CONST_INT
1579 && !(const_ok_for_arm (INTVAL (operands[2]))
1580 || const_ok_for_arm (~INTVAL (operands[2])))"
1581 [(clobber (const_int 0))]
1583 arm_split_constant (AND, SImode, curr_insn,
1584 INTVAL (operands[2]), operands[0], operands[1], 0);
1587 [(set_attr "length" "4,4,16")
1588 (set_attr "predicable" "yes")]
1591 (define_insn "*thumb_andsi3_insn"
1592 [(set (match_operand:SI 0 "register_operand" "=l")
1593 (and:SI (match_operand:SI 1 "register_operand" "%0")
1594 (match_operand:SI 2 "register_operand" "l")))]
1597 [(set_attr "length" "2")]
1600 (define_insn "*andsi3_compare0"
1601 [(set (reg:CC_NOOV CC_REGNUM)
1603 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1604 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1606 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1607 (and:SI (match_dup 1) (match_dup 2)))]
1611 bic%?s\\t%0, %1, #%B2"
1612 [(set_attr "conds" "set")]
1615 (define_insn "*andsi3_compare0_scratch"
1616 [(set (reg:CC_NOOV CC_REGNUM)
1618 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1619 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1621 (clobber (match_scratch:SI 2 "=X,r"))]
1625 bic%?s\\t%2, %0, #%B1"
1626 [(set_attr "conds" "set")]
1629 (define_insn "*zeroextractsi_compare0_scratch"
1630 [(set (reg:CC_NOOV CC_REGNUM)
1631 (compare:CC_NOOV (zero_extract:SI
1632 (match_operand:SI 0 "s_register_operand" "r")
1633 (match_operand 1 "const_int_operand" "n")
1634 (match_operand 2 "const_int_operand" "n"))
1637 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1638 && INTVAL (operands[1]) > 0
1639 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1640 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1642 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1643 << INTVAL (operands[2]));
1644 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1647 [(set_attr "conds" "set")]
1650 (define_insn_and_split "*ne_zeroextractsi"
1651 [(set (match_operand:SI 0 "s_register_operand" "=r")
1652 (ne:SI (zero_extract:SI
1653 (match_operand:SI 1 "s_register_operand" "r")
1654 (match_operand:SI 2 "const_int_operand" "n")
1655 (match_operand:SI 3 "const_int_operand" "n"))
1657 (clobber (reg:CC CC_REGNUM))]
1659 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1660 && INTVAL (operands[2]) > 0
1661 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1662 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1665 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1666 && INTVAL (operands[2]) > 0
1667 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1668 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1669 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1670 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1672 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1674 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1675 (match_dup 0) (const_int 1)))]
1677 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1678 << INTVAL (operands[3]));
1680 [(set_attr "conds" "clob")
1681 (set_attr "length" "8")]
1684 (define_insn_and_split "*ne_zeroextractsi_shifted"
1685 [(set (match_operand:SI 0 "s_register_operand" "=r")
1686 (ne:SI (zero_extract:SI
1687 (match_operand:SI 1 "s_register_operand" "r")
1688 (match_operand:SI 2 "const_int_operand" "n")
1691 (clobber (reg:CC CC_REGNUM))]
1695 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1696 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1698 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1700 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1701 (match_dup 0) (const_int 1)))]
1703 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1705 [(set_attr "conds" "clob")
1706 (set_attr "length" "8")]
1709 (define_insn_and_split "*ite_ne_zeroextractsi"
1710 [(set (match_operand:SI 0 "s_register_operand" "=r")
1711 (if_then_else:SI (ne (zero_extract:SI
1712 (match_operand:SI 1 "s_register_operand" "r")
1713 (match_operand:SI 2 "const_int_operand" "n")
1714 (match_operand:SI 3 "const_int_operand" "n"))
1716 (match_operand:SI 4 "arm_not_operand" "rIK")
1718 (clobber (reg:CC CC_REGNUM))]
1720 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1721 && INTVAL (operands[2]) > 0
1722 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1723 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1724 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1727 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1728 && INTVAL (operands[2]) > 0
1729 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1730 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1731 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1732 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1733 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1735 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1737 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1738 (match_dup 0) (match_dup 4)))]
1740 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1741 << INTVAL (operands[3]));
1743 [(set_attr "conds" "clob")
1744 (set_attr "length" "8")]
1747 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
1748 [(set (match_operand:SI 0 "s_register_operand" "=r")
1749 (if_then_else:SI (ne (zero_extract:SI
1750 (match_operand:SI 1 "s_register_operand" "r")
1751 (match_operand:SI 2 "const_int_operand" "n")
1754 (match_operand:SI 3 "arm_not_operand" "rIK")
1756 (clobber (reg:CC CC_REGNUM))]
1757 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1759 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1760 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1761 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1763 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1765 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1766 (match_dup 0) (match_dup 3)))]
1768 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1770 [(set_attr "conds" "clob")
1771 (set_attr "length" "8")]
1775 [(set (match_operand:SI 0 "s_register_operand" "")
1776 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1777 (match_operand:SI 2 "const_int_operand" "")
1778 (match_operand:SI 3 "const_int_operand" "")))
1779 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1781 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1782 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1784 HOST_WIDE_INT temp = INTVAL (operands[2]);
1786 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1787 operands[3] = GEN_INT (32 - temp);
1792 [(set (match_operand:SI 0 "s_register_operand" "")
1793 (match_operator:SI 1 "shiftable_operator"
1794 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1795 (match_operand:SI 3 "const_int_operand" "")
1796 (match_operand:SI 4 "const_int_operand" ""))
1797 (match_operand:SI 5 "s_register_operand" "")]))
1798 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1800 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1803 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1806 HOST_WIDE_INT temp = INTVAL (operands[3]);
1808 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1809 operands[4] = GEN_INT (32 - temp);
1814 [(set (match_operand:SI 0 "s_register_operand" "")
1815 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1816 (match_operand:SI 2 "const_int_operand" "")
1817 (match_operand:SI 3 "const_int_operand" "")))]
1819 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1820 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1822 HOST_WIDE_INT temp = INTVAL (operands[2]);
1824 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1825 operands[3] = GEN_INT (32 - temp);
1830 [(set (match_operand:SI 0 "s_register_operand" "")
1831 (match_operator:SI 1 "shiftable_operator"
1832 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1833 (match_operand:SI 3 "const_int_operand" "")
1834 (match_operand:SI 4 "const_int_operand" ""))
1835 (match_operand:SI 5 "s_register_operand" "")]))
1836 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1838 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1841 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1844 HOST_WIDE_INT temp = INTVAL (operands[3]);
1846 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1847 operands[4] = GEN_INT (32 - temp);
1851 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1852 ;;; represented by the bitfield, then this will produce incorrect results.
1853 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1854 ;;; which have a real bit-field insert instruction, the truncation happens
1855 ;;; in the bit-field insert instruction itself. Since arm does not have a
1856 ;;; bit-field insert instruction, we would have to emit code here to truncate
1857 ;;; the value before we insert. This loses some of the advantage of having
1858 ;;; this insv pattern, so this pattern needs to be reevalutated.
1860 (define_expand "insv"
1861 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1862 (match_operand:SI 1 "general_operand" "")
1863 (match_operand:SI 2 "general_operand" ""))
1864 (match_operand:SI 3 "reg_or_int_operand" ""))]
1868 int start_bit = INTVAL (operands[2]);
1869 int width = INTVAL (operands[1]);
1870 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1871 rtx target, subtarget;
1873 target = operands[0];
1874 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1875 subreg as the final target. */
1876 if (GET_CODE (target) == SUBREG)
1878 subtarget = gen_reg_rtx (SImode);
1879 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1880 < GET_MODE_SIZE (SImode))
1881 target = SUBREG_REG (target);
1886 if (GET_CODE (operands[3]) == CONST_INT)
1888 /* Since we are inserting a known constant, we may be able to
1889 reduce the number of bits that we have to clear so that
1890 the mask becomes simple. */
1891 /* ??? This code does not check to see if the new mask is actually
1892 simpler. It may not be. */
1893 rtx op1 = gen_reg_rtx (SImode);
1894 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1895 start of this pattern. */
1896 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1897 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1899 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1900 emit_insn (gen_iorsi3 (subtarget, op1,
1901 gen_int_mode (op3_value << start_bit, SImode)));
1903 else if (start_bit == 0
1904 && !(const_ok_for_arm (mask)
1905 || const_ok_for_arm (~mask)))
1907 /* A Trick, since we are setting the bottom bits in the word,
1908 we can shift operand[3] up, operand[0] down, OR them together
1909 and rotate the result back again. This takes 3 insns, and
1910 the third might be mergeable into another op. */
1911 /* The shift up copes with the possibility that operand[3] is
1912 wider than the bitfield. */
1913 rtx op0 = gen_reg_rtx (SImode);
1914 rtx op1 = gen_reg_rtx (SImode);
1916 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1917 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1918 emit_insn (gen_iorsi3 (op1, op1, op0));
1919 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1921 else if ((width + start_bit == 32)
1922 && !(const_ok_for_arm (mask)
1923 || const_ok_for_arm (~mask)))
1925 /* Similar trick, but slightly less efficient. */
1927 rtx op0 = gen_reg_rtx (SImode);
1928 rtx op1 = gen_reg_rtx (SImode);
1930 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1931 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1932 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1933 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1937 rtx op0 = GEN_INT (mask);
1938 rtx op1 = gen_reg_rtx (SImode);
1939 rtx op2 = gen_reg_rtx (SImode);
1941 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1943 rtx tmp = gen_reg_rtx (SImode);
1945 emit_insn (gen_movsi (tmp, op0));
1949 /* Mask out any bits in operand[3] that are not needed. */
1950 emit_insn (gen_andsi3 (op1, operands[3], op0));
1952 if (GET_CODE (op0) == CONST_INT
1953 && (const_ok_for_arm (mask << start_bit)
1954 || const_ok_for_arm (~(mask << start_bit))))
1956 op0 = GEN_INT (~(mask << start_bit));
1957 emit_insn (gen_andsi3 (op2, operands[0], op0));
1961 if (GET_CODE (op0) == CONST_INT)
1963 rtx tmp = gen_reg_rtx (SImode);
1965 emit_insn (gen_movsi (tmp, op0));
1970 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1972 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1976 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1978 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1981 if (subtarget != target)
1983 /* If TARGET is still a SUBREG, then it must be wider than a word,
1984 so we must be careful only to set the subword we were asked to. */
1985 if (GET_CODE (target) == SUBREG)
1986 emit_move_insn (target, subtarget);
1988 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1995 ; constants for op 2 will never be given to these patterns.
1996 (define_insn_and_split "*anddi_notdi_di"
1997 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1998 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1999 (match_operand:DI 2 "s_register_operand" "0,r")))]
2002 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2003 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2004 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2007 operands[3] = gen_highpart (SImode, operands[0]);
2008 operands[0] = gen_lowpart (SImode, operands[0]);
2009 operands[4] = gen_highpart (SImode, operands[1]);
2010 operands[1] = gen_lowpart (SImode, operands[1]);
2011 operands[5] = gen_highpart (SImode, operands[2]);
2012 operands[2] = gen_lowpart (SImode, operands[2]);
2014 [(set_attr "length" "8")
2015 (set_attr "predicable" "yes")]
2018 (define_insn_and_split "*anddi_notzesidi_di"
2019 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2020 (and:DI (not:DI (zero_extend:DI
2021 (match_operand:SI 2 "s_register_operand" "r,r")))
2022 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2025 bic%?\\t%Q0, %Q1, %2
2027 ; (not (zero_extend ...)) allows us to just copy the high word from
2028 ; operand1 to operand0.
2031 && operands[0] != operands[1]"
2032 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2033 (set (match_dup 3) (match_dup 4))]
2036 operands[3] = gen_highpart (SImode, operands[0]);
2037 operands[0] = gen_lowpart (SImode, operands[0]);
2038 operands[4] = gen_highpart (SImode, operands[1]);
2039 operands[1] = gen_lowpart (SImode, operands[1]);
2041 [(set_attr "length" "4,8")
2042 (set_attr "predicable" "yes")]
2045 (define_insn_and_split "*anddi_notsesidi_di"
2046 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2047 (and:DI (not:DI (sign_extend:DI
2048 (match_operand:SI 2 "s_register_operand" "r,r")))
2049 (match_operand:DI 1 "s_register_operand" "0,r")))]
2052 "TARGET_ARM && reload_completed"
2053 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2054 (set (match_dup 3) (and:SI (not:SI
2055 (ashiftrt:SI (match_dup 2) (const_int 31)))
2059 operands[3] = gen_highpart (SImode, operands[0]);
2060 operands[0] = gen_lowpart (SImode, operands[0]);
2061 operands[4] = gen_highpart (SImode, operands[1]);
2062 operands[1] = gen_lowpart (SImode, operands[1]);
2064 [(set_attr "length" "8")
2065 (set_attr "predicable" "yes")]
2068 (define_insn "andsi_notsi_si"
2069 [(set (match_operand:SI 0 "s_register_operand" "=r")
2070 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2071 (match_operand:SI 1 "s_register_operand" "r")))]
2073 "bic%?\\t%0, %1, %2"
2074 [(set_attr "predicable" "yes")]
2077 (define_insn "bicsi3"
2078 [(set (match_operand:SI 0 "register_operand" "=l")
2079 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2080 (match_operand:SI 2 "register_operand" "0")))]
2083 [(set_attr "length" "2")]
2086 (define_insn "andsi_not_shiftsi_si"
2087 [(set (match_operand:SI 0 "s_register_operand" "=r")
2088 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2089 [(match_operand:SI 2 "s_register_operand" "r")
2090 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2091 (match_operand:SI 1 "s_register_operand" "r")))]
2093 "bic%?\\t%0, %1, %2%S4"
2094 [(set_attr "predicable" "yes")
2095 (set_attr "shift" "2")
2096 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2097 (const_string "alu_shift")
2098 (const_string "alu_shift_reg")))]
2101 (define_insn "*andsi_notsi_si_compare0"
2102 [(set (reg:CC_NOOV CC_REGNUM)
2104 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2105 (match_operand:SI 1 "s_register_operand" "r"))
2107 (set (match_operand:SI 0 "s_register_operand" "=r")
2108 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2110 "bic%?s\\t%0, %1, %2"
2111 [(set_attr "conds" "set")]
2114 (define_insn "*andsi_notsi_si_compare0_scratch"
2115 [(set (reg:CC_NOOV CC_REGNUM)
2117 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2118 (match_operand:SI 1 "s_register_operand" "r"))
2120 (clobber (match_scratch:SI 0 "=r"))]
2122 "bic%?s\\t%0, %1, %2"
2123 [(set_attr "conds" "set")]
2126 (define_insn "iordi3"
2127 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2128 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2129 (match_operand:DI 2 "s_register_operand" "r,r")))]
2130 "TARGET_ARM && ! TARGET_IWMMXT"
2132 [(set_attr "length" "8")
2133 (set_attr "predicable" "yes")]
2136 (define_insn "*iordi_zesidi_di"
2137 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2138 (ior:DI (zero_extend:DI
2139 (match_operand:SI 2 "s_register_operand" "r,r"))
2140 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2143 orr%?\\t%Q0, %Q1, %2
2145 [(set_attr "length" "4,8")
2146 (set_attr "predicable" "yes")]
2149 (define_insn "*iordi_sesidi_di"
2150 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2151 (ior:DI (sign_extend:DI
2152 (match_operand:SI 2 "s_register_operand" "r,r"))
2153 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2156 [(set_attr "length" "8")
2157 (set_attr "predicable" "yes")]
2160 (define_expand "iorsi3"
2161 [(set (match_operand:SI 0 "s_register_operand" "")
2162 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2163 (match_operand:SI 2 "reg_or_int_operand" "")))]
2166 if (GET_CODE (operands[2]) == CONST_INT)
2170 arm_split_constant (IOR, SImode, NULL_RTX,
2171 INTVAL (operands[2]), operands[0], operands[1],
2172 optimize && !no_new_pseudos);
2175 else /* TARGET_THUMB */
2176 operands [2] = force_reg (SImode, operands [2]);
2181 (define_insn_and_split "*arm_iorsi3"
2182 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2183 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2184 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2190 && GET_CODE (operands[2]) == CONST_INT
2191 && !const_ok_for_arm (INTVAL (operands[2]))"
2192 [(clobber (const_int 0))]
2194 arm_split_constant (IOR, SImode, curr_insn,
2195 INTVAL (operands[2]), operands[0], operands[1], 0);
2198 [(set_attr "length" "4,16")
2199 (set_attr "predicable" "yes")]
2202 (define_insn "*thumb_iorsi3"
2203 [(set (match_operand:SI 0 "register_operand" "=l")
2204 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2205 (match_operand:SI 2 "register_operand" "l")))]
2208 [(set_attr "length" "2")]
2212 [(match_scratch:SI 3 "r")
2213 (set (match_operand:SI 0 "arm_general_register_operand" "")
2214 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2215 (match_operand:SI 2 "const_int_operand" "")))]
2217 && !const_ok_for_arm (INTVAL (operands[2]))
2218 && const_ok_for_arm (~INTVAL (operands[2]))"
2219 [(set (match_dup 3) (match_dup 2))
2220 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2224 (define_insn "*iorsi3_compare0"
2225 [(set (reg:CC_NOOV CC_REGNUM)
2226 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2227 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2229 (set (match_operand:SI 0 "s_register_operand" "=r")
2230 (ior:SI (match_dup 1) (match_dup 2)))]
2232 "orr%?s\\t%0, %1, %2"
2233 [(set_attr "conds" "set")]
2236 (define_insn "*iorsi3_compare0_scratch"
2237 [(set (reg:CC_NOOV CC_REGNUM)
2238 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2239 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2241 (clobber (match_scratch:SI 0 "=r"))]
2243 "orr%?s\\t%0, %1, %2"
2244 [(set_attr "conds" "set")]
2247 (define_insn "xordi3"
2248 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2249 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2250 (match_operand:DI 2 "s_register_operand" "r,r")))]
2251 "TARGET_ARM && !TARGET_IWMMXT"
2253 [(set_attr "length" "8")
2254 (set_attr "predicable" "yes")]
2257 (define_insn "*xordi_zesidi_di"
2258 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2259 (xor:DI (zero_extend:DI
2260 (match_operand:SI 2 "s_register_operand" "r,r"))
2261 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2264 eor%?\\t%Q0, %Q1, %2
2266 [(set_attr "length" "4,8")
2267 (set_attr "predicable" "yes")]
2270 (define_insn "*xordi_sesidi_di"
2271 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2272 (xor:DI (sign_extend:DI
2273 (match_operand:SI 2 "s_register_operand" "r,r"))
2274 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2277 [(set_attr "length" "8")
2278 (set_attr "predicable" "yes")]
2281 (define_expand "xorsi3"
2282 [(set (match_operand:SI 0 "s_register_operand" "")
2283 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2284 (match_operand:SI 2 "arm_rhs_operand" "")))]
2287 if (GET_CODE (operands[2]) == CONST_INT)
2288 operands[2] = force_reg (SImode, operands[2]);
2292 (define_insn "*arm_xorsi3"
2293 [(set (match_operand:SI 0 "s_register_operand" "=r")
2294 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2295 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2297 "eor%?\\t%0, %1, %2"
2298 [(set_attr "predicable" "yes")]
2301 (define_insn "*thumb_xorsi3"
2302 [(set (match_operand:SI 0 "register_operand" "=l")
2303 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2304 (match_operand:SI 2 "register_operand" "l")))]
2307 [(set_attr "length" "2")]
2310 (define_insn "*xorsi3_compare0"
2311 [(set (reg:CC_NOOV CC_REGNUM)
2312 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2313 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2315 (set (match_operand:SI 0 "s_register_operand" "=r")
2316 (xor:SI (match_dup 1) (match_dup 2)))]
2318 "eor%?s\\t%0, %1, %2"
2319 [(set_attr "conds" "set")]
2322 (define_insn "*xorsi3_compare0_scratch"
2323 [(set (reg:CC_NOOV CC_REGNUM)
2324 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2325 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2329 [(set_attr "conds" "set")]
2332 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2333 ; (NOT D) we can sometimes merge the final NOT into one of the following
2337 [(set (match_operand:SI 0 "s_register_operand" "")
2338 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2339 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2340 (match_operand:SI 3 "arm_rhs_operand" "")))
2341 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2343 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2344 (not:SI (match_dup 3))))
2345 (set (match_dup 0) (not:SI (match_dup 4)))]
2349 (define_insn "*andsi_iorsi3_notsi"
2350 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2351 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2352 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2353 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2355 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2356 [(set_attr "length" "8")
2357 (set_attr "predicable" "yes")]
2361 [(set (match_operand:SI 0 "s_register_operand" "")
2362 (match_operator:SI 1 "logical_binary_operator"
2363 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2364 (match_operand:SI 3 "const_int_operand" "")
2365 (match_operand:SI 4 "const_int_operand" ""))
2366 (match_operator:SI 9 "logical_binary_operator"
2367 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2368 (match_operand:SI 6 "const_int_operand" ""))
2369 (match_operand:SI 7 "s_register_operand" "")])]))
2370 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2372 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2373 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2376 [(ashift:SI (match_dup 2) (match_dup 4))
2380 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2383 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2387 [(set (match_operand:SI 0 "s_register_operand" "")
2388 (match_operator:SI 1 "logical_binary_operator"
2389 [(match_operator:SI 9 "logical_binary_operator"
2390 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2391 (match_operand:SI 6 "const_int_operand" ""))
2392 (match_operand:SI 7 "s_register_operand" "")])
2393 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2394 (match_operand:SI 3 "const_int_operand" "")
2395 (match_operand:SI 4 "const_int_operand" ""))]))
2396 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2398 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2399 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2402 [(ashift:SI (match_dup 2) (match_dup 4))
2406 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2409 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2413 [(set (match_operand:SI 0 "s_register_operand" "")
2414 (match_operator:SI 1 "logical_binary_operator"
2415 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2416 (match_operand:SI 3 "const_int_operand" "")
2417 (match_operand:SI 4 "const_int_operand" ""))
2418 (match_operator:SI 9 "logical_binary_operator"
2419 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2420 (match_operand:SI 6 "const_int_operand" ""))
2421 (match_operand:SI 7 "s_register_operand" "")])]))
2422 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2424 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2425 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2428 [(ashift:SI (match_dup 2) (match_dup 4))
2432 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2435 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2439 [(set (match_operand:SI 0 "s_register_operand" "")
2440 (match_operator:SI 1 "logical_binary_operator"
2441 [(match_operator:SI 9 "logical_binary_operator"
2442 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2443 (match_operand:SI 6 "const_int_operand" ""))
2444 (match_operand:SI 7 "s_register_operand" "")])
2445 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2446 (match_operand:SI 3 "const_int_operand" "")
2447 (match_operand:SI 4 "const_int_operand" ""))]))
2448 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2450 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2451 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2454 [(ashift:SI (match_dup 2) (match_dup 4))
2458 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2461 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2465 ;; Minimum and maximum insns
2467 (define_insn "smaxsi3"
2468 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2469 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2470 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2471 (clobber (reg:CC CC_REGNUM))]
2474 cmp\\t%1, %2\;movlt\\t%0, %2
2475 cmp\\t%1, %2\;movge\\t%0, %1
2476 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2477 [(set_attr "conds" "clob")
2478 (set_attr "length" "8,8,12")]
2481 (define_insn "sminsi3"
2482 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2483 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2484 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2485 (clobber (reg:CC CC_REGNUM))]
2488 cmp\\t%1, %2\;movge\\t%0, %2
2489 cmp\\t%1, %2\;movlt\\t%0, %1
2490 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2491 [(set_attr "conds" "clob")
2492 (set_attr "length" "8,8,12")]
2495 (define_insn "umaxsi3"
2496 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2497 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2498 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2499 (clobber (reg:CC CC_REGNUM))]
2502 cmp\\t%1, %2\;movcc\\t%0, %2
2503 cmp\\t%1, %2\;movcs\\t%0, %1
2504 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2505 [(set_attr "conds" "clob")
2506 (set_attr "length" "8,8,12")]
2509 (define_insn "uminsi3"
2510 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2511 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2512 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2513 (clobber (reg:CC CC_REGNUM))]
2516 cmp\\t%1, %2\;movcs\\t%0, %2
2517 cmp\\t%1, %2\;movcc\\t%0, %1
2518 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2519 [(set_attr "conds" "clob")
2520 (set_attr "length" "8,8,12")]
2523 (define_insn "*store_minmaxsi"
2524 [(set (match_operand:SI 0 "memory_operand" "=m")
2525 (match_operator:SI 3 "minmax_operator"
2526 [(match_operand:SI 1 "s_register_operand" "r")
2527 (match_operand:SI 2 "s_register_operand" "r")]))
2528 (clobber (reg:CC CC_REGNUM))]
2531 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2532 operands[1], operands[2]);
2533 output_asm_insn (\"cmp\\t%1, %2\", operands);
2534 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2535 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2538 [(set_attr "conds" "clob")
2539 (set_attr "length" "12")
2540 (set_attr "type" "store1")]
2543 ; Reject the frame pointer in operand[1], since reloading this after
2544 ; it has been eliminated can cause carnage.
2545 (define_insn "*minmax_arithsi"
2546 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2547 (match_operator:SI 4 "shiftable_operator"
2548 [(match_operator:SI 5 "minmax_operator"
2549 [(match_operand:SI 2 "s_register_operand" "r,r")
2550 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2551 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2552 (clobber (reg:CC CC_REGNUM))]
2553 "TARGET_ARM && !arm_eliminable_register (operands[1])"
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, r, r, m")
4160 (match_operand:DI 1 "di_operand" "rIKDa,Db,Dc,mi,r"))]
4162 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4165 return (output_move_double (operands));
4167 [(set_attr "length" "8,12,16,8,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 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
4464 arm_load_pic_register (3);
4468 ;; If copying one reg to another we can set the condition codes according to
4469 ;; its value. Such a move is common after a return from subroutine and the
4470 ;; result is being tested against zero.
4472 (define_insn "*movsi_compare0"
4473 [(set (reg:CC CC_REGNUM)
4474 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4476 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4481 sub%?s\\t%0, %1, #0"
4482 [(set_attr "conds" "set")]
4485 ;; Subroutine to store a half word from a register into memory.
4486 ;; Operand 0 is the source register (HImode)
4487 ;; Operand 1 is the destination address in a register (SImode)
4489 ;; In both this routine and the next, we must be careful not to spill
4490 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4491 ;; can generate unrecognizable rtl.
4493 (define_expand "storehi"
4494 [;; store the low byte
4495 (set (match_operand 1 "" "") (match_dup 3))
4496 ;; extract the high byte
4498 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4499 ;; store the high byte
4500 (set (match_dup 4) (match_dup 5))]
4504 rtx op1 = operands[1];
4505 rtx addr = XEXP (op1, 0);
4506 enum rtx_code code = GET_CODE (addr);
4508 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4510 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4512 operands[4] = adjust_address (op1, QImode, 1);
4513 operands[1] = adjust_address (operands[1], QImode, 0);
4514 operands[3] = gen_lowpart (QImode, operands[0]);
4515 operands[0] = gen_lowpart (SImode, operands[0]);
4516 operands[2] = gen_reg_rtx (SImode);
4517 operands[5] = gen_lowpart (QImode, operands[2]);
4521 (define_expand "storehi_bigend"
4522 [(set (match_dup 4) (match_dup 3))
4524 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4525 (set (match_operand 1 "" "") (match_dup 5))]
4529 rtx op1 = operands[1];
4530 rtx addr = XEXP (op1, 0);
4531 enum rtx_code code = GET_CODE (addr);
4533 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4535 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4537 operands[4] = adjust_address (op1, QImode, 1);
4538 operands[1] = adjust_address (operands[1], QImode, 0);
4539 operands[3] = gen_lowpart (QImode, operands[0]);
4540 operands[0] = gen_lowpart (SImode, operands[0]);
4541 operands[2] = gen_reg_rtx (SImode);
4542 operands[5] = gen_lowpart (QImode, operands[2]);
4546 ;; Subroutine to store a half word integer constant into memory.
4547 (define_expand "storeinthi"
4548 [(set (match_operand 0 "" "")
4549 (match_operand 1 "" ""))
4550 (set (match_dup 3) (match_dup 2))]
4554 HOST_WIDE_INT value = INTVAL (operands[1]);
4555 rtx addr = XEXP (operands[0], 0);
4556 rtx op0 = operands[0];
4557 enum rtx_code code = GET_CODE (addr);
4559 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4561 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4563 operands[1] = gen_reg_rtx (SImode);
4564 if (BYTES_BIG_ENDIAN)
4566 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4567 if ((value & 255) == ((value >> 8) & 255))
4568 operands[2] = operands[1];
4571 operands[2] = gen_reg_rtx (SImode);
4572 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4577 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4578 if ((value & 255) == ((value >> 8) & 255))
4579 operands[2] = operands[1];
4582 operands[2] = gen_reg_rtx (SImode);
4583 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4587 operands[3] = adjust_address (op0, QImode, 1);
4588 operands[0] = adjust_address (operands[0], QImode, 0);
4589 operands[2] = gen_lowpart (QImode, operands[2]);
4590 operands[1] = gen_lowpart (QImode, operands[1]);
4594 (define_expand "storehi_single_op"
4595 [(set (match_operand:HI 0 "memory_operand" "")
4596 (match_operand:HI 1 "general_operand" ""))]
4597 "TARGET_ARM && arm_arch4"
4599 if (!s_register_operand (operands[1], HImode))
4600 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4604 (define_expand "movhi"
4605 [(set (match_operand:HI 0 "general_operand" "")
4606 (match_operand:HI 1 "general_operand" ""))]
4611 if (!no_new_pseudos)
4613 if (GET_CODE (operands[0]) == MEM)
4617 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4620 if (GET_CODE (operands[1]) == CONST_INT)
4621 emit_insn (gen_storeinthi (operands[0], operands[1]));
4624 if (GET_CODE (operands[1]) == MEM)
4625 operands[1] = force_reg (HImode, operands[1]);
4626 if (BYTES_BIG_ENDIAN)
4627 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4629 emit_insn (gen_storehi (operands[1], operands[0]));
4633 /* Sign extend a constant, and keep it in an SImode reg. */
4634 else if (GET_CODE (operands[1]) == CONST_INT)
4636 rtx reg = gen_reg_rtx (SImode);
4637 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4639 /* If the constant is already valid, leave it alone. */
4640 if (!const_ok_for_arm (val))
4642 /* If setting all the top bits will make the constant
4643 loadable in a single instruction, then set them.
4644 Otherwise, sign extend the number. */
4646 if (const_ok_for_arm (~(val | ~0xffff)))
4648 else if (val & 0x8000)
4652 emit_insn (gen_movsi (reg, GEN_INT (val)));
4653 operands[1] = gen_lowpart (HImode, reg);
4655 else if (arm_arch4 && optimize && !no_new_pseudos
4656 && GET_CODE (operands[1]) == MEM)
4658 rtx reg = gen_reg_rtx (SImode);
4660 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4661 operands[1] = gen_lowpart (HImode, reg);
4663 else if (!arm_arch4)
4665 if (GET_CODE (operands[1]) == MEM)
4668 rtx offset = const0_rtx;
4669 rtx reg = gen_reg_rtx (SImode);
4671 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4672 || (GET_CODE (base) == PLUS
4673 && (GET_CODE (offset = XEXP (base, 1))
4675 && ((INTVAL(offset) & 1) != 1)
4676 && GET_CODE (base = XEXP (base, 0)) == REG))
4677 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4679 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4682 new = gen_rtx_MEM (SImode,
4683 plus_constant (base, new_offset));
4684 MEM_COPY_ATTRIBUTES (new, operands[1]);
4685 emit_insn (gen_movsi (reg, new));
4686 if (((INTVAL (offset) & 2) != 0)
4687 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4689 rtx reg2 = gen_reg_rtx (SImode);
4691 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
4696 emit_insn (gen_movhi_bytes (reg, operands[1]));
4698 operands[1] = gen_lowpart (HImode, reg);
4702 /* Handle loading a large integer during reload. */
4703 else if (GET_CODE (operands[1]) == CONST_INT
4704 && !const_ok_for_arm (INTVAL (operands[1]))
4705 && !const_ok_for_arm (~INTVAL (operands[1])))
4707 /* Writing a constant to memory needs a scratch, which should
4708 be handled with SECONDARY_RELOADs. */
4709 if (GET_CODE (operands[0]) != REG)
4712 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4713 emit_insn (gen_movsi (operands[0], operands[1]));
4717 else /* TARGET_THUMB */
4719 if (!no_new_pseudos)
4721 if (GET_CODE (operands[0]) != REG)
4722 operands[1] = force_reg (HImode, operands[1]);
4724 /* ??? We shouldn't really get invalid addresses here, but this can
4725 happen if we are passed a SP (never OK for HImode/QImode) or
4726 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4727 HImode/QImode) relative address. */
4728 /* ??? This should perhaps be fixed elsewhere, for instance, in
4729 fixup_stack_1, by checking for other kinds of invalid addresses,
4730 e.g. a bare reference to a virtual register. This may confuse the
4731 alpha though, which must handle this case differently. */
4732 if (GET_CODE (operands[0]) == MEM
4733 && !memory_address_p (GET_MODE (operands[0]),
4734 XEXP (operands[0], 0)))
4736 = replace_equiv_address (operands[0],
4737 copy_to_reg (XEXP (operands[0], 0)));
4739 if (GET_CODE (operands[1]) == MEM
4740 && !memory_address_p (GET_MODE (operands[1]),
4741 XEXP (operands[1], 0)))
4743 = replace_equiv_address (operands[1],
4744 copy_to_reg (XEXP (operands[1], 0)));
4746 /* Handle loading a large integer during reload. */
4747 else if (GET_CODE (operands[1]) == CONST_INT
4748 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4750 /* Writing a constant to memory needs a scratch, which should
4751 be handled with SECONDARY_RELOADs. */
4752 if (GET_CODE (operands[0]) != REG)
4755 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4756 emit_insn (gen_movsi (operands[0], operands[1]));
4763 (define_insn "*thumb_movhi_insn"
4764 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4765 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4767 && ( register_operand (operands[0], HImode)
4768 || register_operand (operands[1], HImode))"
4770 switch (which_alternative)
4772 case 0: return \"add %0, %1, #0\";
4773 case 2: return \"strh %1, %0\";
4774 case 3: return \"mov %0, %1\";
4775 case 4: return \"mov %0, %1\";
4776 case 5: return \"mov %0, %1\";
4779 /* The stack pointer can end up being taken as an index register.
4780 Catch this case here and deal with it. */
4781 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4782 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4783 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4786 ops[0] = operands[0];
4787 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4789 output_asm_insn (\"mov %0, %1\", ops);
4791 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4794 return \"ldrh %0, %1\";
4796 [(set_attr "length" "2,4,2,2,2,2")
4797 (set_attr "type" "*,load1,store1,*,*,*")]
4801 (define_expand "movhi_bytes"
4802 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4804 (zero_extend:SI (match_dup 6)))
4805 (set (match_operand:SI 0 "" "")
4806 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4811 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4813 mem1 = gen_rtx_MEM (QImode, addr);
4814 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4815 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4816 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4817 operands[0] = gen_lowpart (SImode, operands[0]);
4819 operands[2] = gen_reg_rtx (SImode);
4820 operands[3] = gen_reg_rtx (SImode);
4823 if (BYTES_BIG_ENDIAN)
4825 operands[4] = operands[2];
4826 operands[5] = operands[3];
4830 operands[4] = operands[3];
4831 operands[5] = operands[2];
4836 (define_expand "movhi_bigend"
4838 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4841 (ashiftrt:SI (match_dup 2) (const_int 16)))
4842 (set (match_operand:HI 0 "s_register_operand" "")
4846 operands[2] = gen_reg_rtx (SImode);
4847 operands[3] = gen_reg_rtx (SImode);
4848 operands[4] = gen_lowpart (HImode, operands[3]);
4852 ;; Pattern to recognize insn generated default case above
4853 (define_insn "*movhi_insn_arch4"
4854 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4855 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4858 && (GET_CODE (operands[1]) != CONST_INT
4859 || const_ok_for_arm (INTVAL (operands[1]))
4860 || const_ok_for_arm (~INTVAL (operands[1])))"
4862 mov%?\\t%0, %1\\t%@ movhi
4863 mvn%?\\t%0, #%B1\\t%@ movhi
4864 str%?h\\t%1, %0\\t%@ movhi
4865 ldr%?h\\t%0, %1\\t%@ movhi"
4866 [(set_attr "type" "*,*,store1,load1")
4867 (set_attr "predicable" "yes")
4868 (set_attr "pool_range" "*,*,*,256")
4869 (set_attr "neg_pool_range" "*,*,*,244")]
4872 (define_insn "*movhi_bytes"
4873 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4874 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4877 mov%?\\t%0, %1\\t%@ movhi
4878 mvn%?\\t%0, #%B1\\t%@ movhi"
4879 [(set_attr "predicable" "yes")]
4882 (define_insn "thumb_movhi_clobber"
4883 [(set (match_operand:HI 0 "memory_operand" "=m")
4884 (match_operand:HI 1 "register_operand" "l"))
4885 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4891 ;; We use a DImode scratch because we may occasionally need an additional
4892 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4893 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4894 (define_expand "reload_outhi"
4895 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4896 (match_operand:HI 1 "s_register_operand" "r")
4897 (match_operand:DI 2 "s_register_operand" "=&l")])]
4900 arm_reload_out_hi (operands);
4902 thumb_reload_out_hi (operands);
4907 (define_expand "reload_inhi"
4908 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4909 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4910 (match_operand:DI 2 "s_register_operand" "=&r")])]
4914 arm_reload_in_hi (operands);
4916 thumb_reload_out_hi (operands);
4920 (define_expand "movqi"
4921 [(set (match_operand:QI 0 "general_operand" "")
4922 (match_operand:QI 1 "general_operand" ""))]
4927 /* Everything except mem = const or mem = mem can be done easily */
4929 if (!no_new_pseudos)
4931 if (GET_CODE (operands[1]) == CONST_INT)
4933 rtx reg = gen_reg_rtx (SImode);
4935 emit_insn (gen_movsi (reg, operands[1]));
4936 operands[1] = gen_lowpart (QImode, reg);
4938 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4940 rtx reg = gen_reg_rtx (SImode);
4942 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4943 operands[1] = gen_lowpart (QImode, reg);
4945 if (GET_CODE (operands[0]) == MEM)
4946 operands[1] = force_reg (QImode, operands[1]);
4949 else /* TARGET_THUMB */
4951 if (!no_new_pseudos)
4953 if (GET_CODE (operands[0]) != REG)
4954 operands[1] = force_reg (QImode, operands[1]);
4956 /* ??? We shouldn't really get invalid addresses here, but this can
4957 happen if we are passed a SP (never OK for HImode/QImode) or
4958 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4959 HImode/QImode) relative address. */
4960 /* ??? This should perhaps be fixed elsewhere, for instance, in
4961 fixup_stack_1, by checking for other kinds of invalid addresses,
4962 e.g. a bare reference to a virtual register. This may confuse the
4963 alpha though, which must handle this case differently. */
4964 if (GET_CODE (operands[0]) == MEM
4965 && !memory_address_p (GET_MODE (operands[0]),
4966 XEXP (operands[0], 0)))
4968 = replace_equiv_address (operands[0],
4969 copy_to_reg (XEXP (operands[0], 0)));
4970 if (GET_CODE (operands[1]) == MEM
4971 && !memory_address_p (GET_MODE (operands[1]),
4972 XEXP (operands[1], 0)))
4974 = replace_equiv_address (operands[1],
4975 copy_to_reg (XEXP (operands[1], 0)));
4977 /* Handle loading a large integer during reload. */
4978 else if (GET_CODE (operands[1]) == CONST_INT
4979 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
4981 /* Writing a constant to memory needs a scratch, which should
4982 be handled with SECONDARY_RELOADs. */
4983 if (GET_CODE (operands[0]) != REG)
4986 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4987 emit_insn (gen_movsi (operands[0], operands[1]));
4995 (define_insn "*arm_movqi_insn"
4996 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4997 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
4999 && ( register_operand (operands[0], QImode)
5000 || register_operand (operands[1], QImode))"
5006 [(set_attr "type" "*,*,load1,store1")
5007 (set_attr "predicable" "yes")]
5010 (define_insn "*thumb_movqi_insn"
5011 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5012 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5014 && ( register_operand (operands[0], QImode)
5015 || register_operand (operands[1], QImode))"
5023 [(set_attr "length" "2")
5024 (set_attr "type" "*,load1,store1,*,*,*")
5025 (set_attr "pool_range" "*,32,*,*,*,*")]
5028 (define_expand "movsf"
5029 [(set (match_operand:SF 0 "general_operand" "")
5030 (match_operand:SF 1 "general_operand" ""))]
5035 if (GET_CODE (operands[0]) == MEM)
5036 operands[1] = force_reg (SFmode, operands[1]);
5038 else /* TARGET_THUMB */
5040 if (!no_new_pseudos)
5042 if (GET_CODE (operands[0]) != REG)
5043 operands[1] = force_reg (SFmode, operands[1]);
5050 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5051 (match_operand:SF 1 "immediate_operand" ""))]
5053 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5055 && GET_CODE (operands[1]) == CONST_DOUBLE"
5056 [(set (match_dup 2) (match_dup 3))]
5058 operands[2] = gen_lowpart (SImode, operands[0]);
5059 operands[3] = gen_lowpart (SImode, operands[1]);
5060 if (operands[2] == 0 || operands[3] == 0)
5065 (define_insn "*arm_movsf_soft_insn"
5066 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5067 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5069 && TARGET_SOFT_FLOAT
5070 && (GET_CODE (operands[0]) != MEM
5071 || register_operand (operands[1], SFmode))"
5074 ldr%?\\t%0, %1\\t%@ float
5075 str%?\\t%1, %0\\t%@ float"
5076 [(set_attr "length" "4,4,4")
5077 (set_attr "predicable" "yes")
5078 (set_attr "type" "*,load1,store1")
5079 (set_attr "pool_range" "*,4096,*")
5080 (set_attr "neg_pool_range" "*,4084,*")]
5083 ;;; ??? This should have alternatives for constants.
5084 (define_insn "*thumb_movsf_insn"
5085 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5086 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5088 && ( register_operand (operands[0], SFmode)
5089 || register_operand (operands[1], SFmode))"
5098 [(set_attr "length" "2")
5099 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5100 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5103 (define_expand "movdf"
5104 [(set (match_operand:DF 0 "general_operand" "")
5105 (match_operand:DF 1 "general_operand" ""))]
5110 if (GET_CODE (operands[0]) == MEM)
5111 operands[1] = force_reg (DFmode, operands[1]);
5113 else /* TARGET_THUMB */
5115 if (!no_new_pseudos)
5117 if (GET_CODE (operands[0]) != REG)
5118 operands[1] = force_reg (DFmode, operands[1]);
5124 ;; Reloading a df mode value stored in integer regs to memory can require a
5126 (define_expand "reload_outdf"
5127 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5128 (match_operand:DF 1 "s_register_operand" "r")
5129 (match_operand:SI 2 "s_register_operand" "=&r")]
5133 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5136 operands[2] = XEXP (operands[0], 0);
5137 else if (code == POST_INC || code == PRE_DEC)
5139 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5140 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5141 emit_insn (gen_movdi (operands[0], operands[1]));
5144 else if (code == PRE_INC)
5146 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5148 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5151 else if (code == POST_DEC)
5152 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5154 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5155 XEXP (XEXP (operands[0], 0), 1)));
5157 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5160 if (code == POST_DEC)
5161 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5167 (define_insn "*movdf_soft_insn"
5168 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
5169 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
5170 "TARGET_ARM && TARGET_SOFT_FLOAT
5172 "* return output_move_double (operands);"
5173 [(set_attr "length" "8,12,16,8,8")
5174 (set_attr "type" "*,*,*,load2,store2")
5175 (set_attr "pool_range" "1020")
5176 (set_attr "neg_pool_range" "1008")]
5179 ;;; ??? This should have alternatives for constants.
5180 ;;; ??? This was originally identical to the movdi_insn pattern.
5181 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5182 ;;; thumb_reorg with a memory reference.
5183 (define_insn "*thumb_movdf_insn"
5184 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5185 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5187 && ( register_operand (operands[0], DFmode)
5188 || register_operand (operands[1], DFmode))"
5190 switch (which_alternative)
5194 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5195 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5196 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5198 return \"ldmia\\t%1, {%0, %H0}\";
5200 return \"stmia\\t%0, {%1, %H1}\";
5202 return thumb_load_double_from_address (operands);
5204 operands[2] = gen_rtx_MEM (SImode,
5205 plus_constant (XEXP (operands[0], 0), 4));
5206 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5209 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5210 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5211 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5214 [(set_attr "length" "4,2,2,6,4,4")
5215 (set_attr "type" "*,load2,store2,load2,store2,*")
5216 (set_attr "pool_range" "*,*,*,1020,*,*")]
5219 (define_expand "movxf"
5220 [(set (match_operand:XF 0 "general_operand" "")
5221 (match_operand:XF 1 "general_operand" ""))]
5222 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
5224 if (GET_CODE (operands[0]) == MEM)
5225 operands[1] = force_reg (XFmode, operands[1]);
5230 (define_expand "movv2si"
5231 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5232 (match_operand:V2SI 1 "general_operand" ""))]
5233 "TARGET_REALLY_IWMMXT"
5237 (define_expand "movv4hi"
5238 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5239 (match_operand:V4HI 1 "general_operand" ""))]
5240 "TARGET_REALLY_IWMMXT"
5244 (define_expand "movv8qi"
5245 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5246 (match_operand:V8QI 1 "general_operand" ""))]
5247 "TARGET_REALLY_IWMMXT"
5252 ;; load- and store-multiple insns
5253 ;; The arm can load/store any set of registers, provided that they are in
5254 ;; ascending order; but that is beyond GCC so stick with what it knows.
5256 (define_expand "load_multiple"
5257 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5258 (match_operand:SI 1 "" ""))
5259 (use (match_operand:SI 2 "" ""))])]
5262 HOST_WIDE_INT offset = 0;
5264 /* Support only fixed point registers. */
5265 if (GET_CODE (operands[2]) != CONST_INT
5266 || INTVAL (operands[2]) > 14
5267 || INTVAL (operands[2]) < 2
5268 || GET_CODE (operands[1]) != MEM
5269 || GET_CODE (operands[0]) != REG
5270 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5271 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5275 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5276 force_reg (SImode, XEXP (operands[1], 0)),
5277 TRUE, FALSE, operands[1], &offset);
5280 ;; Load multiple with write-back
5282 (define_insn "*ldmsi_postinc4"
5283 [(match_parallel 0 "load_multiple_operation"
5284 [(set (match_operand:SI 1 "s_register_operand" "=r")
5285 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5287 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5288 (mem:SI (match_dup 2)))
5289 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5290 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5291 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5292 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5293 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5294 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5295 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5296 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5297 [(set_attr "type" "load4")
5298 (set_attr "predicable" "yes")]
5301 (define_insn "*ldmsi_postinc4_thumb"
5302 [(match_parallel 0 "load_multiple_operation"
5303 [(set (match_operand:SI 1 "s_register_operand" "=l")
5304 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5306 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5307 (mem:SI (match_dup 2)))
5308 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5309 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5310 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5311 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5312 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5313 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5314 "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
5315 "ldmia\\t%1!, {%3, %4, %5, %6}"
5316 [(set_attr "type" "load4")]
5319 (define_insn "*ldmsi_postinc3"
5320 [(match_parallel 0 "load_multiple_operation"
5321 [(set (match_operand:SI 1 "s_register_operand" "=r")
5322 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5324 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5325 (mem:SI (match_dup 2)))
5326 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5327 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5328 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5329 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5330 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5331 "ldm%?ia\\t%1!, {%3, %4, %5}"
5332 [(set_attr "type" "load3")
5333 (set_attr "predicable" "yes")]
5336 (define_insn "*ldmsi_postinc2"
5337 [(match_parallel 0 "load_multiple_operation"
5338 [(set (match_operand:SI 1 "s_register_operand" "=r")
5339 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5341 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5342 (mem:SI (match_dup 2)))
5343 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5344 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5345 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5346 "ldm%?ia\\t%1!, {%3, %4}"
5347 [(set_attr "type" "load2")
5348 (set_attr "predicable" "yes")]
5351 ;; Ordinary load multiple
5353 (define_insn "*ldmsi4"
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 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5360 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5361 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5362 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5363 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5364 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5365 [(set_attr "type" "load4")
5366 (set_attr "predicable" "yes")]
5369 (define_insn "*ldmsi3"
5370 [(match_parallel 0 "load_multiple_operation"
5371 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5372 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5373 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5374 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5375 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5376 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5377 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5378 "ldm%?ia\\t%1, {%2, %3, %4}"
5379 [(set_attr "type" "load3")
5380 (set_attr "predicable" "yes")]
5383 (define_insn "*ldmsi2"
5384 [(match_parallel 0 "load_multiple_operation"
5385 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5386 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5387 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5388 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5389 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5390 "ldm%?ia\\t%1, {%2, %3}"
5391 [(set_attr "type" "load2")
5392 (set_attr "predicable" "yes")]
5395 (define_expand "store_multiple"
5396 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5397 (match_operand:SI 1 "" ""))
5398 (use (match_operand:SI 2 "" ""))])]
5401 HOST_WIDE_INT offset = 0;
5403 /* Support only fixed point registers. */
5404 if (GET_CODE (operands[2]) != CONST_INT
5405 || INTVAL (operands[2]) > 14
5406 || INTVAL (operands[2]) < 2
5407 || GET_CODE (operands[1]) != REG
5408 || GET_CODE (operands[0]) != MEM
5409 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5410 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5414 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5415 force_reg (SImode, XEXP (operands[0], 0)),
5416 TRUE, FALSE, operands[0], &offset);
5419 ;; Store multiple with write-back
5421 (define_insn "*stmsi_postinc4"
5422 [(match_parallel 0 "store_multiple_operation"
5423 [(set (match_operand:SI 1 "s_register_operand" "=r")
5424 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5426 (set (mem:SI (match_dup 2))
5427 (match_operand:SI 3 "arm_hard_register_operand" ""))
5428 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5429 (match_operand:SI 4 "arm_hard_register_operand" ""))
5430 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5431 (match_operand:SI 5 "arm_hard_register_operand" ""))
5432 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5433 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5434 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5435 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5436 [(set_attr "predicable" "yes")
5437 (set_attr "type" "store4")]
5440 (define_insn "*stmsi_postinc4_thumb"
5441 [(match_parallel 0 "store_multiple_operation"
5442 [(set (match_operand:SI 1 "s_register_operand" "=l")
5443 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5445 (set (mem:SI (match_dup 2))
5446 (match_operand:SI 3 "arm_hard_register_operand" ""))
5447 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5448 (match_operand:SI 4 "arm_hard_register_operand" ""))
5449 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5450 (match_operand:SI 5 "arm_hard_register_operand" ""))
5451 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5452 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5453 "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
5454 "stmia\\t%1!, {%3, %4, %5, %6}"
5455 [(set_attr "type" "store4")]
5458 (define_insn "*stmsi_postinc3"
5459 [(match_parallel 0 "store_multiple_operation"
5460 [(set (match_operand:SI 1 "s_register_operand" "=r")
5461 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5463 (set (mem:SI (match_dup 2))
5464 (match_operand:SI 3 "arm_hard_register_operand" ""))
5465 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5466 (match_operand:SI 4 "arm_hard_register_operand" ""))
5467 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5468 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5469 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5470 "stm%?ia\\t%1!, {%3, %4, %5}"
5471 [(set_attr "predicable" "yes")
5472 (set_attr "type" "store3")]
5475 (define_insn "*stmsi_postinc2"
5476 [(match_parallel 0 "store_multiple_operation"
5477 [(set (match_operand:SI 1 "s_register_operand" "=r")
5478 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5480 (set (mem:SI (match_dup 2))
5481 (match_operand:SI 3 "arm_hard_register_operand" ""))
5482 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5483 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5484 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5485 "stm%?ia\\t%1!, {%3, %4}"
5486 [(set_attr "predicable" "yes")
5487 (set_attr "type" "store2")]
5490 ;; Ordinary store multiple
5492 (define_insn "*stmsi4"
5493 [(match_parallel 0 "store_multiple_operation"
5494 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5495 (match_operand:SI 2 "arm_hard_register_operand" ""))
5496 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5497 (match_operand:SI 3 "arm_hard_register_operand" ""))
5498 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5499 (match_operand:SI 4 "arm_hard_register_operand" ""))
5500 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5501 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5502 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5503 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5504 [(set_attr "predicable" "yes")
5505 (set_attr "type" "store4")]
5508 (define_insn "*stmsi3"
5509 [(match_parallel 0 "store_multiple_operation"
5510 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5511 (match_operand:SI 2 "arm_hard_register_operand" ""))
5512 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5513 (match_operand:SI 3 "arm_hard_register_operand" ""))
5514 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5515 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5516 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5517 "stm%?ia\\t%1, {%2, %3, %4}"
5518 [(set_attr "predicable" "yes")
5519 (set_attr "type" "store3")]
5522 (define_insn "*stmsi2"
5523 [(match_parallel 0 "store_multiple_operation"
5524 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5525 (match_operand:SI 2 "arm_hard_register_operand" ""))
5526 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5527 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5528 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5529 "stm%?ia\\t%1, {%2, %3}"
5530 [(set_attr "predicable" "yes")
5531 (set_attr "type" "store2")]
5534 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5535 ;; We could let this apply for blocks of less than this, but it clobbers so
5536 ;; many registers that there is then probably a better way.
5538 (define_expand "movmemqi"
5539 [(match_operand:BLK 0 "general_operand" "")
5540 (match_operand:BLK 1 "general_operand" "")
5541 (match_operand:SI 2 "const_int_operand" "")
5542 (match_operand:SI 3 "const_int_operand" "")]
5547 if (arm_gen_movmemqi (operands))
5551 else /* TARGET_THUMB */
5553 if ( INTVAL (operands[3]) != 4
5554 || INTVAL (operands[2]) > 48)
5557 thumb_expand_movmemqi (operands);
5563 ;; Thumb block-move insns
5565 (define_insn "movmem12b"
5566 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5567 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5568 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5569 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5570 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5571 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5572 (set (match_operand:SI 0 "register_operand" "=l")
5573 (plus:SI (match_dup 2) (const_int 12)))
5574 (set (match_operand:SI 1 "register_operand" "=l")
5575 (plus:SI (match_dup 3) (const_int 12)))
5576 (clobber (match_scratch:SI 4 "=&l"))
5577 (clobber (match_scratch:SI 5 "=&l"))
5578 (clobber (match_scratch:SI 6 "=&l"))]
5580 "* return thumb_output_move_mem_multiple (3, operands);"
5581 [(set_attr "length" "4")
5582 ; This isn't entirely accurate... It loads as well, but in terms of
5583 ; scheduling the following insn it is better to consider it as a store
5584 (set_attr "type" "store3")]
5587 (define_insn "movmem8b"
5588 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5589 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5590 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5591 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5592 (set (match_operand:SI 0 "register_operand" "=l")
5593 (plus:SI (match_dup 2) (const_int 8)))
5594 (set (match_operand:SI 1 "register_operand" "=l")
5595 (plus:SI (match_dup 3) (const_int 8)))
5596 (clobber (match_scratch:SI 4 "=&l"))
5597 (clobber (match_scratch:SI 5 "=&l"))]
5599 "* return thumb_output_move_mem_multiple (2, operands);"
5600 [(set_attr "length" "4")
5601 ; This isn't entirely accurate... It loads as well, but in terms of
5602 ; scheduling the following insn it is better to consider it as a store
5603 (set_attr "type" "store2")]
5608 ;; Compare & branch insns
5609 ;; The range calculations are based as follows:
5610 ;; For forward branches, the address calculation returns the address of
5611 ;; the next instruction. This is 2 beyond the branch instruction.
5612 ;; For backward branches, the address calculation returns the address of
5613 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5614 ;; instruction for the shortest sequence, and 4 before the branch instruction
5615 ;; if we have to jump around an unconditional branch.
5616 ;; To the basic branch range the PC offset must be added (this is +4).
5617 ;; So for forward branches we have
5618 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5619 ;; And for backward branches we have
5620 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5622 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5623 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5625 (define_expand "cbranchsi4"
5626 [(set (pc) (if_then_else
5627 (match_operator 0 "arm_comparison_operator"
5628 [(match_operand:SI 1 "s_register_operand" "")
5629 (match_operand:SI 2 "nonmemory_operand" "")])
5630 (label_ref (match_operand 3 "" ""))
5634 if (thumb_cmpneg_operand (operands[2], SImode))
5636 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5637 operands[3], operands[0]));
5640 if (!thumb_cmp_operand (operands[2], SImode))
5641 operands[2] = force_reg (SImode, operands[2]);
5644 (define_insn "*cbranchsi4_insn"
5645 [(set (pc) (if_then_else
5646 (match_operator 0 "arm_comparison_operator"
5647 [(match_operand:SI 1 "s_register_operand" "l,*h")
5648 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5649 (label_ref (match_operand 3 "" ""))
5653 output_asm_insn (\"cmp\\t%1, %2\", operands);
5655 switch (get_attr_length (insn))
5657 case 4: return \"b%d0\\t%l3\";
5658 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5659 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5662 [(set (attr "far_jump")
5664 (eq_attr "length" "8")
5665 (const_string "yes")
5666 (const_string "no")))
5667 (set (attr "length")
5669 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5670 (le (minus (match_dup 3) (pc)) (const_int 256)))
5673 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5674 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5679 (define_insn "cbranchsi4_scratch"
5680 [(set (pc) (if_then_else
5681 (match_operator 4 "arm_comparison_operator"
5682 [(match_operand:SI 1 "s_register_operand" "l,0")
5683 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5684 (label_ref (match_operand 3 "" ""))
5686 (clobber (match_scratch:SI 0 "=l,l"))]
5689 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5691 switch (get_attr_length (insn))
5693 case 4: return \"b%d4\\t%l3\";
5694 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5695 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5698 [(set (attr "far_jump")
5700 (eq_attr "length" "8")
5701 (const_string "yes")
5702 (const_string "no")))
5703 (set (attr "length")
5705 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5706 (le (minus (match_dup 3) (pc)) (const_int 256)))
5709 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5710 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5714 (define_insn "*movsi_cbranchsi4"
5717 (match_operator 3 "arm_comparison_operator"
5718 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5720 (label_ref (match_operand 2 "" ""))
5722 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5726 if (which_alternative == 0)
5727 output_asm_insn (\"cmp\t%0, #0\", operands);
5728 else if (which_alternative == 1)
5729 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5732 output_asm_insn (\"cmp\t%1, #0\", operands);
5733 if (which_alternative == 2)
5734 output_asm_insn (\"mov\t%0, %1\", operands);
5736 output_asm_insn (\"str\t%1, %0\", operands);
5738 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5740 case 4: return \"b%d3\\t%l2\";
5741 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5742 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5745 [(set (attr "far_jump")
5747 (ior (and (gt (symbol_ref ("which_alternative"))
5749 (eq_attr "length" "8"))
5750 (eq_attr "length" "10"))
5751 (const_string "yes")
5752 (const_string "no")))
5753 (set (attr "length")
5755 (le (symbol_ref ("which_alternative"))
5758 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5759 (le (minus (match_dup 2) (pc)) (const_int 256)))
5762 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5763 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5767 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5768 (le (minus (match_dup 2) (pc)) (const_int 256)))
5771 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5772 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5777 (define_insn "*negated_cbranchsi4"
5780 (match_operator 0 "arm_comparison_operator"
5781 [(match_operand:SI 1 "s_register_operand" "l")
5782 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5783 (label_ref (match_operand 3 "" ""))
5787 output_asm_insn (\"cmn\\t%1, %2\", operands);
5788 switch (get_attr_length (insn))
5790 case 4: return \"b%d0\\t%l3\";
5791 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5792 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5795 [(set (attr "far_jump")
5797 (eq_attr "length" "8")
5798 (const_string "yes")
5799 (const_string "no")))
5800 (set (attr "length")
5802 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5803 (le (minus (match_dup 3) (pc)) (const_int 256)))
5806 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5807 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5812 (define_insn "*tbit_cbranch"
5815 (match_operator 0 "equality_operator"
5816 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5818 (match_operand:SI 2 "const_int_operand" "i"))
5820 (label_ref (match_operand 3 "" ""))
5822 (clobber (match_scratch:SI 4 "=l"))]
5827 op[0] = operands[4];
5828 op[1] = operands[1];
5829 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5831 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5832 switch (get_attr_length (insn))
5834 case 4: return \"b%d0\\t%l3\";
5835 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5836 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5839 [(set (attr "far_jump")
5841 (eq_attr "length" "8")
5842 (const_string "yes")
5843 (const_string "no")))
5844 (set (attr "length")
5846 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5847 (le (minus (match_dup 3) (pc)) (const_int 256)))
5850 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5851 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5856 (define_insn "*tstsi3_cbranch"
5859 (match_operator 3 "equality_operator"
5860 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5861 (match_operand:SI 1 "s_register_operand" "l"))
5863 (label_ref (match_operand 2 "" ""))
5868 output_asm_insn (\"tst\\t%0, %1\", operands);
5869 switch (get_attr_length (insn))
5871 case 4: return \"b%d3\\t%l2\";
5872 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5873 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5876 [(set (attr "far_jump")
5878 (eq_attr "length" "8")
5879 (const_string "yes")
5880 (const_string "no")))
5881 (set (attr "length")
5883 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5884 (le (minus (match_dup 2) (pc)) (const_int 256)))
5887 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5888 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5893 (define_insn "*andsi3_cbranch"
5896 (match_operator 5 "equality_operator"
5897 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5898 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5900 (label_ref (match_operand 4 "" ""))
5902 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5903 (and:SI (match_dup 2) (match_dup 3)))
5904 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5908 if (which_alternative == 0)
5909 output_asm_insn (\"and\\t%0, %3\", operands);
5910 else if (which_alternative == 1)
5912 output_asm_insn (\"and\\t%1, %3\", operands);
5913 output_asm_insn (\"mov\\t%0, %1\", operands);
5917 output_asm_insn (\"and\\t%1, %3\", operands);
5918 output_asm_insn (\"str\\t%1, %0\", operands);
5921 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5923 case 4: return \"b%d5\\t%l4\";
5924 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5925 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5928 [(set (attr "far_jump")
5930 (ior (and (eq (symbol_ref ("which_alternative"))
5932 (eq_attr "length" "8"))
5933 (eq_attr "length" "10"))
5934 (const_string "yes")
5935 (const_string "no")))
5936 (set (attr "length")
5938 (eq (symbol_ref ("which_alternative"))
5941 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5942 (le (minus (match_dup 4) (pc)) (const_int 256)))
5945 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
5946 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5950 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
5951 (le (minus (match_dup 4) (pc)) (const_int 256)))
5954 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
5955 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5960 (define_insn "*orrsi3_cbranch_scratch"
5963 (match_operator 4 "equality_operator"
5964 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
5965 (match_operand:SI 2 "s_register_operand" "l"))
5967 (label_ref (match_operand 3 "" ""))
5969 (clobber (match_scratch:SI 0 "=l"))]
5973 output_asm_insn (\"orr\\t%0, %2\", operands);
5974 switch (get_attr_length (insn))
5976 case 4: return \"b%d4\\t%l3\";
5977 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5978 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5981 [(set (attr "far_jump")
5983 (eq_attr "length" "8")
5984 (const_string "yes")
5985 (const_string "no")))
5986 (set (attr "length")
5988 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5989 (le (minus (match_dup 3) (pc)) (const_int 256)))
5992 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5993 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5998 (define_insn "*orrsi3_cbranch"
6001 (match_operator 5 "equality_operator"
6002 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6003 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6005 (label_ref (match_operand 4 "" ""))
6007 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6008 (ior:SI (match_dup 2) (match_dup 3)))
6009 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6013 if (which_alternative == 0)
6014 output_asm_insn (\"orr\\t%0, %3\", operands);
6015 else if (which_alternative == 1)
6017 output_asm_insn (\"orr\\t%1, %3\", operands);
6018 output_asm_insn (\"mov\\t%0, %1\", operands);
6022 output_asm_insn (\"orr\\t%1, %3\", operands);
6023 output_asm_insn (\"str\\t%1, %0\", operands);
6026 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6028 case 4: return \"b%d5\\t%l4\";
6029 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6030 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6033 [(set (attr "far_jump")
6035 (ior (and (eq (symbol_ref ("which_alternative"))
6037 (eq_attr "length" "8"))
6038 (eq_attr "length" "10"))
6039 (const_string "yes")
6040 (const_string "no")))
6041 (set (attr "length")
6043 (eq (symbol_ref ("which_alternative"))
6046 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6047 (le (minus (match_dup 4) (pc)) (const_int 256)))
6050 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6051 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6055 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6056 (le (minus (match_dup 4) (pc)) (const_int 256)))
6059 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6060 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6065 (define_insn "*xorsi3_cbranch_scratch"
6068 (match_operator 4 "equality_operator"
6069 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6070 (match_operand:SI 2 "s_register_operand" "l"))
6072 (label_ref (match_operand 3 "" ""))
6074 (clobber (match_scratch:SI 0 "=l"))]
6078 output_asm_insn (\"eor\\t%0, %2\", operands);
6079 switch (get_attr_length (insn))
6081 case 4: return \"b%d4\\t%l3\";
6082 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6083 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6086 [(set (attr "far_jump")
6088 (eq_attr "length" "8")
6089 (const_string "yes")
6090 (const_string "no")))
6091 (set (attr "length")
6093 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6094 (le (minus (match_dup 3) (pc)) (const_int 256)))
6097 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6098 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6103 (define_insn "*xorsi3_cbranch"
6106 (match_operator 5 "equality_operator"
6107 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6108 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6110 (label_ref (match_operand 4 "" ""))
6112 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6113 (xor:SI (match_dup 2) (match_dup 3)))
6114 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6118 if (which_alternative == 0)
6119 output_asm_insn (\"eor\\t%0, %3\", operands);
6120 else if (which_alternative == 1)
6122 output_asm_insn (\"eor\\t%1, %3\", operands);
6123 output_asm_insn (\"mov\\t%0, %1\", operands);
6127 output_asm_insn (\"eor\\t%1, %3\", operands);
6128 output_asm_insn (\"str\\t%1, %0\", operands);
6131 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6133 case 4: return \"b%d5\\t%l4\";
6134 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6135 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6138 [(set (attr "far_jump")
6140 (ior (and (eq (symbol_ref ("which_alternative"))
6142 (eq_attr "length" "8"))
6143 (eq_attr "length" "10"))
6144 (const_string "yes")
6145 (const_string "no")))
6146 (set (attr "length")
6148 (eq (symbol_ref ("which_alternative"))
6151 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6152 (le (minus (match_dup 4) (pc)) (const_int 256)))
6155 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6156 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6160 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6161 (le (minus (match_dup 4) (pc)) (const_int 256)))
6164 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6165 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6170 (define_insn "*bicsi3_cbranch_scratch"
6173 (match_operator 4 "equality_operator"
6174 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6175 (match_operand:SI 1 "s_register_operand" "0"))
6177 (label_ref (match_operand 3 "" ""))
6179 (clobber (match_scratch:SI 0 "=l"))]
6183 output_asm_insn (\"bic\\t%0, %2\", operands);
6184 switch (get_attr_length (insn))
6186 case 4: return \"b%d4\\t%l3\";
6187 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6188 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6191 [(set (attr "far_jump")
6193 (eq_attr "length" "8")
6194 (const_string "yes")
6195 (const_string "no")))
6196 (set (attr "length")
6198 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6199 (le (minus (match_dup 3) (pc)) (const_int 256)))
6202 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6203 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6208 (define_insn "*bicsi3_cbranch"
6211 (match_operator 5 "equality_operator"
6212 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
6213 (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
6215 (label_ref (match_operand 4 "" ""))
6217 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
6218 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6219 (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
6223 if (which_alternative == 0)
6224 output_asm_insn (\"bic\\t%0, %3\", operands);
6225 else if (which_alternative <= 2)
6227 output_asm_insn (\"bic\\t%1, %3\", operands);
6228 /* It's ok if OP0 is a lo-reg, even though the mov will set the
6229 conditions again, since we're only testing for equality. */
6230 output_asm_insn (\"mov\\t%0, %1\", operands);
6234 output_asm_insn (\"bic\\t%1, %3\", operands);
6235 output_asm_insn (\"str\\t%1, %0\", operands);
6238 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6240 case 4: return \"b%d5\\t%l4\";
6241 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6242 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6245 [(set (attr "far_jump")
6247 (ior (and (eq (symbol_ref ("which_alternative"))
6249 (eq_attr "length" "8"))
6250 (eq_attr "length" "10"))
6251 (const_string "yes")
6252 (const_string "no")))
6253 (set (attr "length")
6255 (eq (symbol_ref ("which_alternative"))
6258 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6259 (le (minus (match_dup 4) (pc)) (const_int 256)))
6262 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6263 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6267 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6268 (le (minus (match_dup 4) (pc)) (const_int 256)))
6271 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6272 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6277 (define_insn "*cbranchne_decr1"
6279 (if_then_else (match_operator 3 "equality_operator"
6280 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6282 (label_ref (match_operand 4 "" ""))
6284 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6285 (plus:SI (match_dup 2) (const_int -1)))
6286 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6291 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6293 VOIDmode, operands[2], const1_rtx);
6294 cond[1] = operands[4];
6296 if (which_alternative == 0)
6297 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6298 else if (which_alternative == 1)
6300 /* We must provide an alternative for a hi reg because reload
6301 cannot handle output reloads on a jump instruction, but we
6302 can't subtract into that. Fortunately a mov from lo to hi
6303 does not clobber the condition codes. */
6304 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6305 output_asm_insn (\"mov\\t%0, %1\", operands);
6309 /* Similarly, but the target is memory. */
6310 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6311 output_asm_insn (\"str\\t%1, %0\", operands);
6314 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6317 output_asm_insn (\"b%d0\\t%l1\", cond);
6320 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6321 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6323 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6324 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6328 [(set (attr "far_jump")
6330 (ior (and (eq (symbol_ref ("which_alternative"))
6332 (eq_attr "length" "8"))
6333 (eq_attr "length" "10"))
6334 (const_string "yes")
6335 (const_string "no")))
6336 (set_attr_alternative "length"
6340 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6341 (le (minus (match_dup 4) (pc)) (const_int 256)))
6344 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6345 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6350 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6351 (le (minus (match_dup 4) (pc)) (const_int 256)))
6354 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6355 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6360 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6361 (le (minus (match_dup 4) (pc)) (const_int 256)))
6364 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6365 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6370 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6371 (le (minus (match_dup 4) (pc)) (const_int 256)))
6374 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6375 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6380 (define_insn "*addsi3_cbranch"
6383 (match_operator 4 "comparison_operator"
6385 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6386 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6388 (label_ref (match_operand 5 "" ""))
6391 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6392 (plus:SI (match_dup 2) (match_dup 3)))
6393 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6395 && (GET_CODE (operands[4]) == EQ
6396 || GET_CODE (operands[4]) == NE
6397 || GET_CODE (operands[4]) == GE
6398 || GET_CODE (operands[4]) == LT)"
6404 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6405 cond[1] = operands[2];
6406 cond[2] = operands[3];
6408 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6409 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6411 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6413 if (which_alternative >= 3
6414 && which_alternative < 4)
6415 output_asm_insn (\"mov\\t%0, %1\", operands);
6416 else if (which_alternative >= 4)
6417 output_asm_insn (\"str\\t%1, %0\", operands);
6419 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6422 return \"b%d4\\t%l5\";
6424 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6426 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6430 [(set (attr "far_jump")
6432 (ior (and (lt (symbol_ref ("which_alternative"))
6434 (eq_attr "length" "8"))
6435 (eq_attr "length" "10"))
6436 (const_string "yes")
6437 (const_string "no")))
6438 (set (attr "length")
6440 (lt (symbol_ref ("which_alternative"))
6443 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6444 (le (minus (match_dup 5) (pc)) (const_int 256)))
6447 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6448 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6452 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6453 (le (minus (match_dup 5) (pc)) (const_int 256)))
6456 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6457 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6462 (define_insn "*addsi3_cbranch_scratch"
6465 (match_operator 3 "comparison_operator"
6467 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6468 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
6470 (label_ref (match_operand 4 "" ""))
6472 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6474 && (GET_CODE (operands[3]) == EQ
6475 || GET_CODE (operands[3]) == NE
6476 || GET_CODE (operands[3]) == GE
6477 || GET_CODE (operands[3]) == LT)"
6480 switch (which_alternative)
6483 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6486 output_asm_insn (\"cmn\t%1, %2\", operands);
6489 if (INTVAL (operands[2]) < 0)
6490 output_asm_insn (\"sub\t%0, %1, %2\", operands);
6492 output_asm_insn (\"add\t%0, %1, %2\", operands);
6495 if (INTVAL (operands[2]) < 0)
6496 output_asm_insn (\"sub\t%0, %0, %2\", operands);
6498 output_asm_insn (\"add\t%0, %0, %2\", operands);
6502 switch (get_attr_length (insn))
6505 return \"b%d3\\t%l4\";
6507 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6509 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6513 [(set (attr "far_jump")
6515 (eq_attr "length" "8")
6516 (const_string "yes")
6517 (const_string "no")))
6518 (set (attr "length")
6520 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6521 (le (minus (match_dup 4) (pc)) (const_int 256)))
6524 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6525 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6530 (define_insn "*subsi3_cbranch"
6533 (match_operator 4 "comparison_operator"
6535 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6536 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6538 (label_ref (match_operand 5 "" ""))
6540 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6541 (minus:SI (match_dup 2) (match_dup 3)))
6542 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6544 && (GET_CODE (operands[4]) == EQ
6545 || GET_CODE (operands[4]) == NE
6546 || GET_CODE (operands[4]) == GE
6547 || GET_CODE (operands[4]) == LT)"
6550 if (which_alternative == 0)
6551 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6552 else if (which_alternative == 1)
6554 /* We must provide an alternative for a hi reg because reload
6555 cannot handle output reloads on a jump instruction, but we
6556 can't subtract into that. Fortunately a mov from lo to hi
6557 does not clobber the condition codes. */
6558 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6559 output_asm_insn (\"mov\\t%0, %1\", operands);
6563 /* Similarly, but the target is memory. */
6564 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6565 output_asm_insn (\"str\\t%1, %0\", operands);
6568 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6571 return \"b%d4\\t%l5\";
6573 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6575 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6579 [(set (attr "far_jump")
6581 (ior (and (eq (symbol_ref ("which_alternative"))
6583 (eq_attr "length" "8"))
6584 (eq_attr "length" "10"))
6585 (const_string "yes")
6586 (const_string "no")))
6587 (set (attr "length")
6589 (eq (symbol_ref ("which_alternative"))
6592 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6593 (le (minus (match_dup 5) (pc)) (const_int 256)))
6596 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6597 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6601 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6602 (le (minus (match_dup 5) (pc)) (const_int 256)))
6605 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6606 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6611 (define_insn "*subsi3_cbranch_scratch"
6614 (match_operator 0 "arm_comparison_operator"
6615 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6616 (match_operand:SI 2 "nonmemory_operand" "l"))
6618 (label_ref (match_operand 3 "" ""))
6621 && (GET_CODE (operands[0]) == EQ
6622 || GET_CODE (operands[0]) == NE
6623 || GET_CODE (operands[0]) == GE
6624 || GET_CODE (operands[0]) == LT)"
6626 output_asm_insn (\"cmp\\t%1, %2\", operands);
6627 switch (get_attr_length (insn))
6629 case 4: return \"b%d0\\t%l3\";
6630 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6631 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6634 [(set (attr "far_jump")
6636 (eq_attr "length" "8")
6637 (const_string "yes")
6638 (const_string "no")))
6639 (set (attr "length")
6641 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6642 (le (minus (match_dup 3) (pc)) (const_int 256)))
6645 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6646 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6651 ;; Comparison and test insns
6653 (define_expand "cmpsi"
6654 [(match_operand:SI 0 "s_register_operand" "")
6655 (match_operand:SI 1 "arm_add_operand" "")]
6658 arm_compare_op0 = operands[0];
6659 arm_compare_op1 = operands[1];
6664 (define_expand "cmpsf"
6665 [(match_operand:SF 0 "s_register_operand" "")
6666 (match_operand:SF 1 "arm_float_compare_operand" "")]
6667 "TARGET_ARM && TARGET_HARD_FLOAT"
6669 arm_compare_op0 = operands[0];
6670 arm_compare_op1 = operands[1];
6675 (define_expand "cmpdf"
6676 [(match_operand:DF 0 "s_register_operand" "")
6677 (match_operand:DF 1 "arm_float_compare_operand" "")]
6678 "TARGET_ARM && TARGET_HARD_FLOAT"
6680 arm_compare_op0 = operands[0];
6681 arm_compare_op1 = operands[1];
6686 (define_insn "*arm_cmpsi_insn"
6687 [(set (reg:CC CC_REGNUM)
6688 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6689 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6694 [(set_attr "conds" "set")]
6697 (define_insn "*cmpsi_shiftsi"
6698 [(set (reg:CC CC_REGNUM)
6699 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6700 (match_operator:SI 3 "shift_operator"
6701 [(match_operand:SI 1 "s_register_operand" "r")
6702 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6705 [(set_attr "conds" "set")
6706 (set_attr "shift" "1")
6707 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6708 (const_string "alu_shift")
6709 (const_string "alu_shift_reg")))]
6712 (define_insn "*cmpsi_shiftsi_swp"
6713 [(set (reg:CC_SWP CC_REGNUM)
6714 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6715 [(match_operand:SI 1 "s_register_operand" "r")
6716 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6717 (match_operand:SI 0 "s_register_operand" "r")))]
6720 [(set_attr "conds" "set")
6721 (set_attr "shift" "1")
6722 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6723 (const_string "alu_shift")
6724 (const_string "alu_shift_reg")))]
6727 (define_insn "*cmpsi_neg_shiftsi"
6728 [(set (reg:CC CC_REGNUM)
6729 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6730 (neg:SI (match_operator:SI 3 "shift_operator"
6731 [(match_operand:SI 1 "s_register_operand" "r")
6732 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
6735 [(set_attr "conds" "set")
6736 (set_attr "shift" "1")
6737 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6738 (const_string "alu_shift")
6739 (const_string "alu_shift_reg")))]
6742 ;; Cirrus SF compare instruction
6743 (define_insn "*cirrus_cmpsf"
6744 [(set (reg:CCFP CC_REGNUM)
6745 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6746 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6747 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6748 "cfcmps%?\\tr15, %V0, %V1"
6749 [(set_attr "type" "mav_farith")
6750 (set_attr "cirrus" "compare")]
6753 ;; Cirrus DF compare instruction
6754 (define_insn "*cirrus_cmpdf"
6755 [(set (reg:CCFP CC_REGNUM)
6756 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6757 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6758 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6759 "cfcmpd%?\\tr15, %V0, %V1"
6760 [(set_attr "type" "mav_farith")
6761 (set_attr "cirrus" "compare")]
6764 ;; Cirrus DI compare instruction
6765 (define_expand "cmpdi"
6766 [(match_operand:DI 0 "cirrus_fp_register" "")
6767 (match_operand:DI 1 "cirrus_fp_register" "")]
6768 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6770 arm_compare_op0 = operands[0];
6771 arm_compare_op1 = operands[1];
6775 (define_insn "*cirrus_cmpdi"
6776 [(set (reg:CC CC_REGNUM)
6777 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6778 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6779 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6780 "cfcmp64%?\\tr15, %V0, %V1"
6781 [(set_attr "type" "mav_farith")
6782 (set_attr "cirrus" "compare")]
6785 ; This insn allows redundant compares to be removed by cse, nothing should
6786 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6787 ; is deleted later on. The match_dup will match the mode here, so that
6788 ; mode changes of the condition codes aren't lost by this even though we don't
6789 ; specify what they are.
6791 (define_insn "*deleted_compare"
6792 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6794 "\\t%@ deleted compare"
6795 [(set_attr "conds" "set")
6796 (set_attr "length" "0")]
6800 ;; Conditional branch insns
6802 (define_expand "beq"
6804 (if_then_else (eq (match_dup 1) (const_int 0))
6805 (label_ref (match_operand 0 "" ""))
6808 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6811 (define_expand "bne"
6813 (if_then_else (ne (match_dup 1) (const_int 0))
6814 (label_ref (match_operand 0 "" ""))
6817 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6820 (define_expand "bgt"
6822 (if_then_else (gt (match_dup 1) (const_int 0))
6823 (label_ref (match_operand 0 "" ""))
6826 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6829 (define_expand "ble"
6831 (if_then_else (le (match_dup 1) (const_int 0))
6832 (label_ref (match_operand 0 "" ""))
6835 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6838 (define_expand "bge"
6840 (if_then_else (ge (match_dup 1) (const_int 0))
6841 (label_ref (match_operand 0 "" ""))
6844 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6847 (define_expand "blt"
6849 (if_then_else (lt (match_dup 1) (const_int 0))
6850 (label_ref (match_operand 0 "" ""))
6853 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6856 (define_expand "bgtu"
6858 (if_then_else (gtu (match_dup 1) (const_int 0))
6859 (label_ref (match_operand 0 "" ""))
6862 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6865 (define_expand "bleu"
6867 (if_then_else (leu (match_dup 1) (const_int 0))
6868 (label_ref (match_operand 0 "" ""))
6871 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6874 (define_expand "bgeu"
6876 (if_then_else (geu (match_dup 1) (const_int 0))
6877 (label_ref (match_operand 0 "" ""))
6880 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6883 (define_expand "bltu"
6885 (if_then_else (ltu (match_dup 1) (const_int 0))
6886 (label_ref (match_operand 0 "" ""))
6889 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6892 (define_expand "bunordered"
6894 (if_then_else (unordered (match_dup 1) (const_int 0))
6895 (label_ref (match_operand 0 "" ""))
6897 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6898 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6902 (define_expand "bordered"
6904 (if_then_else (ordered (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 (ORDERED, arm_compare_op0,
6912 (define_expand "bungt"
6914 (if_then_else (ungt (match_dup 1) (const_int 0))
6915 (label_ref (match_operand 0 "" ""))
6917 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6918 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
6921 (define_expand "bunlt"
6923 (if_then_else (unlt (match_dup 1) (const_int 0))
6924 (label_ref (match_operand 0 "" ""))
6926 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6927 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6930 (define_expand "bunge"
6932 (if_then_else (unge (match_dup 1) (const_int 0))
6933 (label_ref (match_operand 0 "" ""))
6935 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6936 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6939 (define_expand "bunle"
6941 (if_then_else (unle (match_dup 1) (const_int 0))
6942 (label_ref (match_operand 0 "" ""))
6944 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6945 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
6948 ;; The following two patterns need two branch instructions, since there is
6949 ;; no single instruction that will handle all cases.
6950 (define_expand "buneq"
6952 (if_then_else (uneq (match_dup 1) (const_int 0))
6953 (label_ref (match_operand 0 "" ""))
6955 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6956 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
6959 (define_expand "bltgt"
6961 (if_then_else (ltgt (match_dup 1) (const_int 0))
6962 (label_ref (match_operand 0 "" ""))
6964 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6965 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
6969 ;; Patterns to match conditional branch insns.
6972 ; Special pattern to match UNEQ.
6973 (define_insn "*arm_buneq"
6975 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6976 (label_ref (match_operand 0 "" ""))
6978 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6980 if (arm_ccfsm_state != 0)
6983 return \"bvs\\t%l0\;beq\\t%l0\";
6985 [(set_attr "conds" "jump_clob")
6986 (set_attr "length" "8")]
6989 ; Special pattern to match LTGT.
6990 (define_insn "*arm_bltgt"
6992 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
6993 (label_ref (match_operand 0 "" ""))
6995 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6997 if (arm_ccfsm_state != 0)
7000 return \"bmi\\t%l0\;bgt\\t%l0\";
7002 [(set_attr "conds" "jump_clob")
7003 (set_attr "length" "8")]
7006 (define_insn "*arm_cond_branch"
7008 (if_then_else (match_operator 1 "arm_comparison_operator"
7009 [(match_operand 2 "cc_register" "") (const_int 0)])
7010 (label_ref (match_operand 0 "" ""))
7014 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7016 arm_ccfsm_state += 2;
7019 return \"b%d1\\t%l0\";
7021 [(set_attr "conds" "use")
7022 (set_attr "type" "branch")]
7025 ; Special pattern to match reversed UNEQ.
7026 (define_insn "*arm_buneq_reversed"
7028 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7030 (label_ref (match_operand 0 "" ""))))]
7031 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7033 if (arm_ccfsm_state != 0)
7036 return \"bmi\\t%l0\;bgt\\t%l0\";
7038 [(set_attr "conds" "jump_clob")
7039 (set_attr "length" "8")]
7042 ; Special pattern to match reversed LTGT.
7043 (define_insn "*arm_bltgt_reversed"
7045 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7047 (label_ref (match_operand 0 "" ""))))]
7048 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7050 if (arm_ccfsm_state != 0)
7053 return \"bvs\\t%l0\;beq\\t%l0\";
7055 [(set_attr "conds" "jump_clob")
7056 (set_attr "length" "8")]
7059 (define_insn "*arm_cond_branch_reversed"
7061 (if_then_else (match_operator 1 "arm_comparison_operator"
7062 [(match_operand 2 "cc_register" "") (const_int 0)])
7064 (label_ref (match_operand 0 "" ""))))]
7067 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7069 arm_ccfsm_state += 2;
7072 return \"b%D1\\t%l0\";
7074 [(set_attr "conds" "use")
7075 (set_attr "type" "branch")]
7082 (define_expand "seq"
7083 [(set (match_operand:SI 0 "s_register_operand" "")
7084 (eq:SI (match_dup 1) (const_int 0)))]
7086 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7089 (define_expand "sne"
7090 [(set (match_operand:SI 0 "s_register_operand" "")
7091 (ne:SI (match_dup 1) (const_int 0)))]
7093 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7096 (define_expand "sgt"
7097 [(set (match_operand:SI 0 "s_register_operand" "")
7098 (gt:SI (match_dup 1) (const_int 0)))]
7100 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7103 (define_expand "sle"
7104 [(set (match_operand:SI 0 "s_register_operand" "")
7105 (le:SI (match_dup 1) (const_int 0)))]
7107 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7110 (define_expand "sge"
7111 [(set (match_operand:SI 0 "s_register_operand" "")
7112 (ge:SI (match_dup 1) (const_int 0)))]
7114 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7117 (define_expand "slt"
7118 [(set (match_operand:SI 0 "s_register_operand" "")
7119 (lt:SI (match_dup 1) (const_int 0)))]
7121 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7124 (define_expand "sgtu"
7125 [(set (match_operand:SI 0 "s_register_operand" "")
7126 (gtu:SI (match_dup 1) (const_int 0)))]
7128 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7131 (define_expand "sleu"
7132 [(set (match_operand:SI 0 "s_register_operand" "")
7133 (leu:SI (match_dup 1) (const_int 0)))]
7135 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7138 (define_expand "sgeu"
7139 [(set (match_operand:SI 0 "s_register_operand" "")
7140 (geu:SI (match_dup 1) (const_int 0)))]
7142 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7145 (define_expand "sltu"
7146 [(set (match_operand:SI 0 "s_register_operand" "")
7147 (ltu:SI (match_dup 1) (const_int 0)))]
7149 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7152 (define_expand "sunordered"
7153 [(set (match_operand:SI 0 "s_register_operand" "")
7154 (unordered:SI (match_dup 1) (const_int 0)))]
7155 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7156 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7160 (define_expand "sordered"
7161 [(set (match_operand:SI 0 "s_register_operand" "")
7162 (ordered:SI (match_dup 1) (const_int 0)))]
7163 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7164 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7168 (define_expand "sungt"
7169 [(set (match_operand:SI 0 "s_register_operand" "")
7170 (ungt:SI (match_dup 1) (const_int 0)))]
7171 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7172 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7176 (define_expand "sunge"
7177 [(set (match_operand:SI 0 "s_register_operand" "")
7178 (unge:SI (match_dup 1) (const_int 0)))]
7179 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7180 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7184 (define_expand "sunlt"
7185 [(set (match_operand:SI 0 "s_register_operand" "")
7186 (unlt:SI (match_dup 1) (const_int 0)))]
7187 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7188 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7192 (define_expand "sunle"
7193 [(set (match_operand:SI 0 "s_register_operand" "")
7194 (unle:SI (match_dup 1) (const_int 0)))]
7195 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7196 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7200 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7201 ;;; simple ARM instructions.
7203 ; (define_expand "suneq"
7204 ; [(set (match_operand:SI 0 "s_register_operand" "")
7205 ; (uneq:SI (match_dup 1) (const_int 0)))]
7206 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7210 ; (define_expand "sltgt"
7211 ; [(set (match_operand:SI 0 "s_register_operand" "")
7212 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7213 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7217 (define_insn "*mov_scc"
7218 [(set (match_operand:SI 0 "s_register_operand" "=r")
7219 (match_operator:SI 1 "arm_comparison_operator"
7220 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7222 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7223 [(set_attr "conds" "use")
7224 (set_attr "length" "8")]
7227 (define_insn "*mov_negscc"
7228 [(set (match_operand:SI 0 "s_register_operand" "=r")
7229 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7230 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7232 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7233 [(set_attr "conds" "use")
7234 (set_attr "length" "8")]
7237 (define_insn "*mov_notscc"
7238 [(set (match_operand:SI 0 "s_register_operand" "=r")
7239 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7240 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7242 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7243 [(set_attr "conds" "use")
7244 (set_attr "length" "8")]
7248 ;; Conditional move insns
7250 (define_expand "movsicc"
7251 [(set (match_operand:SI 0 "s_register_operand" "")
7252 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7253 (match_operand:SI 2 "arm_not_operand" "")
7254 (match_operand:SI 3 "arm_not_operand" "")))]
7258 enum rtx_code code = GET_CODE (operands[1]);
7261 if (code == UNEQ || code == LTGT)
7264 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7265 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7269 (define_expand "movsfcc"
7270 [(set (match_operand:SF 0 "s_register_operand" "")
7271 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7272 (match_operand:SF 2 "s_register_operand" "")
7273 (match_operand:SF 3 "nonmemory_operand" "")))]
7277 enum rtx_code code = GET_CODE (operands[1]);
7280 if (code == UNEQ || code == LTGT)
7283 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7284 Otherwise, ensure it is a valid FP add operand */
7285 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7286 || (!arm_float_add_operand (operands[3], SFmode)))
7287 operands[3] = force_reg (SFmode, operands[3]);
7289 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7290 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7294 (define_expand "movdfcc"
7295 [(set (match_operand:DF 0 "s_register_operand" "")
7296 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7297 (match_operand:DF 2 "s_register_operand" "")
7298 (match_operand:DF 3 "arm_float_add_operand" "")))]
7299 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7302 enum rtx_code code = GET_CODE (operands[1]);
7305 if (code == UNEQ || code == LTGT)
7308 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7309 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7313 (define_insn "*movsicc_insn"
7314 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7316 (match_operator 3 "arm_comparison_operator"
7317 [(match_operand 4 "cc_register" "") (const_int 0)])
7318 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7319 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7326 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7327 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7328 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7329 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7330 [(set_attr "length" "4,4,4,4,8,8,8,8")
7331 (set_attr "conds" "use")]
7334 (define_insn "*movsfcc_soft_insn"
7335 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7336 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7337 [(match_operand 4 "cc_register" "") (const_int 0)])
7338 (match_operand:SF 1 "s_register_operand" "0,r")
7339 (match_operand:SF 2 "s_register_operand" "r,0")))]
7340 "TARGET_ARM && TARGET_SOFT_FLOAT"
7344 [(set_attr "conds" "use")]
7348 ;; Jump and linkage insns
7350 (define_expand "jump"
7352 (label_ref (match_operand 0 "" "")))]
7357 (define_insn "*arm_jump"
7359 (label_ref (match_operand 0 "" "")))]
7363 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7365 arm_ccfsm_state += 2;
7368 return \"b%?\\t%l0\";
7371 [(set_attr "predicable" "yes")]
7374 (define_insn "*thumb_jump"
7376 (label_ref (match_operand 0 "" "")))]
7379 if (get_attr_length (insn) == 2)
7381 return \"bl\\t%l0\\t%@ far jump\";
7383 [(set (attr "far_jump")
7385 (eq_attr "length" "4")
7386 (const_string "yes")
7387 (const_string "no")))
7388 (set (attr "length")
7390 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7391 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7396 (define_expand "call"
7397 [(parallel [(call (match_operand 0 "memory_operand" "")
7398 (match_operand 1 "general_operand" ""))
7399 (use (match_operand 2 "" ""))
7400 (clobber (reg:SI LR_REGNUM))])]
7406 /* In an untyped call, we can get NULL for operand 2. */
7407 if (operands[2] == NULL_RTX)
7408 operands[2] = const0_rtx;
7410 /* This is to decide if we should generate indirect calls by loading the
7411 32 bit address of the callee into a register before performing the
7412 branch and link. operand[2] encodes the long_call/short_call
7413 attribute of the function being called. This attribute is set whenever
7414 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7415 is used, and the short_call attribute can also be set if function is
7416 declared as static or if it has already been defined in the current
7417 compilation unit. See arm.c and arm.h for info about this. The third
7418 parameter to arm_is_longcall_p is used to tell it which pattern
7420 callee = XEXP (operands[0], 0);
7422 if (GET_CODE (callee) != REG
7423 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7424 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7428 (define_insn "*call_reg_armv5"
7429 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7430 (match_operand 1 "" ""))
7431 (use (match_operand 2 "" ""))
7432 (clobber (reg:SI LR_REGNUM))]
7433 "TARGET_ARM && arm_arch5"
7435 [(set_attr "type" "call")]
7438 (define_insn "*call_reg_arm"
7439 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7440 (match_operand 1 "" ""))
7441 (use (match_operand 2 "" ""))
7442 (clobber (reg:SI LR_REGNUM))]
7443 "TARGET_ARM && !arm_arch5"
7445 return output_call (operands);
7447 ;; length is worst case, normally it is only two
7448 [(set_attr "length" "12")
7449 (set_attr "type" "call")]
7452 (define_insn "*call_mem"
7453 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7454 (match_operand 1 "" ""))
7455 (use (match_operand 2 "" ""))
7456 (clobber (reg:SI LR_REGNUM))]
7459 return output_call_mem (operands);
7461 [(set_attr "length" "12")
7462 (set_attr "type" "call")]
7465 (define_insn "*call_reg_thumb_v5"
7466 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7467 (match_operand 1 "" ""))
7468 (use (match_operand 2 "" ""))
7469 (clobber (reg:SI LR_REGNUM))]
7470 "TARGET_THUMB && arm_arch5"
7472 [(set_attr "length" "2")
7473 (set_attr "type" "call")]
7476 (define_insn "*call_reg_thumb"
7477 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7478 (match_operand 1 "" ""))
7479 (use (match_operand 2 "" ""))
7480 (clobber (reg:SI LR_REGNUM))]
7481 "TARGET_THUMB && !arm_arch5"
7484 if (!TARGET_CALLER_INTERWORKING)
7485 return thumb_call_via_reg (operands[0]);
7486 else if (operands[1] == const0_rtx)
7487 return \"bl\\t%__interwork_call_via_%0\";
7488 else if (frame_pointer_needed)
7489 return \"bl\\t%__interwork_r7_call_via_%0\";
7491 return \"bl\\t%__interwork_r11_call_via_%0\";
7493 [(set_attr "type" "call")]
7496 (define_expand "call_value"
7497 [(parallel [(set (match_operand 0 "" "")
7498 (call (match_operand 1 "memory_operand" "")
7499 (match_operand 2 "general_operand" "")))
7500 (use (match_operand 3 "" ""))
7501 (clobber (reg:SI LR_REGNUM))])]
7505 rtx callee = XEXP (operands[1], 0);
7507 /* In an untyped call, we can get NULL for operand 2. */
7508 if (operands[3] == 0)
7509 operands[3] = const0_rtx;
7511 /* See the comment in define_expand \"call\". */
7512 if (GET_CODE (callee) != REG
7513 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7514 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7518 (define_insn "*call_value_reg_armv5"
7519 [(set (match_operand 0 "" "")
7520 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7521 (match_operand 2 "" "")))
7522 (use (match_operand 3 "" ""))
7523 (clobber (reg:SI LR_REGNUM))]
7524 "TARGET_ARM && arm_arch5"
7526 [(set_attr "type" "call")]
7529 (define_insn "*call_value_reg_arm"
7530 [(set (match_operand 0 "" "")
7531 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7532 (match_operand 2 "" "")))
7533 (use (match_operand 3 "" ""))
7534 (clobber (reg:SI LR_REGNUM))]
7535 "TARGET_ARM && !arm_arch5"
7537 return output_call (&operands[1]);
7539 [(set_attr "length" "12")
7540 (set_attr "type" "call")]
7543 (define_insn "*call_value_mem"
7544 [(set (match_operand 0 "" "")
7545 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7546 (match_operand 2 "" "")))
7547 (use (match_operand 3 "" ""))
7548 (clobber (reg:SI LR_REGNUM))]
7549 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7551 return output_call_mem (&operands[1]);
7553 [(set_attr "length" "12")
7554 (set_attr "type" "call")]
7557 (define_insn "*call_value_reg_thumb_v5"
7558 [(set (match_operand 0 "" "")
7559 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7560 (match_operand 2 "" "")))
7561 (use (match_operand 3 "" ""))
7562 (clobber (reg:SI LR_REGNUM))]
7563 "TARGET_THUMB && arm_arch5"
7565 [(set_attr "length" "2")
7566 (set_attr "type" "call")]
7569 (define_insn "*call_value_reg_thumb"
7570 [(set (match_operand 0 "" "")
7571 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7572 (match_operand 2 "" "")))
7573 (use (match_operand 3 "" ""))
7574 (clobber (reg:SI LR_REGNUM))]
7575 "TARGET_THUMB && !arm_arch5"
7578 if (!TARGET_CALLER_INTERWORKING)
7579 return thumb_call_via_reg (operands[1]);
7580 else if (operands[2] == const0_rtx)
7581 return \"bl\\t%__interwork_call_via_%1\";
7582 else if (frame_pointer_needed)
7583 return \"bl\\t%__interwork_r7_call_via_%1\";
7585 return \"bl\\t%__interwork_r11_call_via_%1\";
7587 [(set_attr "type" "call")]
7590 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7591 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7593 (define_insn "*call_symbol"
7594 [(call (mem:SI (match_operand:SI 0 "" ""))
7595 (match_operand 1 "" ""))
7596 (use (match_operand 2 "" ""))
7597 (clobber (reg:SI LR_REGNUM))]
7599 && (GET_CODE (operands[0]) == SYMBOL_REF)
7600 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7603 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7605 [(set_attr "type" "call")]
7608 (define_insn "*call_value_symbol"
7609 [(set (match_operand 0 "" "")
7610 (call (mem:SI (match_operand:SI 1 "" ""))
7611 (match_operand:SI 2 "" "")))
7612 (use (match_operand 3 "" ""))
7613 (clobber (reg:SI LR_REGNUM))]
7615 && (GET_CODE (operands[1]) == SYMBOL_REF)
7616 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7619 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7621 [(set_attr "type" "call")]
7624 (define_insn "*call_insn"
7625 [(call (mem:SI (match_operand:SI 0 "" ""))
7626 (match_operand:SI 1 "" ""))
7627 (use (match_operand 2 "" ""))
7628 (clobber (reg:SI LR_REGNUM))]
7630 && GET_CODE (operands[0]) == SYMBOL_REF
7631 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7633 [(set_attr "length" "4")
7634 (set_attr "type" "call")]
7637 (define_insn "*call_value_insn"
7638 [(set (match_operand 0 "" "")
7639 (call (mem:SI (match_operand 1 "" ""))
7640 (match_operand 2 "" "")))
7641 (use (match_operand 3 "" ""))
7642 (clobber (reg:SI LR_REGNUM))]
7644 && GET_CODE (operands[1]) == SYMBOL_REF
7645 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7647 [(set_attr "length" "4")
7648 (set_attr "type" "call")]
7651 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7652 (define_expand "sibcall"
7653 [(parallel [(call (match_operand 0 "memory_operand" "")
7654 (match_operand 1 "general_operand" ""))
7656 (use (match_operand 2 "" ""))])]
7660 if (operands[2] == NULL_RTX)
7661 operands[2] = const0_rtx;
7665 (define_expand "sibcall_value"
7666 [(parallel [(set (match_operand 0 "" "")
7667 (call (match_operand 1 "memory_operand" "")
7668 (match_operand 2 "general_operand" "")))
7670 (use (match_operand 3 "" ""))])]
7674 if (operands[3] == NULL_RTX)
7675 operands[3] = const0_rtx;
7679 (define_insn "*sibcall_insn"
7680 [(call (mem:SI (match_operand:SI 0 "" "X"))
7681 (match_operand 1 "" ""))
7683 (use (match_operand 2 "" ""))]
7684 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7686 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7688 [(set_attr "type" "call")]
7691 (define_insn "*sibcall_value_insn"
7692 [(set (match_operand 0 "" "")
7693 (call (mem:SI (match_operand:SI 1 "" "X"))
7694 (match_operand 2 "" "")))
7696 (use (match_operand 3 "" ""))]
7697 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7699 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7701 [(set_attr "type" "call")]
7704 ;; Often the return insn will be the same as loading from memory, so set attr
7705 (define_insn "return"
7707 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7710 if (arm_ccfsm_state == 2)
7712 arm_ccfsm_state += 2;
7715 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7717 [(set_attr "type" "load1")
7718 (set_attr "length" "12")
7719 (set_attr "predicable" "yes")]
7722 (define_insn "*cond_return"
7724 (if_then_else (match_operator 0 "arm_comparison_operator"
7725 [(match_operand 1 "cc_register" "") (const_int 0)])
7728 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7731 if (arm_ccfsm_state == 2)
7733 arm_ccfsm_state += 2;
7736 return output_return_instruction (operands[0], TRUE, FALSE);
7738 [(set_attr "conds" "use")
7739 (set_attr "length" "12")
7740 (set_attr "type" "load1")]
7743 (define_insn "*cond_return_inverted"
7745 (if_then_else (match_operator 0 "arm_comparison_operator"
7746 [(match_operand 1 "cc_register" "") (const_int 0)])
7749 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7752 if (arm_ccfsm_state == 2)
7754 arm_ccfsm_state += 2;
7757 return output_return_instruction (operands[0], TRUE, TRUE);
7759 [(set_attr "conds" "use")
7760 (set_attr "length" "12")
7761 (set_attr "type" "load1")]
7764 ;; Generate a sequence of instructions to determine if the processor is
7765 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7768 (define_expand "return_addr_mask"
7770 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7772 (set (match_operand:SI 0 "s_register_operand" "")
7773 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7775 (const_int 67108860)))] ; 0x03fffffc
7778 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7781 (define_insn "*check_arch2"
7782 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7783 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7786 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7787 [(set_attr "length" "8")
7788 (set_attr "conds" "set")]
7791 ;; Call subroutine returning any type.
7793 (define_expand "untyped_call"
7794 [(parallel [(call (match_operand 0 "" "")
7796 (match_operand 1 "" "")
7797 (match_operand 2 "" "")])]
7802 rtx par = gen_rtx_PARALLEL (VOIDmode,
7803 rtvec_alloc (XVECLEN (operands[2], 0)));
7804 rtx addr = gen_reg_rtx (Pmode);
7808 emit_move_insn (addr, XEXP (operands[1], 0));
7809 mem = change_address (operands[1], BLKmode, addr);
7811 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7813 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7815 /* Default code only uses r0 as a return value, but we could
7816 be using anything up to 4 registers. */
7817 if (REGNO (src) == R0_REGNUM)
7818 src = gen_rtx_REG (TImode, R0_REGNUM);
7820 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7822 size += GET_MODE_SIZE (GET_MODE (src));
7825 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7830 for (i = 0; i < XVECLEN (par, 0); i++)
7832 HOST_WIDE_INT offset = 0;
7833 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
7836 emit_move_insn (addr, plus_constant (addr, size));
7838 mem = change_address (mem, GET_MODE (reg), NULL);
7839 if (REGNO (reg) == R0_REGNUM)
7841 /* On thumb we have to use a write-back instruction. */
7842 emit_insn (arm_gen_store_multiple (R0_REGNUM, 4, addr, TRUE,
7843 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
7844 size = TARGET_ARM ? 16 : 0;
7848 emit_move_insn (mem, reg);
7849 size = GET_MODE_SIZE (GET_MODE (reg));
7853 /* The optimizer does not know that the call sets the function value
7854 registers we stored in the result block. We avoid problems by
7855 claiming that all hard registers are used and clobbered at this
7857 emit_insn (gen_blockage ());
7863 (define_expand "untyped_return"
7864 [(match_operand:BLK 0 "memory_operand" "")
7865 (match_operand 1 "" "")]
7870 rtx addr = gen_reg_rtx (Pmode);
7874 emit_move_insn (addr, XEXP (operands[0], 0));
7875 mem = change_address (operands[0], BLKmode, addr);
7877 for (i = 0; i < XVECLEN (operands[1], 0); i++)
7879 HOST_WIDE_INT offset = 0;
7880 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
7883 emit_move_insn (addr, plus_constant (addr, size));
7885 mem = change_address (mem, GET_MODE (reg), NULL);
7886 if (REGNO (reg) == R0_REGNUM)
7888 /* On thumb we have to use a write-back instruction. */
7889 emit_insn (arm_gen_load_multiple (R0_REGNUM, 4, addr, TRUE,
7890 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
7891 size = TARGET_ARM ? 16 : 0;
7895 emit_move_insn (reg, mem);
7896 size = GET_MODE_SIZE (GET_MODE (reg));
7900 /* Emit USE insns before the return. */
7901 for (i = 0; i < XVECLEN (operands[1], 0); i++)
7902 emit_insn (gen_rtx_USE (VOIDmode,
7903 SET_DEST (XVECEXP (operands[1], 0, i))));
7905 /* Construct the return. */
7906 expand_naked_return ();
7912 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7913 ;; all of memory. This blocks insns from being moved across this point.
7915 (define_insn "blockage"
7916 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7919 [(set_attr "length" "0")
7920 (set_attr "type" "block")]
7923 (define_expand "casesi"
7924 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7925 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7926 (match_operand:SI 2 "const_int_operand" "") ; total range
7927 (match_operand:SI 3 "" "") ; table label
7928 (match_operand:SI 4 "" "")] ; Out of range label
7933 if (operands[1] != const0_rtx)
7935 reg = gen_reg_rtx (SImode);
7937 emit_insn (gen_addsi3 (reg, operands[0],
7938 GEN_INT (-INTVAL (operands[1]))));
7942 if (!const_ok_for_arm (INTVAL (operands[2])))
7943 operands[2] = force_reg (SImode, operands[2]);
7945 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
7951 ;; The USE in this pattern is needed to tell flow analysis that this is
7952 ;; a CASESI insn. It has no other purpose.
7953 (define_insn "casesi_internal"
7954 [(parallel [(set (pc)
7956 (leu (match_operand:SI 0 "s_register_operand" "r")
7957 (match_operand:SI 1 "arm_rhs_operand" "rI"))
7958 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
7959 (label_ref (match_operand 2 "" ""))))
7960 (label_ref (match_operand 3 "" ""))))
7961 (clobber (reg:CC CC_REGNUM))
7962 (use (label_ref (match_dup 2)))])]
7966 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
7967 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
7969 [(set_attr "conds" "clob")
7970 (set_attr "length" "12")]
7973 (define_expand "indirect_jump"
7975 (match_operand:SI 0 "s_register_operand" ""))]
7980 ;; NB Never uses BX.
7981 (define_insn "*arm_indirect_jump"
7983 (match_operand:SI 0 "s_register_operand" "r"))]
7985 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
7986 [(set_attr "predicable" "yes")]
7989 (define_insn "*load_indirect_jump"
7991 (match_operand:SI 0 "memory_operand" "m"))]
7993 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
7994 [(set_attr "type" "load1")
7995 (set_attr "pool_range" "4096")
7996 (set_attr "neg_pool_range" "4084")
7997 (set_attr "predicable" "yes")]
8000 ;; NB Never uses BX.
8001 (define_insn "*thumb_indirect_jump"
8003 (match_operand:SI 0 "register_operand" "l*r"))]
8006 [(set_attr "conds" "clob")
8007 (set_attr "length" "2")]
8018 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8019 return \"mov\\tr8, r8\";
8021 [(set (attr "length")
8022 (if_then_else (eq_attr "is_thumb" "yes")
8028 ;; Patterns to allow combination of arithmetic, cond code and shifts
8030 (define_insn "*arith_shiftsi"
8031 [(set (match_operand:SI 0 "s_register_operand" "=r")
8032 (match_operator:SI 1 "shiftable_operator"
8033 [(match_operator:SI 3 "shift_operator"
8034 [(match_operand:SI 4 "s_register_operand" "r")
8035 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8036 (match_operand:SI 2 "s_register_operand" "r")]))]
8038 "%i1%?\\t%0, %2, %4%S3"
8039 [(set_attr "predicable" "yes")
8040 (set_attr "shift" "4")
8041 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8042 (const_string "alu_shift")
8043 (const_string "alu_shift_reg")))]
8047 [(set (match_operand:SI 0 "s_register_operand" "")
8048 (match_operator:SI 1 "shiftable_operator"
8049 [(match_operator:SI 2 "shiftable_operator"
8050 [(match_operator:SI 3 "shift_operator"
8051 [(match_operand:SI 4 "s_register_operand" "")
8052 (match_operand:SI 5 "reg_or_int_operand" "")])
8053 (match_operand:SI 6 "s_register_operand" "")])
8054 (match_operand:SI 7 "arm_rhs_operand" "")]))
8055 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8058 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8061 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8064 (define_insn "*arith_shiftsi_compare0"
8065 [(set (reg:CC_NOOV CC_REGNUM)
8066 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8067 [(match_operator:SI 3 "shift_operator"
8068 [(match_operand:SI 4 "s_register_operand" "r")
8069 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8070 (match_operand:SI 2 "s_register_operand" "r")])
8072 (set (match_operand:SI 0 "s_register_operand" "=r")
8073 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8076 "%i1%?s\\t%0, %2, %4%S3"
8077 [(set_attr "conds" "set")
8078 (set_attr "shift" "4")
8079 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8080 (const_string "alu_shift")
8081 (const_string "alu_shift_reg")))]
8084 (define_insn "*arith_shiftsi_compare0_scratch"
8085 [(set (reg:CC_NOOV CC_REGNUM)
8086 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8087 [(match_operator:SI 3 "shift_operator"
8088 [(match_operand:SI 4 "s_register_operand" "r")
8089 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8090 (match_operand:SI 2 "s_register_operand" "r")])
8092 (clobber (match_scratch:SI 0 "=r"))]
8094 "%i1%?s\\t%0, %2, %4%S3"
8095 [(set_attr "conds" "set")
8096 (set_attr "shift" "4")
8097 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8098 (const_string "alu_shift")
8099 (const_string "alu_shift_reg")))]
8102 (define_insn "*sub_shiftsi"
8103 [(set (match_operand:SI 0 "s_register_operand" "=r")
8104 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8105 (match_operator:SI 2 "shift_operator"
8106 [(match_operand:SI 3 "s_register_operand" "r")
8107 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
8109 "sub%?\\t%0, %1, %3%S2"
8110 [(set_attr "predicable" "yes")
8111 (set_attr "shift" "3")
8112 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8113 (const_string "alu_shift")
8114 (const_string "alu_shift_reg")))]
8117 (define_insn "*sub_shiftsi_compare0"
8118 [(set (reg:CC_NOOV CC_REGNUM)
8120 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8121 (match_operator:SI 2 "shift_operator"
8122 [(match_operand:SI 3 "s_register_operand" "r")
8123 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8125 (set (match_operand:SI 0 "s_register_operand" "=r")
8126 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
8129 "sub%?s\\t%0, %1, %3%S2"
8130 [(set_attr "conds" "set")
8131 (set_attr "shift" "3")
8132 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8133 (const_string "alu_shift")
8134 (const_string "alu_shift_reg")))]
8137 (define_insn "*sub_shiftsi_compare0_scratch"
8138 [(set (reg:CC_NOOV CC_REGNUM)
8140 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8141 (match_operator:SI 2 "shift_operator"
8142 [(match_operand:SI 3 "s_register_operand" "r")
8143 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8145 (clobber (match_scratch:SI 0 "=r"))]
8147 "sub%?s\\t%0, %1, %3%S2"
8148 [(set_attr "conds" "set")
8149 (set_attr "shift" "3")
8150 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8151 (const_string "alu_shift")
8152 (const_string "alu_shift_reg")))]
8157 (define_insn "*and_scc"
8158 [(set (match_operand:SI 0 "s_register_operand" "=r")
8159 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8160 [(match_operand 3 "cc_register" "") (const_int 0)])
8161 (match_operand:SI 2 "s_register_operand" "r")))]
8163 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8164 [(set_attr "conds" "use")
8165 (set_attr "length" "8")]
8168 (define_insn "*ior_scc"
8169 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8170 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8171 [(match_operand 3 "cc_register" "") (const_int 0)])
8172 (match_operand:SI 1 "s_register_operand" "0,?r")))]
8176 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8177 [(set_attr "conds" "use")
8178 (set_attr "length" "4,8")]
8181 (define_insn "*compare_scc"
8182 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8183 (match_operator:SI 1 "arm_comparison_operator"
8184 [(match_operand:SI 2 "s_register_operand" "r,r")
8185 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8186 (clobber (reg:CC CC_REGNUM))]
8189 if (operands[3] == const0_rtx)
8191 if (GET_CODE (operands[1]) == LT)
8192 return \"mov\\t%0, %2, lsr #31\";
8194 if (GET_CODE (operands[1]) == GE)
8195 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8197 if (GET_CODE (operands[1]) == EQ)
8198 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8201 if (GET_CODE (operands[1]) == NE)
8203 if (which_alternative == 1)
8204 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8205 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8207 if (which_alternative == 1)
8208 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8210 output_asm_insn (\"cmp\\t%2, %3\", operands);
8211 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8213 [(set_attr "conds" "clob")
8214 (set_attr "length" "12")]
8217 (define_insn "*cond_move"
8218 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8219 (if_then_else:SI (match_operator 3 "equality_operator"
8220 [(match_operator 4 "arm_comparison_operator"
8221 [(match_operand 5 "cc_register" "") (const_int 0)])
8223 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8224 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8227 if (GET_CODE (operands[3]) == NE)
8229 if (which_alternative != 1)
8230 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8231 if (which_alternative != 0)
8232 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8235 if (which_alternative != 0)
8236 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8237 if (which_alternative != 1)
8238 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8241 [(set_attr "conds" "use")
8242 (set_attr "length" "4,4,8")]
8245 (define_insn "*cond_arith"
8246 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8247 (match_operator:SI 5 "shiftable_operator"
8248 [(match_operator:SI 4 "arm_comparison_operator"
8249 [(match_operand:SI 2 "s_register_operand" "r,r")
8250 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8251 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8252 (clobber (reg:CC CC_REGNUM))]
8255 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8256 return \"%i5\\t%0, %1, %2, lsr #31\";
8258 output_asm_insn (\"cmp\\t%2, %3\", operands);
8259 if (GET_CODE (operands[5]) == AND)
8260 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8261 else if (GET_CODE (operands[5]) == MINUS)
8262 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8263 else if (which_alternative != 0)
8264 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8265 return \"%i5%d4\\t%0, %1, #1\";
8267 [(set_attr "conds" "clob")
8268 (set_attr "length" "12")]
8271 (define_insn "*cond_sub"
8272 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8273 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8274 (match_operator:SI 4 "arm_comparison_operator"
8275 [(match_operand:SI 2 "s_register_operand" "r,r")
8276 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8277 (clobber (reg:CC CC_REGNUM))]
8280 output_asm_insn (\"cmp\\t%2, %3\", operands);
8281 if (which_alternative != 0)
8282 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8283 return \"sub%d4\\t%0, %1, #1\";
8285 [(set_attr "conds" "clob")
8286 (set_attr "length" "8,12")]
8289 (define_insn "*cmp_ite0"
8290 [(set (match_operand 6 "dominant_cc_register" "")
8293 (match_operator 4 "arm_comparison_operator"
8294 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8295 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8296 (match_operator:SI 5 "arm_comparison_operator"
8297 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8298 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8304 static const char * const opcodes[4][2] =
8306 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8307 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8308 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8309 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8310 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8311 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8312 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8313 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8316 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8318 return opcodes[which_alternative][swap];
8320 [(set_attr "conds" "set")
8321 (set_attr "length" "8")]
8324 (define_insn "*cmp_ite1"
8325 [(set (match_operand 6 "dominant_cc_register" "")
8328 (match_operator 4 "arm_comparison_operator"
8329 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8330 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8331 (match_operator:SI 5 "arm_comparison_operator"
8332 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8333 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8339 static const char * const opcodes[4][2] =
8341 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8342 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8343 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8344 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8345 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8346 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8347 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8348 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8351 comparison_dominates_p (GET_CODE (operands[5]),
8352 reverse_condition (GET_CODE (operands[4])));
8354 return opcodes[which_alternative][swap];
8356 [(set_attr "conds" "set")
8357 (set_attr "length" "8")]
8360 (define_insn "*cmp_and"
8361 [(set (match_operand 6 "dominant_cc_register" "")
8364 (match_operator 4 "arm_comparison_operator"
8365 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8366 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8367 (match_operator:SI 5 "arm_comparison_operator"
8368 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8369 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8374 static const char *const opcodes[4][2] =
8376 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8377 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8378 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8379 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8380 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8381 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8382 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8383 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8386 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8388 return opcodes[which_alternative][swap];
8390 [(set_attr "conds" "set")
8391 (set_attr "predicable" "no")
8392 (set_attr "length" "8")]
8395 (define_insn "*cmp_ior"
8396 [(set (match_operand 6 "dominant_cc_register" "")
8399 (match_operator 4 "arm_comparison_operator"
8400 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8401 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8402 (match_operator:SI 5 "arm_comparison_operator"
8403 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8404 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8409 static const char *const opcodes[4][2] =
8411 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8412 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8413 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8414 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8415 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8416 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8417 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8418 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8421 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8423 return opcodes[which_alternative][swap];
8426 [(set_attr "conds" "set")
8427 (set_attr "length" "8")]
8430 (define_insn_and_split "*ior_scc_scc"
8431 [(set (match_operand:SI 0 "s_register_operand" "=r")
8432 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8433 [(match_operand:SI 1 "s_register_operand" "r")
8434 (match_operand:SI 2 "arm_add_operand" "rIL")])
8435 (match_operator:SI 6 "arm_comparison_operator"
8436 [(match_operand:SI 4 "s_register_operand" "r")
8437 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8438 (clobber (reg:CC CC_REGNUM))]
8440 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8443 "TARGET_ARM && reload_completed"
8447 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8448 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8450 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8452 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8455 [(set_attr "conds" "clob")
8456 (set_attr "length" "16")])
8458 ; If the above pattern is followed by a CMP insn, then the compare is
8459 ; redundant, since we can rework the conditional instruction that follows.
8460 (define_insn_and_split "*ior_scc_scc_cmp"
8461 [(set (match_operand 0 "dominant_cc_register" "")
8462 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8463 [(match_operand:SI 1 "s_register_operand" "r")
8464 (match_operand:SI 2 "arm_add_operand" "rIL")])
8465 (match_operator:SI 6 "arm_comparison_operator"
8466 [(match_operand:SI 4 "s_register_operand" "r")
8467 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8469 (set (match_operand:SI 7 "s_register_operand" "=r")
8470 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8471 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8474 "TARGET_ARM && reload_completed"
8478 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8479 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8481 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8483 [(set_attr "conds" "set")
8484 (set_attr "length" "16")])
8486 (define_insn_and_split "*and_scc_scc"
8487 [(set (match_operand:SI 0 "s_register_operand" "=r")
8488 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8489 [(match_operand:SI 1 "s_register_operand" "r")
8490 (match_operand:SI 2 "arm_add_operand" "rIL")])
8491 (match_operator:SI 6 "arm_comparison_operator"
8492 [(match_operand:SI 4 "s_register_operand" "r")
8493 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8494 (clobber (reg:CC CC_REGNUM))]
8496 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8499 "TARGET_ARM && reload_completed
8500 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8505 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8506 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8508 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8510 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8513 [(set_attr "conds" "clob")
8514 (set_attr "length" "16")])
8516 ; If the above pattern is followed by a CMP insn, then the compare is
8517 ; redundant, since we can rework the conditional instruction that follows.
8518 (define_insn_and_split "*and_scc_scc_cmp"
8519 [(set (match_operand 0 "dominant_cc_register" "")
8520 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8521 [(match_operand:SI 1 "s_register_operand" "r")
8522 (match_operand:SI 2 "arm_add_operand" "rIL")])
8523 (match_operator:SI 6 "arm_comparison_operator"
8524 [(match_operand:SI 4 "s_register_operand" "r")
8525 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8527 (set (match_operand:SI 7 "s_register_operand" "=r")
8528 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8529 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8532 "TARGET_ARM && reload_completed"
8536 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8537 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8539 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8541 [(set_attr "conds" "set")
8542 (set_attr "length" "16")])
8544 ;; If there is no dominance in the comparison, then we can still save an
8545 ;; instruction in the AND case, since we can know that the second compare
8546 ;; need only zero the value if false (if true, then the value is already
8548 (define_insn_and_split "*and_scc_scc_nodom"
8549 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8550 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8551 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8552 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8553 (match_operator:SI 6 "arm_comparison_operator"
8554 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8555 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8556 (clobber (reg:CC CC_REGNUM))]
8558 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8561 "TARGET_ARM && reload_completed"
8562 [(parallel [(set (match_dup 0)
8563 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8564 (clobber (reg:CC CC_REGNUM))])
8565 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8567 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8570 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8571 operands[4], operands[5]),
8573 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8575 [(set_attr "conds" "clob")
8576 (set_attr "length" "20")])
8579 [(set (reg:CC_NOOV CC_REGNUM)
8580 (compare:CC_NOOV (ior:SI
8581 (and:SI (match_operand:SI 0 "s_register_operand" "")
8583 (match_operator:SI 1 "comparison_operator"
8584 [(match_operand:SI 2 "s_register_operand" "")
8585 (match_operand:SI 3 "arm_add_operand" "")]))
8587 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8590 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8592 (set (reg:CC_NOOV CC_REGNUM)
8593 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8598 [(set (reg:CC_NOOV CC_REGNUM)
8599 (compare:CC_NOOV (ior:SI
8600 (match_operator:SI 1 "comparison_operator"
8601 [(match_operand:SI 2 "s_register_operand" "")
8602 (match_operand:SI 3 "arm_add_operand" "")])
8603 (and:SI (match_operand:SI 0 "s_register_operand" "")
8606 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8609 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8611 (set (reg:CC_NOOV CC_REGNUM)
8612 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8616 (define_insn "*negscc"
8617 [(set (match_operand:SI 0 "s_register_operand" "=r")
8618 (neg:SI (match_operator 3 "arm_comparison_operator"
8619 [(match_operand:SI 1 "s_register_operand" "r")
8620 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8621 (clobber (reg:CC CC_REGNUM))]
8624 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8625 return \"mov\\t%0, %1, asr #31\";
8627 if (GET_CODE (operands[3]) == NE)
8628 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8630 if (GET_CODE (operands[3]) == GT)
8631 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8633 output_asm_insn (\"cmp\\t%1, %2\", operands);
8634 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8635 return \"mvn%d3\\t%0, #0\";
8637 [(set_attr "conds" "clob")
8638 (set_attr "length" "12")]
8641 (define_insn "movcond"
8642 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8644 (match_operator 5 "arm_comparison_operator"
8645 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8646 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8647 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8648 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8649 (clobber (reg:CC CC_REGNUM))]
8652 if (GET_CODE (operands[5]) == LT
8653 && (operands[4] == const0_rtx))
8655 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8657 if (operands[2] == const0_rtx)
8658 return \"and\\t%0, %1, %3, asr #31\";
8659 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8661 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8663 if (operands[1] == const0_rtx)
8664 return \"bic\\t%0, %2, %3, asr #31\";
8665 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8667 /* The only case that falls through to here is when both ops 1 & 2
8671 if (GET_CODE (operands[5]) == GE
8672 && (operands[4] == const0_rtx))
8674 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8676 if (operands[2] == const0_rtx)
8677 return \"bic\\t%0, %1, %3, asr #31\";
8678 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8680 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8682 if (operands[1] == const0_rtx)
8683 return \"and\\t%0, %2, %3, asr #31\";
8684 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8686 /* The only case that falls through to here is when both ops 1 & 2
8689 if (GET_CODE (operands[4]) == CONST_INT
8690 && !const_ok_for_arm (INTVAL (operands[4])))
8691 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8693 output_asm_insn (\"cmp\\t%3, %4\", operands);
8694 if (which_alternative != 0)
8695 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8696 if (which_alternative != 1)
8697 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8700 [(set_attr "conds" "clob")
8701 (set_attr "length" "8,8,12")]
8704 (define_insn "*ifcompare_plus_move"
8705 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8706 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8707 [(match_operand:SI 4 "s_register_operand" "r,r")
8708 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8710 (match_operand:SI 2 "s_register_operand" "r,r")
8711 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8712 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8713 (clobber (reg:CC CC_REGNUM))]
8716 [(set_attr "conds" "clob")
8717 (set_attr "length" "8,12")]
8720 (define_insn "*if_plus_move"
8721 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8723 (match_operator 4 "arm_comparison_operator"
8724 [(match_operand 5 "cc_register" "") (const_int 0)])
8726 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8727 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8728 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8732 sub%d4\\t%0, %2, #%n3
8733 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8734 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8735 [(set_attr "conds" "use")
8736 (set_attr "length" "4,4,8,8")
8737 (set_attr "type" "*,*,*,*")]
8740 (define_insn "*ifcompare_move_plus"
8741 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8742 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8743 [(match_operand:SI 4 "s_register_operand" "r,r")
8744 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8745 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8747 (match_operand:SI 2 "s_register_operand" "r,r")
8748 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8749 (clobber (reg:CC CC_REGNUM))]
8752 [(set_attr "conds" "clob")
8753 (set_attr "length" "8,12")]
8756 (define_insn "*if_move_plus"
8757 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8759 (match_operator 4 "arm_comparison_operator"
8760 [(match_operand 5 "cc_register" "") (const_int 0)])
8761 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8763 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8764 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8768 sub%D4\\t%0, %2, #%n3
8769 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8770 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8771 [(set_attr "conds" "use")
8772 (set_attr "length" "4,4,8,8")
8773 (set_attr "type" "*,*,*,*")]
8776 (define_insn "*ifcompare_arith_arith"
8777 [(set (match_operand:SI 0 "s_register_operand" "=r")
8778 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8779 [(match_operand:SI 5 "s_register_operand" "r")
8780 (match_operand:SI 6 "arm_add_operand" "rIL")])
8781 (match_operator:SI 8 "shiftable_operator"
8782 [(match_operand:SI 1 "s_register_operand" "r")
8783 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8784 (match_operator:SI 7 "shiftable_operator"
8785 [(match_operand:SI 3 "s_register_operand" "r")
8786 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8787 (clobber (reg:CC CC_REGNUM))]
8790 [(set_attr "conds" "clob")
8791 (set_attr "length" "12")]
8794 (define_insn "*if_arith_arith"
8795 [(set (match_operand:SI 0 "s_register_operand" "=r")
8796 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8797 [(match_operand 8 "cc_register" "") (const_int 0)])
8798 (match_operator:SI 6 "shiftable_operator"
8799 [(match_operand:SI 1 "s_register_operand" "r")
8800 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8801 (match_operator:SI 7 "shiftable_operator"
8802 [(match_operand:SI 3 "s_register_operand" "r")
8803 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8805 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8806 [(set_attr "conds" "use")
8807 (set_attr "length" "8")]
8810 (define_insn "*ifcompare_arith_move"
8811 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8812 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8813 [(match_operand:SI 2 "s_register_operand" "r,r")
8814 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8815 (match_operator:SI 7 "shiftable_operator"
8816 [(match_operand:SI 4 "s_register_operand" "r,r")
8817 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8818 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8819 (clobber (reg:CC CC_REGNUM))]
8822 /* If we have an operation where (op x 0) is the identity operation and
8823 the conditional operator is LT or GE and we are comparing against zero and
8824 everything is in registers then we can do this in two instructions. */
8825 if (operands[3] == const0_rtx
8826 && GET_CODE (operands[7]) != AND
8827 && GET_CODE (operands[5]) == REG
8828 && GET_CODE (operands[1]) == REG
8829 && REGNO (operands[1]) == REGNO (operands[4])
8830 && REGNO (operands[4]) != REGNO (operands[0]))
8832 if (GET_CODE (operands[6]) == LT)
8833 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8834 else if (GET_CODE (operands[6]) == GE)
8835 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8837 if (GET_CODE (operands[3]) == CONST_INT
8838 && !const_ok_for_arm (INTVAL (operands[3])))
8839 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8841 output_asm_insn (\"cmp\\t%2, %3\", operands);
8842 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8843 if (which_alternative != 0)
8844 return \"mov%D6\\t%0, %1\";
8847 [(set_attr "conds" "clob")
8848 (set_attr "length" "8,12")]
8851 (define_insn "*if_arith_move"
8852 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8853 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8854 [(match_operand 6 "cc_register" "") (const_int 0)])
8855 (match_operator:SI 5 "shiftable_operator"
8856 [(match_operand:SI 2 "s_register_operand" "r,r")
8857 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8858 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8862 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8863 [(set_attr "conds" "use")
8864 (set_attr "length" "4,8")
8865 (set_attr "type" "*,*")]
8868 (define_insn "*ifcompare_move_arith"
8869 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8870 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8871 [(match_operand:SI 4 "s_register_operand" "r,r")
8872 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8873 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8874 (match_operator:SI 7 "shiftable_operator"
8875 [(match_operand:SI 2 "s_register_operand" "r,r")
8876 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8877 (clobber (reg:CC CC_REGNUM))]
8880 /* If we have an operation where (op x 0) is the identity operation and
8881 the conditional operator is LT or GE and we are comparing against zero and
8882 everything is in registers then we can do this in two instructions */
8883 if (operands[5] == const0_rtx
8884 && GET_CODE (operands[7]) != AND
8885 && GET_CODE (operands[3]) == REG
8886 && GET_CODE (operands[1]) == REG
8887 && REGNO (operands[1]) == REGNO (operands[2])
8888 && REGNO (operands[2]) != REGNO (operands[0]))
8890 if (GET_CODE (operands[6]) == GE)
8891 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8892 else if (GET_CODE (operands[6]) == LT)
8893 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8896 if (GET_CODE (operands[5]) == CONST_INT
8897 && !const_ok_for_arm (INTVAL (operands[5])))
8898 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8900 output_asm_insn (\"cmp\\t%4, %5\", operands);
8902 if (which_alternative != 0)
8903 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8904 return \"%I7%D6\\t%0, %2, %3\";
8906 [(set_attr "conds" "clob")
8907 (set_attr "length" "8,12")]
8910 (define_insn "*if_move_arith"
8911 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8913 (match_operator 4 "arm_comparison_operator"
8914 [(match_operand 6 "cc_register" "") (const_int 0)])
8915 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8916 (match_operator:SI 5 "shiftable_operator"
8917 [(match_operand:SI 2 "s_register_operand" "r,r")
8918 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8922 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8923 [(set_attr "conds" "use")
8924 (set_attr "length" "4,8")
8925 (set_attr "type" "*,*")]
8928 (define_insn "*ifcompare_move_not"
8929 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8931 (match_operator 5 "arm_comparison_operator"
8932 [(match_operand:SI 3 "s_register_operand" "r,r")
8933 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8934 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8936 (match_operand:SI 2 "s_register_operand" "r,r"))))
8937 (clobber (reg:CC CC_REGNUM))]
8940 [(set_attr "conds" "clob")
8941 (set_attr "length" "8,12")]
8944 (define_insn "*if_move_not"
8945 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8947 (match_operator 4 "arm_comparison_operator"
8948 [(match_operand 3 "cc_register" "") (const_int 0)])
8949 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8950 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
8954 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
8955 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8956 [(set_attr "conds" "use")
8957 (set_attr "length" "4,8,8")]
8960 (define_insn "*ifcompare_not_move"
8961 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8963 (match_operator 5 "arm_comparison_operator"
8964 [(match_operand:SI 3 "s_register_operand" "r,r")
8965 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8967 (match_operand:SI 2 "s_register_operand" "r,r"))
8968 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8969 (clobber (reg:CC CC_REGNUM))]
8972 [(set_attr "conds" "clob")
8973 (set_attr "length" "8,12")]
8976 (define_insn "*if_not_move"
8977 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8979 (match_operator 4 "arm_comparison_operator"
8980 [(match_operand 3 "cc_register" "") (const_int 0)])
8981 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
8982 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8986 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
8987 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8988 [(set_attr "conds" "use")
8989 (set_attr "length" "4,8,8")]
8992 (define_insn "*ifcompare_shift_move"
8993 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8995 (match_operator 6 "arm_comparison_operator"
8996 [(match_operand:SI 4 "s_register_operand" "r,r")
8997 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8998 (match_operator:SI 7 "shift_operator"
8999 [(match_operand:SI 2 "s_register_operand" "r,r")
9000 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9001 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9002 (clobber (reg:CC CC_REGNUM))]
9005 [(set_attr "conds" "clob")
9006 (set_attr "length" "8,12")]
9009 (define_insn "*if_shift_move"
9010 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9012 (match_operator 5 "arm_comparison_operator"
9013 [(match_operand 6 "cc_register" "") (const_int 0)])
9014 (match_operator:SI 4 "shift_operator"
9015 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9016 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9017 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9021 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9022 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9023 [(set_attr "conds" "use")
9024 (set_attr "shift" "2")
9025 (set_attr "length" "4,8,8")
9026 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9027 (const_string "alu_shift")
9028 (const_string "alu_shift_reg")))]
9031 (define_insn "*ifcompare_move_shift"
9032 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9034 (match_operator 6 "arm_comparison_operator"
9035 [(match_operand:SI 4 "s_register_operand" "r,r")
9036 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9037 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9038 (match_operator:SI 7 "shift_operator"
9039 [(match_operand:SI 2 "s_register_operand" "r,r")
9040 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9041 (clobber (reg:CC CC_REGNUM))]
9044 [(set_attr "conds" "clob")
9045 (set_attr "length" "8,12")]
9048 (define_insn "*if_move_shift"
9049 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9051 (match_operator 5 "arm_comparison_operator"
9052 [(match_operand 6 "cc_register" "") (const_int 0)])
9053 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9054 (match_operator:SI 4 "shift_operator"
9055 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9056 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9060 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9061 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9062 [(set_attr "conds" "use")
9063 (set_attr "shift" "2")
9064 (set_attr "length" "4,8,8")
9065 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9066 (const_string "alu_shift")
9067 (const_string "alu_shift_reg")))]
9070 (define_insn "*ifcompare_shift_shift"
9071 [(set (match_operand:SI 0 "s_register_operand" "=r")
9073 (match_operator 7 "arm_comparison_operator"
9074 [(match_operand:SI 5 "s_register_operand" "r")
9075 (match_operand:SI 6 "arm_add_operand" "rIL")])
9076 (match_operator:SI 8 "shift_operator"
9077 [(match_operand:SI 1 "s_register_operand" "r")
9078 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9079 (match_operator:SI 9 "shift_operator"
9080 [(match_operand:SI 3 "s_register_operand" "r")
9081 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9082 (clobber (reg:CC CC_REGNUM))]
9085 [(set_attr "conds" "clob")
9086 (set_attr "length" "12")]
9089 (define_insn "*if_shift_shift"
9090 [(set (match_operand:SI 0 "s_register_operand" "=r")
9092 (match_operator 5 "arm_comparison_operator"
9093 [(match_operand 8 "cc_register" "") (const_int 0)])
9094 (match_operator:SI 6 "shift_operator"
9095 [(match_operand:SI 1 "s_register_operand" "r")
9096 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9097 (match_operator:SI 7 "shift_operator"
9098 [(match_operand:SI 3 "s_register_operand" "r")
9099 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9101 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9102 [(set_attr "conds" "use")
9103 (set_attr "shift" "1")
9104 (set_attr "length" "8")
9105 (set (attr "type") (if_then_else
9106 (and (match_operand 2 "const_int_operand" "")
9107 (match_operand 4 "const_int_operand" ""))
9108 (const_string "alu_shift")
9109 (const_string "alu_shift_reg")))]
9112 (define_insn "*ifcompare_not_arith"
9113 [(set (match_operand:SI 0 "s_register_operand" "=r")
9115 (match_operator 6 "arm_comparison_operator"
9116 [(match_operand:SI 4 "s_register_operand" "r")
9117 (match_operand:SI 5 "arm_add_operand" "rIL")])
9118 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9119 (match_operator:SI 7 "shiftable_operator"
9120 [(match_operand:SI 2 "s_register_operand" "r")
9121 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9122 (clobber (reg:CC CC_REGNUM))]
9125 [(set_attr "conds" "clob")
9126 (set_attr "length" "12")]
9129 (define_insn "*if_not_arith"
9130 [(set (match_operand:SI 0 "s_register_operand" "=r")
9132 (match_operator 5 "arm_comparison_operator"
9133 [(match_operand 4 "cc_register" "") (const_int 0)])
9134 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9135 (match_operator:SI 6 "shiftable_operator"
9136 [(match_operand:SI 2 "s_register_operand" "r")
9137 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9139 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9140 [(set_attr "conds" "use")
9141 (set_attr "length" "8")]
9144 (define_insn "*ifcompare_arith_not"
9145 [(set (match_operand:SI 0 "s_register_operand" "=r")
9147 (match_operator 6 "arm_comparison_operator"
9148 [(match_operand:SI 4 "s_register_operand" "r")
9149 (match_operand:SI 5 "arm_add_operand" "rIL")])
9150 (match_operator:SI 7 "shiftable_operator"
9151 [(match_operand:SI 2 "s_register_operand" "r")
9152 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9153 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9154 (clobber (reg:CC CC_REGNUM))]
9157 [(set_attr "conds" "clob")
9158 (set_attr "length" "12")]
9161 (define_insn "*if_arith_not"
9162 [(set (match_operand:SI 0 "s_register_operand" "=r")
9164 (match_operator 5 "arm_comparison_operator"
9165 [(match_operand 4 "cc_register" "") (const_int 0)])
9166 (match_operator:SI 6 "shiftable_operator"
9167 [(match_operand:SI 2 "s_register_operand" "r")
9168 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9169 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9171 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9172 [(set_attr "conds" "use")
9173 (set_attr "length" "8")]
9176 (define_insn "*ifcompare_neg_move"
9177 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9179 (match_operator 5 "arm_comparison_operator"
9180 [(match_operand:SI 3 "s_register_operand" "r,r")
9181 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9182 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9183 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9184 (clobber (reg:CC CC_REGNUM))]
9187 [(set_attr "conds" "clob")
9188 (set_attr "length" "8,12")]
9191 (define_insn "*if_neg_move"
9192 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9194 (match_operator 4 "arm_comparison_operator"
9195 [(match_operand 3 "cc_register" "") (const_int 0)])
9196 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9197 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9201 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9202 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9203 [(set_attr "conds" "use")
9204 (set_attr "length" "4,8,8")]
9207 (define_insn "*ifcompare_move_neg"
9208 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9210 (match_operator 5 "arm_comparison_operator"
9211 [(match_operand:SI 3 "s_register_operand" "r,r")
9212 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9213 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9214 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9215 (clobber (reg:CC CC_REGNUM))]
9218 [(set_attr "conds" "clob")
9219 (set_attr "length" "8,12")]
9222 (define_insn "*if_move_neg"
9223 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9225 (match_operator 4 "arm_comparison_operator"
9226 [(match_operand 3 "cc_register" "") (const_int 0)])
9227 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9228 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9232 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9233 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9234 [(set_attr "conds" "use")
9235 (set_attr "length" "4,8,8")]
9238 (define_insn "*arith_adjacentmem"
9239 [(set (match_operand:SI 0 "s_register_operand" "=r")
9240 (match_operator:SI 1 "shiftable_operator"
9241 [(match_operand:SI 2 "memory_operand" "m")
9242 (match_operand:SI 3 "memory_operand" "m")]))
9243 (clobber (match_scratch:SI 4 "=r"))]
9244 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9249 int val1 = 0, val2 = 0;
9251 if (REGNO (operands[0]) > REGNO (operands[4]))
9253 ldm[1] = operands[4];
9254 ldm[2] = operands[0];
9258 ldm[1] = operands[0];
9259 ldm[2] = operands[4];
9261 if (GET_CODE (XEXP (operands[2], 0)) != REG)
9262 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
9263 if (GET_CODE (XEXP (operands[3], 0)) != REG)
9264 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9265 arith[0] = operands[0];
9266 arith[3] = operands[1];
9280 ldm[0] = ops[0] = operands[4];
9281 ops[1] = XEXP (XEXP (operands[2], 0), 0);
9282 ops[2] = XEXP (XEXP (operands[2], 0), 1);
9283 output_add_immediate (ops);
9285 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9287 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9291 ldm[0] = XEXP (operands[3], 0);
9293 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9295 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9299 ldm[0] = XEXP (operands[2], 0);
9301 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9303 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9305 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9308 [(set_attr "length" "12")
9309 (set_attr "predicable" "yes")
9310 (set_attr "type" "load1")]
9313 ;; the arm can support extended pre-inc instructions
9315 ;; In all these cases, we use operands 0 and 1 for the register being
9316 ;; incremented because those are the operands that local-alloc will
9317 ;; tie and these are the pair most likely to be tieable (and the ones
9318 ;; that will benefit the most).
9320 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9321 ;; elimination will cause too many headaches.
9323 (define_insn "*strqi_preinc"
9324 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9325 (match_operand:SI 2 "index_operand" "rJ")))
9326 (match_operand:QI 3 "s_register_operand" "r"))
9327 (set (match_operand:SI 0 "s_register_operand" "=r")
9328 (plus:SI (match_dup 1) (match_dup 2)))]
9330 && !arm_eliminable_register (operands[0])
9331 && !arm_eliminable_register (operands[1])
9332 && !arm_eliminable_register (operands[2])"
9333 "str%?b\\t%3, [%0, %2]!"
9334 [(set_attr "type" "store1")
9335 (set_attr "predicable" "yes")]
9338 (define_insn "*strqi_predec"
9339 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9340 (match_operand:SI 2 "s_register_operand" "r")))
9341 (match_operand:QI 3 "s_register_operand" "r"))
9342 (set (match_operand:SI 0 "s_register_operand" "=r")
9343 (minus:SI (match_dup 1) (match_dup 2)))]
9345 && !arm_eliminable_register (operands[0])
9346 && !arm_eliminable_register (operands[1])
9347 && !arm_eliminable_register (operands[2])"
9348 "str%?b\\t%3, [%0, -%2]!"
9349 [(set_attr "type" "store1")
9350 (set_attr "predicable" "yes")]
9353 (define_insn "*loadqi_preinc"
9354 [(set (match_operand:QI 3 "s_register_operand" "=r")
9355 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9356 (match_operand:SI 2 "index_operand" "rJ"))))
9357 (set (match_operand:SI 0 "s_register_operand" "=r")
9358 (plus:SI (match_dup 1) (match_dup 2)))]
9360 && !arm_eliminable_register (operands[0])
9361 && !arm_eliminable_register (operands[1])
9362 && !arm_eliminable_register (operands[2])"
9363 "ldr%?b\\t%3, [%0, %2]!"
9364 [(set_attr "type" "load_byte")
9365 (set_attr "predicable" "yes")]
9368 (define_insn "*loadqi_predec"
9369 [(set (match_operand:QI 3 "s_register_operand" "=r")
9370 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9371 (match_operand:SI 2 "s_register_operand" "r"))))
9372 (set (match_operand:SI 0 "s_register_operand" "=r")
9373 (minus:SI (match_dup 1) (match_dup 2)))]
9375 && !arm_eliminable_register (operands[0])
9376 && !arm_eliminable_register (operands[1])
9377 && !arm_eliminable_register (operands[2])"
9378 "ldr%?b\\t%3, [%0, -%2]!"
9379 [(set_attr "type" "load_byte")
9380 (set_attr "predicable" "yes")]
9383 (define_insn "*loadqisi_preinc"
9384 [(set (match_operand:SI 3 "s_register_operand" "=r")
9386 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9387 (match_operand:SI 2 "index_operand" "rJ")))))
9388 (set (match_operand:SI 0 "s_register_operand" "=r")
9389 (plus:SI (match_dup 1) (match_dup 2)))]
9391 && !arm_eliminable_register (operands[0])
9392 && !arm_eliminable_register (operands[1])
9393 && !arm_eliminable_register (operands[2])"
9394 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9395 [(set_attr "type" "load_byte")
9396 (set_attr "predicable" "yes")]
9399 (define_insn "*loadqisi_predec"
9400 [(set (match_operand:SI 3 "s_register_operand" "=r")
9402 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9403 (match_operand:SI 2 "s_register_operand" "r")))))
9404 (set (match_operand:SI 0 "s_register_operand" "=r")
9405 (minus:SI (match_dup 1) (match_dup 2)))]
9407 && !arm_eliminable_register (operands[0])
9408 && !arm_eliminable_register (operands[1])
9409 && !arm_eliminable_register (operands[2])"
9410 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9411 [(set_attr "type" "load_byte")
9412 (set_attr "predicable" "yes")]
9415 (define_insn "*strsi_preinc"
9416 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9417 (match_operand:SI 2 "index_operand" "rJ")))
9418 (match_operand:SI 3 "s_register_operand" "r"))
9419 (set (match_operand:SI 0 "s_register_operand" "=r")
9420 (plus:SI (match_dup 1) (match_dup 2)))]
9422 && !arm_eliminable_register (operands[0])
9423 && !arm_eliminable_register (operands[1])
9424 && !arm_eliminable_register (operands[2])"
9425 "str%?\\t%3, [%0, %2]!"
9426 [(set_attr "type" "store1")
9427 (set_attr "predicable" "yes")]
9430 (define_insn "*strsi_predec"
9431 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9432 (match_operand:SI 2 "s_register_operand" "r")))
9433 (match_operand:SI 3 "s_register_operand" "r"))
9434 (set (match_operand:SI 0 "s_register_operand" "=r")
9435 (minus:SI (match_dup 1) (match_dup 2)))]
9437 && !arm_eliminable_register (operands[0])
9438 && !arm_eliminable_register (operands[1])
9439 && !arm_eliminable_register (operands[2])"
9440 "str%?\\t%3, [%0, -%2]!"
9441 [(set_attr "type" "store1")
9442 (set_attr "predicable" "yes")]
9445 (define_insn "*loadsi_preinc"
9446 [(set (match_operand:SI 3 "s_register_operand" "=r")
9447 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9448 (match_operand:SI 2 "index_operand" "rJ"))))
9449 (set (match_operand:SI 0 "s_register_operand" "=r")
9450 (plus:SI (match_dup 1) (match_dup 2)))]
9452 && !arm_eliminable_register (operands[0])
9453 && !arm_eliminable_register (operands[1])
9454 && !arm_eliminable_register (operands[2])"
9455 "ldr%?\\t%3, [%0, %2]!"
9456 [(set_attr "type" "load1")
9457 (set_attr "predicable" "yes")]
9460 (define_insn "*loadsi_predec"
9461 [(set (match_operand:SI 3 "s_register_operand" "=r")
9462 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9463 (match_operand:SI 2 "s_register_operand" "r"))))
9464 (set (match_operand:SI 0 "s_register_operand" "=r")
9465 (minus:SI (match_dup 1) (match_dup 2)))]
9467 && !arm_eliminable_register (operands[0])
9468 && !arm_eliminable_register (operands[1])
9469 && !arm_eliminable_register (operands[2])"
9470 "ldr%?\\t%3, [%0, -%2]!"
9471 [(set_attr "type" "load1")
9472 (set_attr "predicable" "yes")]
9475 (define_insn "*strqi_shiftpreinc"
9476 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9477 [(match_operand:SI 3 "s_register_operand" "r")
9478 (match_operand:SI 4 "const_shift_operand" "n")])
9479 (match_operand:SI 1 "s_register_operand" "0")))
9480 (match_operand:QI 5 "s_register_operand" "r"))
9481 (set (match_operand:SI 0 "s_register_operand" "=r")
9482 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9485 && !arm_eliminable_register (operands[0])
9486 && !arm_eliminable_register (operands[1])
9487 && !arm_eliminable_register (operands[3])"
9488 "str%?b\\t%5, [%0, %3%S2]!"
9489 [(set_attr "type" "store1")
9490 (set_attr "predicable" "yes")]
9493 (define_insn "*strqi_shiftpredec"
9494 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9495 (match_operator:SI 2 "shift_operator"
9496 [(match_operand:SI 3 "s_register_operand" "r")
9497 (match_operand:SI 4 "const_shift_operand" "n")])))
9498 (match_operand:QI 5 "s_register_operand" "r"))
9499 (set (match_operand:SI 0 "s_register_operand" "=r")
9500 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9503 && !arm_eliminable_register (operands[0])
9504 && !arm_eliminable_register (operands[1])
9505 && !arm_eliminable_register (operands[3])"
9506 "str%?b\\t%5, [%0, -%3%S2]!"
9507 [(set_attr "type" "store1")
9508 (set_attr "predicable" "yes")]
9511 (define_insn "*loadqi_shiftpreinc"
9512 [(set (match_operand:QI 5 "s_register_operand" "=r")
9513 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9514 [(match_operand:SI 3 "s_register_operand" "r")
9515 (match_operand:SI 4 "const_shift_operand" "n")])
9516 (match_operand:SI 1 "s_register_operand" "0"))))
9517 (set (match_operand:SI 0 "s_register_operand" "=r")
9518 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9521 && !arm_eliminable_register (operands[0])
9522 && !arm_eliminable_register (operands[1])
9523 && !arm_eliminable_register (operands[3])"
9524 "ldr%?b\\t%5, [%0, %3%S2]!"
9525 [(set_attr "type" "load_byte")
9526 (set_attr "predicable" "yes")]
9529 (define_insn "*loadqi_shiftpredec"
9530 [(set (match_operand:QI 5 "s_register_operand" "=r")
9531 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9532 (match_operator:SI 2 "shift_operator"
9533 [(match_operand:SI 3 "s_register_operand" "r")
9534 (match_operand:SI 4 "const_shift_operand" "n")]))))
9535 (set (match_operand:SI 0 "s_register_operand" "=r")
9536 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9539 && !arm_eliminable_register (operands[0])
9540 && !arm_eliminable_register (operands[1])
9541 && !arm_eliminable_register (operands[3])"
9542 "ldr%?b\\t%5, [%0, -%3%S2]!"
9543 [(set_attr "type" "load_byte")
9544 (set_attr "predicable" "yes")]
9547 (define_insn "*strsi_shiftpreinc"
9548 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9549 [(match_operand:SI 3 "s_register_operand" "r")
9550 (match_operand:SI 4 "const_shift_operand" "n")])
9551 (match_operand:SI 1 "s_register_operand" "0")))
9552 (match_operand:SI 5 "s_register_operand" "r"))
9553 (set (match_operand:SI 0 "s_register_operand" "=r")
9554 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9557 && !arm_eliminable_register (operands[0])
9558 && !arm_eliminable_register (operands[1])
9559 && !arm_eliminable_register (operands[3])"
9560 "str%?\\t%5, [%0, %3%S2]!"
9561 [(set_attr "type" "store1")
9562 (set_attr "predicable" "yes")]
9565 (define_insn "*strsi_shiftpredec"
9566 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9567 (match_operator:SI 2 "shift_operator"
9568 [(match_operand:SI 3 "s_register_operand" "r")
9569 (match_operand:SI 4 "const_shift_operand" "n")])))
9570 (match_operand:SI 5 "s_register_operand" "r"))
9571 (set (match_operand:SI 0 "s_register_operand" "=r")
9572 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9575 && !arm_eliminable_register (operands[0])
9576 && !arm_eliminable_register (operands[1])
9577 && !arm_eliminable_register (operands[3])"
9578 "str%?\\t%5, [%0, -%3%S2]!"
9579 [(set_attr "type" "store1")
9580 (set_attr "predicable" "yes")]
9583 (define_insn "*loadsi_shiftpreinc"
9584 [(set (match_operand:SI 5 "s_register_operand" "=r")
9585 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9586 [(match_operand:SI 3 "s_register_operand" "r")
9587 (match_operand:SI 4 "const_shift_operand" "n")])
9588 (match_operand:SI 1 "s_register_operand" "0"))))
9589 (set (match_operand:SI 0 "s_register_operand" "=r")
9590 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9593 && !arm_eliminable_register (operands[0])
9594 && !arm_eliminable_register (operands[1])
9595 && !arm_eliminable_register (operands[3])"
9596 "ldr%?\\t%5, [%0, %3%S2]!"
9597 [(set_attr "type" "load1")
9598 (set_attr "predicable" "yes")]
9601 (define_insn "*loadsi_shiftpredec"
9602 [(set (match_operand:SI 5 "s_register_operand" "=r")
9603 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9604 (match_operator:SI 2 "shift_operator"
9605 [(match_operand:SI 3 "s_register_operand" "r")
9606 (match_operand:SI 4 "const_shift_operand" "n")]))))
9607 (set (match_operand:SI 0 "s_register_operand" "=r")
9608 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9611 && !arm_eliminable_register (operands[0])
9612 && !arm_eliminable_register (operands[1])
9613 && !arm_eliminable_register (operands[3])"
9614 "ldr%?\\t%5, [%0, -%3%S2]!"
9615 [(set_attr "type" "load1")
9616 (set_attr "predicable" "yes")])
9618 ; It can also support extended post-inc expressions, but combine doesn't
9620 ; It doesn't seem worth adding peepholes for anything but the most common
9621 ; cases since, unlike combine, the increment must immediately follow the load
9622 ; for this pattern to match.
9623 ; We must watch to see that the source/destination register isn't also the
9624 ; same as the base address register, and that if the index is a register,
9625 ; that it is not the same as the base address register. In such cases the
9626 ; instruction that we would generate would have UNPREDICTABLE behavior so
9630 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9631 (match_operand:QI 2 "s_register_operand" "r"))
9633 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9635 && (REGNO (operands[2]) != REGNO (operands[0]))
9636 && (GET_CODE (operands[1]) != REG
9637 || (REGNO (operands[1]) != REGNO (operands[0])))"
9638 "str%?b\\t%2, [%0], %1"
9642 [(set (match_operand:QI 0 "s_register_operand" "=r")
9643 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9645 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9647 && REGNO (operands[0]) != REGNO(operands[1])
9648 && (GET_CODE (operands[2]) != REG
9649 || REGNO(operands[0]) != REGNO (operands[2]))"
9650 "ldr%?b\\t%0, [%1], %2"
9654 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9655 (match_operand:SI 2 "s_register_operand" "r"))
9657 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9659 && (REGNO (operands[2]) != REGNO (operands[0]))
9660 && (GET_CODE (operands[1]) != REG
9661 || (REGNO (operands[1]) != REGNO (operands[0])))"
9662 "str%?\\t%2, [%0], %1"
9666 [(set (match_operand:SI 0 "s_register_operand" "=r")
9667 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9669 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9671 && REGNO (operands[0]) != REGNO(operands[1])
9672 && (GET_CODE (operands[2]) != REG
9673 || REGNO(operands[0]) != REGNO (operands[2]))"
9674 "ldr%?\\t%0, [%1], %2"
9678 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9679 (match_operand:SI 1 "index_operand" "rJ")))
9680 (match_operand:QI 2 "s_register_operand" "r"))
9681 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9683 && (REGNO (operands[2]) != REGNO (operands[0]))
9684 && (GET_CODE (operands[1]) != REG
9685 || (REGNO (operands[1]) != REGNO (operands[0])))"
9686 "str%?b\\t%2, [%0, %1]!"
9690 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9691 [(match_operand:SI 0 "s_register_operand" "r")
9692 (match_operand:SI 1 "const_int_operand" "n")])
9693 (match_operand:SI 2 "s_register_operand" "+r")))
9694 (match_operand:QI 3 "s_register_operand" "r"))
9695 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9698 && (REGNO (operands[3]) != REGNO (operands[2]))
9699 && (REGNO (operands[0]) != REGNO (operands[2]))"
9700 "str%?b\\t%3, [%2, %0%S4]!"
9703 ; This pattern is never tried by combine, so do it as a peephole
9706 [(set (match_operand:SI 0 "arm_general_register_operand" "")
9707 (match_operand:SI 1 "arm_general_register_operand" ""))
9708 (set (reg:CC CC_REGNUM)
9709 (compare:CC (match_dup 1) (const_int 0)))]
9711 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9712 (set (match_dup 0) (match_dup 1))])]
9716 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9717 ; reversed, check that the memory references aren't volatile.
9720 [(set (match_operand:SI 0 "s_register_operand" "=r")
9721 (match_operand:SI 4 "memory_operand" "m"))
9722 (set (match_operand:SI 1 "s_register_operand" "=r")
9723 (match_operand:SI 5 "memory_operand" "m"))
9724 (set (match_operand:SI 2 "s_register_operand" "=r")
9725 (match_operand:SI 6 "memory_operand" "m"))
9726 (set (match_operand:SI 3 "s_register_operand" "=r")
9727 (match_operand:SI 7 "memory_operand" "m"))]
9728 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9730 return emit_ldm_seq (operands, 4);
9735 [(set (match_operand:SI 0 "s_register_operand" "=r")
9736 (match_operand:SI 3 "memory_operand" "m"))
9737 (set (match_operand:SI 1 "s_register_operand" "=r")
9738 (match_operand:SI 4 "memory_operand" "m"))
9739 (set (match_operand:SI 2 "s_register_operand" "=r")
9740 (match_operand:SI 5 "memory_operand" "m"))]
9741 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9743 return emit_ldm_seq (operands, 3);
9748 [(set (match_operand:SI 0 "s_register_operand" "=r")
9749 (match_operand:SI 2 "memory_operand" "m"))
9750 (set (match_operand:SI 1 "s_register_operand" "=r")
9751 (match_operand:SI 3 "memory_operand" "m"))]
9752 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9754 return emit_ldm_seq (operands, 2);
9759 [(set (match_operand:SI 4 "memory_operand" "=m")
9760 (match_operand:SI 0 "s_register_operand" "r"))
9761 (set (match_operand:SI 5 "memory_operand" "=m")
9762 (match_operand:SI 1 "s_register_operand" "r"))
9763 (set (match_operand:SI 6 "memory_operand" "=m")
9764 (match_operand:SI 2 "s_register_operand" "r"))
9765 (set (match_operand:SI 7 "memory_operand" "=m")
9766 (match_operand:SI 3 "s_register_operand" "r"))]
9767 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9769 return emit_stm_seq (operands, 4);
9774 [(set (match_operand:SI 3 "memory_operand" "=m")
9775 (match_operand:SI 0 "s_register_operand" "r"))
9776 (set (match_operand:SI 4 "memory_operand" "=m")
9777 (match_operand:SI 1 "s_register_operand" "r"))
9778 (set (match_operand:SI 5 "memory_operand" "=m")
9779 (match_operand:SI 2 "s_register_operand" "r"))]
9780 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9782 return emit_stm_seq (operands, 3);
9787 [(set (match_operand:SI 2 "memory_operand" "=m")
9788 (match_operand:SI 0 "s_register_operand" "r"))
9789 (set (match_operand:SI 3 "memory_operand" "=m")
9790 (match_operand:SI 1 "s_register_operand" "r"))]
9791 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9793 return emit_stm_seq (operands, 2);
9798 [(set (match_operand:SI 0 "s_register_operand" "")
9799 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9801 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9802 [(match_operand:SI 3 "s_register_operand" "")
9803 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9804 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9806 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9807 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9812 ;; This split can be used because CC_Z mode implies that the following
9813 ;; branch will be an equality, or an unsigned inequality, so the sign
9814 ;; extension is not needed.
9817 [(set (reg:CC_Z CC_REGNUM)
9819 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9821 (match_operand 1 "const_int_operand" "")))
9822 (clobber (match_scratch:SI 2 ""))]
9824 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9825 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9826 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9827 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9829 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9833 (define_expand "prologue"
9834 [(clobber (const_int 0))]
9837 arm_expand_prologue ();
9839 thumb_expand_prologue ();
9844 (define_expand "epilogue"
9845 [(clobber (const_int 0))]
9848 if (current_function_calls_eh_return)
9849 emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
9851 thumb_expand_epilogue ();
9852 else if (USE_RETURN_INSN (FALSE))
9854 emit_jump_insn (gen_return ());
9857 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9859 gen_rtx_RETURN (VOIDmode)),
9865 ;; Note - although unspec_volatile's USE all hard registers,
9866 ;; USEs are ignored after relaod has completed. Thus we need
9867 ;; to add an unspec of the link register to ensure that flow
9868 ;; does not think that it is unused by the sibcall branch that
9869 ;; will replace the standard function epilogue.
9870 (define_insn "sibcall_epilogue"
9871 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9872 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9875 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9876 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9877 return arm_output_epilogue (next_nonnote_insn (insn));
9879 ;; Length is absolute worst case
9880 [(set_attr "length" "44")
9881 (set_attr "type" "block")
9882 ;; We don't clobber the conditions, but the potential length of this
9883 ;; operation is sufficient to make conditionalizing the sequence
9884 ;; unlikely to be profitable.
9885 (set_attr "conds" "clob")]
9888 (define_insn "*epilogue_insns"
9889 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9893 return arm_output_epilogue (NULL);
9894 else /* TARGET_THUMB */
9895 return thumb_unexpanded_epilogue ();
9897 ; Length is absolute worst case
9898 [(set_attr "length" "44")
9899 (set_attr "type" "block")
9900 ;; We don't clobber the conditions, but the potential length of this
9901 ;; operation is sufficient to make conditionalizing the sequence
9902 ;; unlikely to be profitable.
9903 (set_attr "conds" "clob")]
9906 (define_expand "eh_epilogue"
9907 [(use (match_operand:SI 0 "register_operand" ""))
9908 (use (match_operand:SI 1 "register_operand" ""))
9909 (use (match_operand:SI 2 "register_operand" ""))]
9913 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9914 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9916 rtx ra = gen_rtx_REG (Pmode, 2);
9918 emit_move_insn (ra, operands[2]);
9921 /* This is a hack -- we may have crystalized the function type too
9923 cfun->machine->func_type = 0;
9927 ;; This split is only used during output to reduce the number of patterns
9928 ;; that need assembler instructions adding to them. We allowed the setting
9929 ;; of the conditions to be implicit during rtl generation so that
9930 ;; the conditional compare patterns would work. However this conflicts to
9931 ;; some extent with the conditional data operations, so we have to split them
9935 [(set (match_operand:SI 0 "s_register_operand" "")
9936 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9937 [(match_operand 2 "" "") (match_operand 3 "" "")])
9939 (match_operand 4 "" "")))
9940 (clobber (reg:CC CC_REGNUM))]
9941 "TARGET_ARM && reload_completed"
9942 [(set (match_dup 5) (match_dup 6))
9943 (cond_exec (match_dup 7)
9944 (set (match_dup 0) (match_dup 4)))]
9947 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9948 operands[2], operands[3]);
9949 enum rtx_code rc = GET_CODE (operands[1]);
9951 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9952 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9953 if (mode == CCFPmode || mode == CCFPEmode)
9954 rc = reverse_condition_maybe_unordered (rc);
9956 rc = reverse_condition (rc);
9958 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
9963 [(set (match_operand:SI 0 "s_register_operand" "")
9964 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9965 [(match_operand 2 "" "") (match_operand 3 "" "")])
9966 (match_operand 4 "" "")
9968 (clobber (reg:CC CC_REGNUM))]
9969 "TARGET_ARM && reload_completed"
9970 [(set (match_dup 5) (match_dup 6))
9971 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
9972 (set (match_dup 0) (match_dup 4)))]
9975 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9976 operands[2], operands[3]);
9978 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9979 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9984 [(set (match_operand:SI 0 "s_register_operand" "")
9985 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9986 [(match_operand 2 "" "") (match_operand 3 "" "")])
9987 (match_operand 4 "" "")
9988 (match_operand 5 "" "")))
9989 (clobber (reg:CC CC_REGNUM))]
9990 "TARGET_ARM && reload_completed"
9991 [(set (match_dup 6) (match_dup 7))
9992 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9993 (set (match_dup 0) (match_dup 4)))
9994 (cond_exec (match_dup 8)
9995 (set (match_dup 0) (match_dup 5)))]
9998 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9999 operands[2], operands[3]);
10000 enum rtx_code rc = GET_CODE (operands[1]);
10002 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10003 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10004 if (mode == CCFPmode || mode == CCFPEmode)
10005 rc = reverse_condition_maybe_unordered (rc);
10007 rc = reverse_condition (rc);
10009 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10014 [(set (match_operand:SI 0 "s_register_operand" "")
10015 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10016 [(match_operand:SI 2 "s_register_operand" "")
10017 (match_operand:SI 3 "arm_add_operand" "")])
10018 (match_operand:SI 4 "arm_rhs_operand" "")
10020 (match_operand:SI 5 "s_register_operand" ""))))
10021 (clobber (reg:CC CC_REGNUM))]
10022 "TARGET_ARM && reload_completed"
10023 [(set (match_dup 6) (match_dup 7))
10024 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10025 (set (match_dup 0) (match_dup 4)))
10026 (cond_exec (match_dup 8)
10027 (set (match_dup 0) (not:SI (match_dup 5))))]
10030 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10031 operands[2], operands[3]);
10032 enum rtx_code rc = GET_CODE (operands[1]);
10034 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10035 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10036 if (mode == CCFPmode || mode == CCFPEmode)
10037 rc = reverse_condition_maybe_unordered (rc);
10039 rc = reverse_condition (rc);
10041 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10045 (define_insn "*cond_move_not"
10046 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10047 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10048 [(match_operand 3 "cc_register" "") (const_int 0)])
10049 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10051 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10055 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10056 [(set_attr "conds" "use")
10057 (set_attr "length" "4,8")]
10060 ;; The next two patterns occur when an AND operation is followed by a
10061 ;; scc insn sequence
10063 (define_insn "*sign_extract_onebit"
10064 [(set (match_operand:SI 0 "s_register_operand" "=r")
10065 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10067 (match_operand:SI 2 "const_int_operand" "n")))
10068 (clobber (reg:CC CC_REGNUM))]
10071 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10072 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10073 return \"mvnne\\t%0, #0\";
10075 [(set_attr "conds" "clob")
10076 (set_attr "length" "8")]
10079 (define_insn "*not_signextract_onebit"
10080 [(set (match_operand:SI 0 "s_register_operand" "=r")
10082 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10084 (match_operand:SI 2 "const_int_operand" "n"))))
10085 (clobber (reg:CC CC_REGNUM))]
10088 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10089 output_asm_insn (\"tst\\t%1, %2\", operands);
10090 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10091 return \"movne\\t%0, #0\";
10093 [(set_attr "conds" "clob")
10094 (set_attr "length" "12")]
10097 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10098 ;; expressions. For simplicity, the first register is also in the unspec
10100 (define_insn "*push_multi"
10101 [(match_parallel 2 "multi_register_push"
10102 [(set (match_operand:BLK 0 "memory_operand" "=m")
10103 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10104 UNSPEC_PUSH_MULT))])]
10108 int num_saves = XVECLEN (operands[2], 0);
10110 /* For the StrongARM at least it is faster to
10111 use STR to store only a single register. */
10112 if (num_saves == 1)
10113 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10119 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10121 for (i = 1; i < num_saves; i++)
10123 strcat (pattern, \", %|\");
10125 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10128 strcat (pattern, \"}\");
10129 output_asm_insn (pattern, operands);
10134 [(set_attr "type" "store4")]
10137 (define_insn "stack_tie"
10138 [(set (mem:BLK (scratch))
10139 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10140 (match_operand:SI 1 "s_register_operand" "r")]
10144 [(set_attr "length" "0")]
10147 ;; Similarly for the floating point registers
10148 (define_insn "*push_fp_multi"
10149 [(match_parallel 2 "multi_register_push"
10150 [(set (match_operand:BLK 0 "memory_operand" "=m")
10151 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10152 UNSPEC_PUSH_MULT))])]
10153 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10158 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10159 output_asm_insn (pattern, operands);
10162 [(set_attr "type" "f_store")]
10165 ;; Special patterns for dealing with the constant pool
10167 (define_insn "align_4"
10168 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10171 assemble_align (32);
10176 (define_insn "align_8"
10177 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10180 assemble_align (64);
10185 (define_insn "consttable_end"
10186 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10189 making_const_table = FALSE;
10194 (define_insn "consttable_1"
10195 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10198 making_const_table = TRUE;
10199 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10200 assemble_zeros (3);
10203 [(set_attr "length" "4")]
10206 (define_insn "consttable_2"
10207 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10210 making_const_table = TRUE;
10211 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10212 assemble_zeros (2);
10215 [(set_attr "length" "4")]
10218 (define_insn "consttable_4"
10219 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10223 making_const_table = TRUE;
10224 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10229 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10230 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10234 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10239 [(set_attr "length" "4")]
10242 (define_insn "consttable_8"
10243 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10247 making_const_table = TRUE;
10248 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10253 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10254 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10258 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10263 [(set_attr "length" "8")]
10266 ;; Miscellaneous Thumb patterns
10268 (define_expand "tablejump"
10269 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10270 (use (label_ref (match_operand 1 "" "")))])]
10275 /* Hopefully, CSE will eliminate this copy. */
10276 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10277 rtx reg2 = gen_reg_rtx (SImode);
10279 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10280 operands[0] = reg2;
10285 ;; NB never uses BX.
10286 (define_insn "*thumb_tablejump"
10287 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10288 (use (label_ref (match_operand 1 "" "")))]
10291 [(set_attr "length" "2")]
10294 ;; V5 Instructions,
10296 (define_insn "clzsi2"
10297 [(set (match_operand:SI 0 "s_register_operand" "=r")
10298 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10299 "TARGET_ARM && arm_arch5"
10301 [(set_attr "predicable" "yes")])
10303 (define_expand "ffssi2"
10304 [(set (match_operand:SI 0 "s_register_operand" "")
10305 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10306 "TARGET_ARM && arm_arch5"
10311 t1 = gen_reg_rtx (SImode);
10312 t2 = gen_reg_rtx (SImode);
10313 t3 = gen_reg_rtx (SImode);
10315 emit_insn (gen_negsi2 (t1, operands[1]));
10316 emit_insn (gen_andsi3 (t2, operands[1], t1));
10317 emit_insn (gen_clzsi2 (t3, t2));
10318 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10323 (define_expand "ctzsi2"
10324 [(set (match_operand:SI 0 "s_register_operand" "")
10325 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10326 "TARGET_ARM && arm_arch5"
10331 t1 = gen_reg_rtx (SImode);
10332 t2 = gen_reg_rtx (SImode);
10333 t3 = gen_reg_rtx (SImode);
10335 emit_insn (gen_negsi2 (t1, operands[1]));
10336 emit_insn (gen_andsi3 (t2, operands[1], t1));
10337 emit_insn (gen_clzsi2 (t3, t2));
10338 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10343 ;; V5E instructions.
10345 (define_insn "prefetch"
10346 [(prefetch (match_operand:SI 0 "address_operand" "p")
10347 (match_operand:SI 1 "" "")
10348 (match_operand:SI 2 "" ""))]
10349 "TARGET_ARM && arm_arch5e"
10352 ;; General predication pattern
10355 [(match_operator 0 "arm_comparison_operator"
10356 [(match_operand 1 "cc_register" "")
10362 (define_insn "prologue_use"
10363 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10365 "%@ %0 needed for prologue"
10369 ;; Patterns for exception handling
10371 (define_expand "eh_return"
10372 [(use (match_operand 0 "general_operand" ""))]
10377 emit_insn (gen_arm_eh_return (operands[0]));
10379 emit_insn (gen_thumb_eh_return (operands[0]));
10384 ;; We can't expand this before we know where the link register is stored.
10385 (define_insn_and_split "arm_eh_return"
10386 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10388 (clobber (match_scratch:SI 1 "=&r"))]
10391 "&& reload_completed"
10395 arm_set_return_address (operands[0], operands[1]);
10400 (define_insn_and_split "thumb_eh_return"
10401 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
10403 (clobber (match_scratch:SI 1 "=&l"))]
10406 "&& reload_completed"
10410 thumb_set_return_address (operands[0], operands[1]);
10415 ;; Load the FPA co-processor patterns
10417 ;; Load the Maverick co-processor patterns
10418 (include "cirrus.md")
10419 ;; Load the Intel Wireless Multimedia Extension patterns
10420 (include "iwmmxt.md")
10421 ;; Load the VFP co-processor patterns