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"))
293 ;;---------------------------------------------------------------------------
296 ; A list of modes that are exactly 64 bits in size. We use this to expand
297 ; some splits that are the same for all modes when operating on ARM
299 (define_mode_macro ANY64 [DI DF V8QI V4HI V2SI V2SF])
301 ;;---------------------------------------------------------------------------
304 (include "predicates.md")
306 ;;---------------------------------------------------------------------------
307 ;; Pipeline descriptions
309 ;; Processor type. This is created automatically from arm-cores.def.
310 (include "arm-tune.md")
312 ;; True if the generic scheduling description should be used.
314 (define_attr "generic_sched" "yes,no"
316 (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
318 (const_string "yes"))))
320 (include "arm-generic.md")
321 (include "arm926ejs.md")
322 (include "arm1026ejs.md")
323 (include "arm1136jfs.md")
326 ;;---------------------------------------------------------------------------
331 ;; Note: For DImode insns, there is normally no reason why operands should
332 ;; not be in the same register, what we don't want is for something being
333 ;; written to partially overlap something that is an input.
334 ;; Cirrus 64bit additions should not be split because we have a native
335 ;; 64bit addition instructions.
337 (define_expand "adddi3"
339 [(set (match_operand:DI 0 "s_register_operand" "")
340 (plus:DI (match_operand:DI 1 "s_register_operand" "")
341 (match_operand:DI 2 "s_register_operand" "")))
342 (clobber (reg:CC CC_REGNUM))])]
345 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
347 if (!cirrus_fp_register (operands[0], DImode))
348 operands[0] = force_reg (DImode, operands[0]);
349 if (!cirrus_fp_register (operands[1], DImode))
350 operands[1] = force_reg (DImode, operands[1]);
351 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
357 if (GET_CODE (operands[1]) != REG)
358 operands[1] = force_reg (SImode, operands[1]);
359 if (GET_CODE (operands[2]) != REG)
360 operands[2] = force_reg (SImode, operands[2]);
365 (define_insn "*thumb_adddi3"
366 [(set (match_operand:DI 0 "register_operand" "=l")
367 (plus:DI (match_operand:DI 1 "register_operand" "%0")
368 (match_operand:DI 2 "register_operand" "l")))
369 (clobber (reg:CC CC_REGNUM))
372 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
373 [(set_attr "length" "4")]
376 (define_insn_and_split "*arm_adddi3"
377 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
378 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
379 (match_operand:DI 2 "s_register_operand" "r, 0")))
380 (clobber (reg:CC CC_REGNUM))]
381 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
383 "TARGET_ARM && reload_completed"
384 [(parallel [(set (reg:CC_C CC_REGNUM)
385 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
387 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
388 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
389 (plus:SI (match_dup 4) (match_dup 5))))]
392 operands[3] = gen_highpart (SImode, operands[0]);
393 operands[0] = gen_lowpart (SImode, operands[0]);
394 operands[4] = gen_highpart (SImode, operands[1]);
395 operands[1] = gen_lowpart (SImode, operands[1]);
396 operands[5] = gen_highpart (SImode, operands[2]);
397 operands[2] = gen_lowpart (SImode, operands[2]);
399 [(set_attr "conds" "clob")
400 (set_attr "length" "8")]
403 (define_insn_and_split "*adddi_sesidi_di"
404 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
405 (plus:DI (sign_extend:DI
406 (match_operand:SI 2 "s_register_operand" "r,r"))
407 (match_operand:DI 1 "s_register_operand" "r,0")))
408 (clobber (reg:CC CC_REGNUM))]
409 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
411 "TARGET_ARM && reload_completed"
412 [(parallel [(set (reg:CC_C CC_REGNUM)
413 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
415 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
416 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
417 (plus:SI (ashiftrt:SI (match_dup 2)
422 operands[3] = gen_highpart (SImode, operands[0]);
423 operands[0] = gen_lowpart (SImode, operands[0]);
424 operands[4] = gen_highpart (SImode, operands[1]);
425 operands[1] = gen_lowpart (SImode, operands[1]);
426 operands[2] = gen_lowpart (SImode, operands[2]);
428 [(set_attr "conds" "clob")
429 (set_attr "length" "8")]
432 (define_insn_and_split "*adddi_zesidi_di"
433 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
434 (plus:DI (zero_extend:DI
435 (match_operand:SI 2 "s_register_operand" "r,r"))
436 (match_operand:DI 1 "s_register_operand" "r,0")))
437 (clobber (reg:CC CC_REGNUM))]
438 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
440 "TARGET_ARM && reload_completed"
441 [(parallel [(set (reg:CC_C CC_REGNUM)
442 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
444 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
445 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
446 (plus:SI (match_dup 4) (const_int 0))))]
449 operands[3] = gen_highpart (SImode, operands[0]);
450 operands[0] = gen_lowpart (SImode, operands[0]);
451 operands[4] = gen_highpart (SImode, operands[1]);
452 operands[1] = gen_lowpart (SImode, operands[1]);
453 operands[2] = gen_lowpart (SImode, operands[2]);
455 [(set_attr "conds" "clob")
456 (set_attr "length" "8")]
459 (define_expand "addsi3"
460 [(set (match_operand:SI 0 "s_register_operand" "")
461 (plus:SI (match_operand:SI 1 "s_register_operand" "")
462 (match_operand:SI 2 "reg_or_int_operand" "")))]
465 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
467 arm_split_constant (PLUS, SImode, NULL_RTX,
468 INTVAL (operands[2]), operands[0], operands[1],
469 optimize && !no_new_pseudos);
475 ; If there is a scratch available, this will be faster than synthesizing the
478 [(match_scratch:SI 3 "r")
479 (set (match_operand:SI 0 "arm_general_register_operand" "")
480 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
481 (match_operand:SI 2 "const_int_operand" "")))]
483 !(const_ok_for_arm (INTVAL (operands[2]))
484 || const_ok_for_arm (-INTVAL (operands[2])))
485 && const_ok_for_arm (~INTVAL (operands[2]))"
486 [(set (match_dup 3) (match_dup 2))
487 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
491 (define_insn_and_split "*arm_addsi3"
492 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
493 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
494 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
501 GET_CODE (operands[2]) == CONST_INT
502 && !(const_ok_for_arm (INTVAL (operands[2]))
503 || const_ok_for_arm (-INTVAL (operands[2])))"
504 [(clobber (const_int 0))]
506 arm_split_constant (PLUS, SImode, curr_insn,
507 INTVAL (operands[2]), operands[0],
511 [(set_attr "length" "4,4,16")
512 (set_attr "predicable" "yes")]
515 ;; Register group 'k' is a single register group containing only the stack
516 ;; register. Trying to reload it will always fail catastrophically,
517 ;; so never allow those alternatives to match if reloading is needed.
519 (define_insn "*thumb_addsi3"
520 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
521 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
522 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
525 static const char * const asms[] =
527 \"add\\t%0, %0, %2\",
528 \"sub\\t%0, %0, #%n2\",
529 \"add\\t%0, %1, %2\",
530 \"add\\t%0, %0, %2\",
531 \"add\\t%0, %0, %2\",
532 \"add\\t%0, %1, %2\",
535 if ((which_alternative == 2 || which_alternative == 6)
536 && GET_CODE (operands[2]) == CONST_INT
537 && INTVAL (operands[2]) < 0)
538 return \"sub\\t%0, %1, #%n2\";
539 return asms[which_alternative];
541 [(set_attr "length" "2")]
544 ;; Reloading and elimination of the frame pointer can
545 ;; sometimes cause this optimization to be missed.
547 [(set (match_operand:SI 0 "arm_general_register_operand" "")
548 (match_operand:SI 1 "const_int_operand" ""))
550 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
552 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
553 && (INTVAL (operands[1]) & 3) == 0"
554 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
558 (define_insn "*addsi3_compare0"
559 [(set (reg:CC_NOOV CC_REGNUM)
561 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
562 (match_operand:SI 2 "arm_add_operand" "rI,L"))
564 (set (match_operand:SI 0 "s_register_operand" "=r,r")
565 (plus:SI (match_dup 1) (match_dup 2)))]
569 sub%?s\\t%0, %1, #%n2"
570 [(set_attr "conds" "set")]
573 (define_insn "*addsi3_compare0_scratch"
574 [(set (reg:CC_NOOV CC_REGNUM)
576 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
577 (match_operand:SI 1 "arm_add_operand" "rI,L"))
583 [(set_attr "conds" "set")]
586 (define_insn "*compare_negsi_si"
587 [(set (reg:CC_Z CC_REGNUM)
589 (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
590 (match_operand:SI 1 "s_register_operand" "r")))]
593 [(set_attr "conds" "set")]
596 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
597 ;; addend is a constant.
598 (define_insn "*cmpsi2_addneg"
599 [(set (reg:CC CC_REGNUM)
601 (match_operand:SI 1 "s_register_operand" "r,r")
602 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
603 (set (match_operand:SI 0 "s_register_operand" "=r,r")
604 (plus:SI (match_dup 1)
605 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
606 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
609 add%?s\\t%0, %1, #%n2"
610 [(set_attr "conds" "set")]
613 ;; Convert the sequence
615 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
619 ;; bcs dest ((unsigned)rn >= 1)
620 ;; similarly for the beq variant using bcc.
621 ;; This is a common looping idiom (while (n--))
623 [(set (match_operand:SI 0 "arm_general_register_operand" "")
624 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
626 (set (match_operand 2 "cc_register" "")
627 (compare (match_dup 0) (const_int -1)))
629 (if_then_else (match_operator 3 "equality_operator"
630 [(match_dup 2) (const_int 0)])
631 (match_operand 4 "" "")
632 (match_operand 5 "" "")))]
633 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
637 (match_dup 1) (const_int 1)))
638 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
640 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
643 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
644 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
647 operands[2], const0_rtx);"
650 ;; The next four insns work because they compare the result with one of
651 ;; the operands, and we know that the use of the condition code is
652 ;; either GEU or LTU, so we can use the carry flag from the addition
653 ;; instead of doing the compare a second time.
654 (define_insn "*addsi3_compare_op1"
655 [(set (reg:CC_C CC_REGNUM)
657 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
658 (match_operand:SI 2 "arm_add_operand" "rI,L"))
660 (set (match_operand:SI 0 "s_register_operand" "=r,r")
661 (plus:SI (match_dup 1) (match_dup 2)))]
665 sub%?s\\t%0, %1, #%n2"
666 [(set_attr "conds" "set")]
669 (define_insn "*addsi3_compare_op2"
670 [(set (reg:CC_C CC_REGNUM)
672 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
673 (match_operand:SI 2 "arm_add_operand" "rI,L"))
675 (set (match_operand:SI 0 "s_register_operand" "=r,r")
676 (plus:SI (match_dup 1) (match_dup 2)))]
680 sub%?s\\t%0, %1, #%n2"
681 [(set_attr "conds" "set")]
684 (define_insn "*compare_addsi2_op0"
685 [(set (reg:CC_C CC_REGNUM)
687 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
688 (match_operand:SI 1 "arm_add_operand" "rI,L"))
694 [(set_attr "conds" "set")]
697 (define_insn "*compare_addsi2_op1"
698 [(set (reg:CC_C CC_REGNUM)
700 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
701 (match_operand:SI 1 "arm_add_operand" "rI,L"))
707 [(set_attr "conds" "set")]
710 (define_insn "*addsi3_carryin"
711 [(set (match_operand:SI 0 "s_register_operand" "=r")
712 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
713 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
714 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
717 [(set_attr "conds" "use")]
720 (define_insn "*addsi3_carryin_shift"
721 [(set (match_operand:SI 0 "s_register_operand" "=r")
722 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
724 (match_operator:SI 2 "shift_operator"
725 [(match_operand:SI 3 "s_register_operand" "r")
726 (match_operand:SI 4 "reg_or_int_operand" "rM")])
727 (match_operand:SI 1 "s_register_operand" "r"))))]
729 "adc%?\\t%0, %1, %3%S2"
730 [(set_attr "conds" "use")
731 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
732 (const_string "alu_shift")
733 (const_string "alu_shift_reg")))]
736 (define_insn "*addsi3_carryin_alt1"
737 [(set (match_operand:SI 0 "s_register_operand" "=r")
738 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
739 (match_operand:SI 2 "arm_rhs_operand" "rI"))
740 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
743 [(set_attr "conds" "use")]
746 (define_insn "*addsi3_carryin_alt2"
747 [(set (match_operand:SI 0 "s_register_operand" "=r")
748 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
749 (match_operand:SI 1 "s_register_operand" "r"))
750 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
753 [(set_attr "conds" "use")]
756 (define_insn "*addsi3_carryin_alt3"
757 [(set (match_operand:SI 0 "s_register_operand" "=r")
758 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
759 (match_operand:SI 2 "arm_rhs_operand" "rI"))
760 (match_operand:SI 1 "s_register_operand" "r")))]
763 [(set_attr "conds" "use")]
766 (define_insn "incscc"
767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
768 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
769 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
770 (match_operand:SI 1 "s_register_operand" "0,?r")))]
774 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
775 [(set_attr "conds" "use")
776 (set_attr "length" "4,8")]
779 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
781 [(set (match_operand:SI 0 "s_register_operand" "")
782 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
783 (match_operand:SI 2 "s_register_operand" ""))
785 (clobber (match_operand:SI 3 "s_register_operand" ""))]
787 [(set (match_dup 3) (match_dup 1))
788 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
790 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
793 (define_expand "addsf3"
794 [(set (match_operand:SF 0 "s_register_operand" "")
795 (plus:SF (match_operand:SF 1 "s_register_operand" "")
796 (match_operand:SF 2 "arm_float_add_operand" "")))]
797 "TARGET_ARM && TARGET_HARD_FLOAT"
800 && !cirrus_fp_register (operands[2], SFmode))
801 operands[2] = force_reg (SFmode, operands[2]);
804 (define_expand "adddf3"
805 [(set (match_operand:DF 0 "s_register_operand" "")
806 (plus:DF (match_operand:DF 1 "s_register_operand" "")
807 (match_operand:DF 2 "arm_float_add_operand" "")))]
808 "TARGET_ARM && TARGET_HARD_FLOAT"
811 && !cirrus_fp_register (operands[2], DFmode))
812 operands[2] = force_reg (DFmode, operands[2]);
815 (define_expand "subdi3"
817 [(set (match_operand:DI 0 "s_register_operand" "")
818 (minus:DI (match_operand:DI 1 "s_register_operand" "")
819 (match_operand:DI 2 "s_register_operand" "")))
820 (clobber (reg:CC CC_REGNUM))])]
823 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
825 && cirrus_fp_register (operands[0], DImode)
826 && cirrus_fp_register (operands[1], DImode))
828 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
834 if (GET_CODE (operands[1]) != REG)
835 operands[1] = force_reg (SImode, operands[1]);
836 if (GET_CODE (operands[2]) != REG)
837 operands[2] = force_reg (SImode, operands[2]);
842 (define_insn "*arm_subdi3"
843 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
844 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
845 (match_operand:DI 2 "s_register_operand" "r,0,0")))
846 (clobber (reg:CC CC_REGNUM))]
848 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
849 [(set_attr "conds" "clob")
850 (set_attr "length" "8")]
853 (define_insn "*thumb_subdi3"
854 [(set (match_operand:DI 0 "register_operand" "=l")
855 (minus:DI (match_operand:DI 1 "register_operand" "0")
856 (match_operand:DI 2 "register_operand" "l")))
857 (clobber (reg:CC CC_REGNUM))]
859 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
860 [(set_attr "length" "4")]
863 (define_insn "*subdi_di_zesidi"
864 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
865 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
867 (match_operand:SI 2 "s_register_operand" "r,r"))))
868 (clobber (reg:CC CC_REGNUM))]
870 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
871 [(set_attr "conds" "clob")
872 (set_attr "length" "8")]
875 (define_insn "*subdi_di_sesidi"
876 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
877 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
879 (match_operand:SI 2 "s_register_operand" "r,r"))))
880 (clobber (reg:CC CC_REGNUM))]
882 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
883 [(set_attr "conds" "clob")
884 (set_attr "length" "8")]
887 (define_insn "*subdi_zesidi_di"
888 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
889 (minus:DI (zero_extend:DI
890 (match_operand:SI 2 "s_register_operand" "r,r"))
891 (match_operand:DI 1 "s_register_operand" "?r,0")))
892 (clobber (reg:CC CC_REGNUM))]
894 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
895 [(set_attr "conds" "clob")
896 (set_attr "length" "8")]
899 (define_insn "*subdi_sesidi_di"
900 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
901 (minus:DI (sign_extend:DI
902 (match_operand:SI 2 "s_register_operand" "r,r"))
903 (match_operand:DI 1 "s_register_operand" "?r,0")))
904 (clobber (reg:CC CC_REGNUM))]
906 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
907 [(set_attr "conds" "clob")
908 (set_attr "length" "8")]
911 (define_insn "*subdi_zesidi_zesidi"
912 [(set (match_operand:DI 0 "s_register_operand" "=r")
913 (minus:DI (zero_extend:DI
914 (match_operand:SI 1 "s_register_operand" "r"))
916 (match_operand:SI 2 "s_register_operand" "r"))))
917 (clobber (reg:CC CC_REGNUM))]
919 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
920 [(set_attr "conds" "clob")
921 (set_attr "length" "8")]
924 (define_expand "subsi3"
925 [(set (match_operand:SI 0 "s_register_operand" "")
926 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
927 (match_operand:SI 2 "s_register_operand" "")))]
930 if (GET_CODE (operands[1]) == CONST_INT)
934 arm_split_constant (MINUS, SImode, NULL_RTX,
935 INTVAL (operands[1]), operands[0],
936 operands[2], optimize && !no_new_pseudos);
939 else /* TARGET_THUMB */
940 operands[1] = force_reg (SImode, operands[1]);
945 (define_insn "*thumb_subsi3_insn"
946 [(set (match_operand:SI 0 "register_operand" "=l")
947 (minus:SI (match_operand:SI 1 "register_operand" "l")
948 (match_operand:SI 2 "register_operand" "l")))]
951 [(set_attr "length" "2")]
954 (define_insn_and_split "*arm_subsi3_insn"
955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
956 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
957 (match_operand:SI 2 "s_register_operand" "r,r")))]
963 && GET_CODE (operands[1]) == CONST_INT
964 && !const_ok_for_arm (INTVAL (operands[1]))"
965 [(clobber (const_int 0))]
967 arm_split_constant (MINUS, SImode, curr_insn,
968 INTVAL (operands[1]), operands[0], operands[2], 0);
971 [(set_attr "length" "4,16")
972 (set_attr "predicable" "yes")]
976 [(match_scratch:SI 3 "r")
977 (set (match_operand:SI 0 "arm_general_register_operand" "")
978 (minus:SI (match_operand:SI 1 "const_int_operand" "")
979 (match_operand:SI 2 "arm_general_register_operand" "")))]
981 && !const_ok_for_arm (INTVAL (operands[1]))
982 && const_ok_for_arm (~INTVAL (operands[1]))"
983 [(set (match_dup 3) (match_dup 1))
984 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
988 (define_insn "*subsi3_compare0"
989 [(set (reg:CC_NOOV CC_REGNUM)
991 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
992 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
994 (set (match_operand:SI 0 "s_register_operand" "=r,r")
995 (minus:SI (match_dup 1) (match_dup 2)))]
1000 [(set_attr "conds" "set")]
1003 (define_insn "decscc"
1004 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1005 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1006 (match_operator:SI 2 "arm_comparison_operator"
1007 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1011 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1012 [(set_attr "conds" "use")
1013 (set_attr "length" "*,8")]
1016 (define_expand "subsf3"
1017 [(set (match_operand:SF 0 "s_register_operand" "")
1018 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1019 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1020 "TARGET_ARM && TARGET_HARD_FLOAT"
1022 if (TARGET_MAVERICK)
1024 if (!cirrus_fp_register (operands[1], SFmode))
1025 operands[1] = force_reg (SFmode, operands[1]);
1026 if (!cirrus_fp_register (operands[2], SFmode))
1027 operands[2] = force_reg (SFmode, operands[2]);
1031 (define_expand "subdf3"
1032 [(set (match_operand:DF 0 "s_register_operand" "")
1033 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1034 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1035 "TARGET_ARM && TARGET_HARD_FLOAT"
1037 if (TARGET_MAVERICK)
1039 if (!cirrus_fp_register (operands[1], DFmode))
1040 operands[1] = force_reg (DFmode, operands[1]);
1041 if (!cirrus_fp_register (operands[2], DFmode))
1042 operands[2] = force_reg (DFmode, operands[2]);
1047 ;; Multiplication insns
1049 (define_expand "mulsi3"
1050 [(set (match_operand:SI 0 "s_register_operand" "")
1051 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1052 (match_operand:SI 1 "s_register_operand" "")))]
1057 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1058 (define_insn "*arm_mulsi3"
1059 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1060 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1061 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1063 "mul%?\\t%0, %2, %1"
1064 [(set_attr "insn" "mul")
1065 (set_attr "predicable" "yes")]
1068 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1069 ; 1 and 2; are the same, because reload will make operand 0 match
1070 ; operand 1 without realizing that this conflicts with operand 2. We fix
1071 ; this by adding another alternative to match this case, and then `reload'
1072 ; it ourselves. This alternative must come first.
1073 (define_insn "*thumb_mulsi3"
1074 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1075 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1076 (match_operand:SI 2 "register_operand" "l,l,l")))]
1079 if (which_alternative < 2)
1080 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1082 return \"mul\\t%0, %0, %2\";
1084 [(set_attr "length" "4,4,2")
1085 (set_attr "insn" "mul")]
1088 (define_insn "*mulsi3_compare0"
1089 [(set (reg:CC_NOOV CC_REGNUM)
1090 (compare:CC_NOOV (mult:SI
1091 (match_operand:SI 2 "s_register_operand" "r,r")
1092 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1094 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1095 (mult:SI (match_dup 2) (match_dup 1)))]
1097 "mul%?s\\t%0, %2, %1"
1098 [(set_attr "conds" "set")
1099 (set_attr "insn" "muls")]
1102 (define_insn "*mulsi_compare0_scratch"
1103 [(set (reg:CC_NOOV CC_REGNUM)
1104 (compare:CC_NOOV (mult:SI
1105 (match_operand:SI 2 "s_register_operand" "r,r")
1106 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1108 (clobber (match_scratch:SI 0 "=&r,&r"))]
1110 "mul%?s\\t%0, %2, %1"
1111 [(set_attr "conds" "set")
1112 (set_attr "insn" "muls")]
1115 ;; Unnamed templates to match MLA instruction.
1117 (define_insn "*mulsi3addsi"
1118 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1120 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1121 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1122 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1124 "mla%?\\t%0, %2, %1, %3"
1125 [(set_attr "insn" "mla")
1126 (set_attr "predicable" "yes")]
1129 (define_insn "*mulsi3addsi_compare0"
1130 [(set (reg:CC_NOOV CC_REGNUM)
1133 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1134 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1135 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1137 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1138 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1141 "mla%?s\\t%0, %2, %1, %3"
1142 [(set_attr "conds" "set")
1143 (set_attr "insn" "mlas")]
1146 (define_insn "*mulsi3addsi_compare0_scratch"
1147 [(set (reg:CC_NOOV CC_REGNUM)
1150 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1151 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1152 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1154 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1156 "mla%?s\\t%0, %2, %1, %3"
1157 [(set_attr "conds" "set")
1158 (set_attr "insn" "mlas")]
1161 ;; Unnamed template to match long long multiply-accumulate (smlal)
1163 (define_insn "*mulsidi3adddi"
1164 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1167 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1168 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1169 (match_operand:DI 1 "s_register_operand" "0")))]
1170 "TARGET_ARM && arm_arch3m"
1171 "smlal%?\\t%Q0, %R0, %3, %2"
1172 [(set_attr "insn" "smlal")
1173 (set_attr "predicable" "yes")]
1176 (define_insn "mulsidi3"
1177 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1179 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1180 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1181 "TARGET_ARM && arm_arch3m"
1182 "smull%?\\t%Q0, %R0, %1, %2"
1183 [(set_attr "insn" "smull")
1184 (set_attr "predicable" "yes")]
1187 (define_insn "umulsidi3"
1188 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1190 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1191 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1192 "TARGET_ARM && arm_arch3m"
1193 "umull%?\\t%Q0, %R0, %1, %2"
1194 [(set_attr "insn" "umull")
1195 (set_attr "predicable" "yes")]
1198 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1200 (define_insn "*umulsidi3adddi"
1201 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1204 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1205 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1206 (match_operand:DI 1 "s_register_operand" "0")))]
1207 "TARGET_ARM && arm_arch3m"
1208 "umlal%?\\t%Q0, %R0, %3, %2"
1209 [(set_attr "insn" "umlal")
1210 (set_attr "predicable" "yes")]
1213 (define_insn "smulsi3_highpart"
1214 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1218 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1219 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1221 (clobber (match_scratch:SI 3 "=&r,&r"))]
1222 "TARGET_ARM && arm_arch3m"
1223 "smull%?\\t%3, %0, %2, %1"
1224 [(set_attr "insn" "smull")
1225 (set_attr "predicable" "yes")]
1228 (define_insn "umulsi3_highpart"
1229 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1233 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1234 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1236 (clobber (match_scratch:SI 3 "=&r,&r"))]
1237 "TARGET_ARM && arm_arch3m"
1238 "umull%?\\t%3, %0, %2, %1"
1239 [(set_attr "insn" "umull")
1240 (set_attr "predicable" "yes")]
1243 (define_insn "mulhisi3"
1244 [(set (match_operand:SI 0 "s_register_operand" "=r")
1245 (mult:SI (sign_extend:SI
1246 (match_operand:HI 1 "s_register_operand" "%r"))
1248 (match_operand:HI 2 "s_register_operand" "r"))))]
1249 "TARGET_ARM && arm_arch5e"
1250 "smulbb%?\\t%0, %1, %2"
1251 [(set_attr "insn" "smulxy")
1252 (set_attr "predicable" "yes")]
1255 (define_insn "*mulhisi3tb"
1256 [(set (match_operand:SI 0 "s_register_operand" "=r")
1257 (mult:SI (ashiftrt:SI
1258 (match_operand:SI 1 "s_register_operand" "r")
1261 (match_operand:HI 2 "s_register_operand" "r"))))]
1262 "TARGET_ARM && arm_arch5e"
1263 "smultb%?\\t%0, %1, %2"
1264 [(set_attr "insn" "smulxy")
1265 (set_attr "predicable" "yes")]
1268 (define_insn "*mulhisi3bt"
1269 [(set (match_operand:SI 0 "s_register_operand" "=r")
1270 (mult:SI (sign_extend:SI
1271 (match_operand:HI 1 "s_register_operand" "r"))
1273 (match_operand:SI 2 "s_register_operand" "r")
1275 "TARGET_ARM && arm_arch5e"
1276 "smulbt%?\\t%0, %1, %2"
1277 [(set_attr "insn" "smulxy")
1278 (set_attr "predicable" "yes")]
1281 (define_insn "*mulhisi3tt"
1282 [(set (match_operand:SI 0 "s_register_operand" "=r")
1283 (mult:SI (ashiftrt:SI
1284 (match_operand:SI 1 "s_register_operand" "r")
1287 (match_operand:SI 2 "s_register_operand" "r")
1289 "TARGET_ARM && arm_arch5e"
1290 "smultt%?\\t%0, %1, %2"
1291 [(set_attr "insn" "smulxy")
1292 (set_attr "predicable" "yes")]
1295 (define_insn "*mulhisi3addsi"
1296 [(set (match_operand:SI 0 "s_register_operand" "=r")
1297 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1298 (mult:SI (sign_extend:SI
1299 (match_operand:HI 2 "s_register_operand" "%r"))
1301 (match_operand:HI 3 "s_register_operand" "r")))))]
1302 "TARGET_ARM && arm_arch5e"
1303 "smlabb%?\\t%0, %2, %3, %1"
1304 [(set_attr "insn" "smlaxy")
1305 (set_attr "predicable" "yes")]
1308 (define_insn "*mulhidi3adddi"
1309 [(set (match_operand:DI 0 "s_register_operand" "=r")
1311 (match_operand:DI 1 "s_register_operand" "0")
1312 (mult:DI (sign_extend:DI
1313 (match_operand:HI 2 "s_register_operand" "%r"))
1315 (match_operand:HI 3 "s_register_operand" "r")))))]
1316 "TARGET_ARM && arm_arch5e"
1317 "smlalbb%?\\t%Q0, %R0, %2, %3"
1318 [(set_attr "insn" "smlalxy")
1319 (set_attr "predicable" "yes")])
1321 (define_expand "mulsf3"
1322 [(set (match_operand:SF 0 "s_register_operand" "")
1323 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1324 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1325 "TARGET_ARM && TARGET_HARD_FLOAT"
1328 && !cirrus_fp_register (operands[2], SFmode))
1329 operands[2] = force_reg (SFmode, operands[2]);
1332 (define_expand "muldf3"
1333 [(set (match_operand:DF 0 "s_register_operand" "")
1334 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1335 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1336 "TARGET_ARM && TARGET_HARD_FLOAT"
1339 && !cirrus_fp_register (operands[2], DFmode))
1340 operands[2] = force_reg (DFmode, operands[2]);
1345 (define_expand "divsf3"
1346 [(set (match_operand:SF 0 "s_register_operand" "")
1347 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1348 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1349 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1352 (define_expand "divdf3"
1353 [(set (match_operand:DF 0 "s_register_operand" "")
1354 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1355 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1356 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1361 (define_expand "modsf3"
1362 [(set (match_operand:SF 0 "s_register_operand" "")
1363 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1364 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1365 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1368 (define_expand "moddf3"
1369 [(set (match_operand:DF 0 "s_register_operand" "")
1370 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1371 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1372 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1375 ;; Boolean and,ior,xor insns
1377 ;; Split up double word logical operations
1379 ;; Split up simple DImode logical operations. Simply perform the logical
1380 ;; operation on the upper and lower halves of the registers.
1382 [(set (match_operand:DI 0 "s_register_operand" "")
1383 (match_operator:DI 6 "logical_binary_operator"
1384 [(match_operand:DI 1 "s_register_operand" "")
1385 (match_operand:DI 2 "s_register_operand" "")]))]
1386 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1387 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1388 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1391 operands[3] = gen_highpart (SImode, operands[0]);
1392 operands[0] = gen_lowpart (SImode, operands[0]);
1393 operands[4] = gen_highpart (SImode, operands[1]);
1394 operands[1] = gen_lowpart (SImode, operands[1]);
1395 operands[5] = gen_highpart (SImode, operands[2]);
1396 operands[2] = gen_lowpart (SImode, operands[2]);
1401 [(set (match_operand:DI 0 "s_register_operand" "")
1402 (match_operator:DI 6 "logical_binary_operator"
1403 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1404 (match_operand:DI 1 "s_register_operand" "")]))]
1405 "TARGET_ARM && reload_completed"
1406 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1407 (set (match_dup 3) (match_op_dup:SI 6
1408 [(ashiftrt:SI (match_dup 2) (const_int 31))
1412 operands[3] = gen_highpart (SImode, operands[0]);
1413 operands[0] = gen_lowpart (SImode, operands[0]);
1414 operands[4] = gen_highpart (SImode, operands[1]);
1415 operands[1] = gen_lowpart (SImode, operands[1]);
1416 operands[5] = gen_highpart (SImode, operands[2]);
1417 operands[2] = gen_lowpart (SImode, operands[2]);
1421 ;; The zero extend of operand 2 means we can just copy the high part of
1422 ;; operand1 into operand0.
1424 [(set (match_operand:DI 0 "s_register_operand" "")
1426 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1427 (match_operand:DI 1 "s_register_operand" "")))]
1428 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1429 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1430 (set (match_dup 3) (match_dup 4))]
1433 operands[4] = gen_highpart (SImode, operands[1]);
1434 operands[3] = gen_highpart (SImode, operands[0]);
1435 operands[0] = gen_lowpart (SImode, operands[0]);
1436 operands[1] = gen_lowpart (SImode, operands[1]);
1440 ;; The zero extend of operand 2 means we can just copy the high part of
1441 ;; operand1 into operand0.
1443 [(set (match_operand:DI 0 "s_register_operand" "")
1445 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1446 (match_operand:DI 1 "s_register_operand" "")))]
1447 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1448 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1449 (set (match_dup 3) (match_dup 4))]
1452 operands[4] = gen_highpart (SImode, operands[1]);
1453 operands[3] = gen_highpart (SImode, operands[0]);
1454 operands[0] = gen_lowpart (SImode, operands[0]);
1455 operands[1] = gen_lowpart (SImode, operands[1]);
1459 (define_insn "anddi3"
1460 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1461 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1462 (match_operand:DI 2 "s_register_operand" "r,r")))]
1463 "TARGET_ARM && ! TARGET_IWMMXT"
1465 [(set_attr "length" "8")]
1468 (define_insn_and_split "*anddi_zesidi_di"
1469 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1470 (and:DI (zero_extend:DI
1471 (match_operand:SI 2 "s_register_operand" "r,r"))
1472 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1475 "TARGET_ARM && reload_completed"
1476 ; The zero extend of operand 2 clears the high word of the output
1478 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1479 (set (match_dup 3) (const_int 0))]
1482 operands[3] = gen_highpart (SImode, operands[0]);
1483 operands[0] = gen_lowpart (SImode, operands[0]);
1484 operands[1] = gen_lowpart (SImode, operands[1]);
1486 [(set_attr "length" "8")]
1489 (define_insn "*anddi_sesdi_di"
1490 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1491 (and:DI (sign_extend:DI
1492 (match_operand:SI 2 "s_register_operand" "r,r"))
1493 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1496 [(set_attr "length" "8")]
1499 (define_expand "andsi3"
1500 [(set (match_operand:SI 0 "s_register_operand" "")
1501 (and:SI (match_operand:SI 1 "s_register_operand" "")
1502 (match_operand:SI 2 "reg_or_int_operand" "")))]
1507 if (GET_CODE (operands[2]) == CONST_INT)
1509 arm_split_constant (AND, SImode, NULL_RTX,
1510 INTVAL (operands[2]), operands[0],
1511 operands[1], optimize && !no_new_pseudos);
1516 else /* TARGET_THUMB */
1518 if (GET_CODE (operands[2]) != CONST_INT)
1519 operands[2] = force_reg (SImode, operands[2]);
1524 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1526 operands[2] = force_reg (SImode,
1527 GEN_INT (~INTVAL (operands[2])));
1529 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1534 for (i = 9; i <= 31; i++)
1536 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1538 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1542 else if ((((HOST_WIDE_INT) 1) << i) - 1
1543 == ~INTVAL (operands[2]))
1545 rtx shift = GEN_INT (i);
1546 rtx reg = gen_reg_rtx (SImode);
1548 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1549 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1555 operands[2] = force_reg (SImode, operands[2]);
1561 (define_insn_and_split "*arm_andsi3_insn"
1562 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1563 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1564 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1568 bic%?\\t%0, %1, #%B2
1571 && GET_CODE (operands[2]) == CONST_INT
1572 && !(const_ok_for_arm (INTVAL (operands[2]))
1573 || const_ok_for_arm (~INTVAL (operands[2])))"
1574 [(clobber (const_int 0))]
1576 arm_split_constant (AND, SImode, curr_insn,
1577 INTVAL (operands[2]), operands[0], operands[1], 0);
1580 [(set_attr "length" "4,4,16")
1581 (set_attr "predicable" "yes")]
1584 (define_insn "*thumb_andsi3_insn"
1585 [(set (match_operand:SI 0 "register_operand" "=l")
1586 (and:SI (match_operand:SI 1 "register_operand" "%0")
1587 (match_operand:SI 2 "register_operand" "l")))]
1590 [(set_attr "length" "2")]
1593 (define_insn "*andsi3_compare0"
1594 [(set (reg:CC_NOOV CC_REGNUM)
1596 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1597 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1599 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1600 (and:SI (match_dup 1) (match_dup 2)))]
1604 bic%?s\\t%0, %1, #%B2"
1605 [(set_attr "conds" "set")]
1608 (define_insn "*andsi3_compare0_scratch"
1609 [(set (reg:CC_NOOV CC_REGNUM)
1611 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1612 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1614 (clobber (match_scratch:SI 2 "=X,r"))]
1618 bic%?s\\t%2, %0, #%B1"
1619 [(set_attr "conds" "set")]
1622 (define_insn "*zeroextractsi_compare0_scratch"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1624 (compare:CC_NOOV (zero_extract:SI
1625 (match_operand:SI 0 "s_register_operand" "r")
1626 (match_operand 1 "const_int_operand" "n")
1627 (match_operand 2 "const_int_operand" "n"))
1630 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1631 && INTVAL (operands[1]) > 0
1632 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1633 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1635 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1636 << INTVAL (operands[2]));
1637 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1640 [(set_attr "conds" "set")]
1643 (define_insn_and_split "*ne_zeroextractsi"
1644 [(set (match_operand:SI 0 "s_register_operand" "=r")
1645 (ne:SI (zero_extract:SI
1646 (match_operand:SI 1 "s_register_operand" "r")
1647 (match_operand:SI 2 "const_int_operand" "n")
1648 (match_operand:SI 3 "const_int_operand" "n"))
1650 (clobber (reg:CC CC_REGNUM))]
1652 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1653 && INTVAL (operands[2]) > 0
1654 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1655 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1658 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1659 && INTVAL (operands[2]) > 0
1660 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1661 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1662 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1663 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1665 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1667 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1668 (match_dup 0) (const_int 1)))]
1670 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1671 << INTVAL (operands[3]));
1673 [(set_attr "conds" "clob")
1674 (set_attr "length" "8")]
1677 (define_insn_and_split "*ne_zeroextractsi_shifted"
1678 [(set (match_operand:SI 0 "s_register_operand" "=r")
1679 (ne:SI (zero_extract:SI
1680 (match_operand:SI 1 "s_register_operand" "r")
1681 (match_operand:SI 2 "const_int_operand" "n")
1684 (clobber (reg:CC CC_REGNUM))]
1688 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1689 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1691 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1693 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1694 (match_dup 0) (const_int 1)))]
1696 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1698 [(set_attr "conds" "clob")
1699 (set_attr "length" "8")]
1702 (define_insn_and_split "*ite_ne_zeroextractsi"
1703 [(set (match_operand:SI 0 "s_register_operand" "=r")
1704 (if_then_else:SI (ne (zero_extract:SI
1705 (match_operand:SI 1 "s_register_operand" "r")
1706 (match_operand:SI 2 "const_int_operand" "n")
1707 (match_operand:SI 3 "const_int_operand" "n"))
1709 (match_operand:SI 4 "arm_not_operand" "rIK")
1711 (clobber (reg:CC CC_REGNUM))]
1713 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1714 && INTVAL (operands[2]) > 0
1715 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1716 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1717 && !reg_overlap_mentioned_p (operands[0], operands[4])"
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])"
1725 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1726 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1728 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1730 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1731 (match_dup 0) (match_dup 4)))]
1733 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1734 << INTVAL (operands[3]));
1736 [(set_attr "conds" "clob")
1737 (set_attr "length" "8")]
1740 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
1741 [(set (match_operand:SI 0 "s_register_operand" "=r")
1742 (if_then_else:SI (ne (zero_extract:SI
1743 (match_operand:SI 1 "s_register_operand" "r")
1744 (match_operand:SI 2 "const_int_operand" "n")
1747 (match_operand:SI 3 "arm_not_operand" "rIK")
1749 (clobber (reg:CC CC_REGNUM))]
1750 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1752 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1753 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1754 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1756 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1758 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1759 (match_dup 0) (match_dup 3)))]
1761 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1763 [(set_attr "conds" "clob")
1764 (set_attr "length" "8")]
1768 [(set (match_operand:SI 0 "s_register_operand" "")
1769 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1770 (match_operand:SI 2 "const_int_operand" "")
1771 (match_operand:SI 3 "const_int_operand" "")))
1772 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1774 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1775 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1777 HOST_WIDE_INT temp = INTVAL (operands[2]);
1779 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1780 operands[3] = GEN_INT (32 - temp);
1785 [(set (match_operand:SI 0 "s_register_operand" "")
1786 (match_operator:SI 1 "shiftable_operator"
1787 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1788 (match_operand:SI 3 "const_int_operand" "")
1789 (match_operand:SI 4 "const_int_operand" ""))
1790 (match_operand:SI 5 "s_register_operand" "")]))
1791 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1793 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1796 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1799 HOST_WIDE_INT temp = INTVAL (operands[3]);
1801 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1802 operands[4] = GEN_INT (32 - temp);
1807 [(set (match_operand:SI 0 "s_register_operand" "")
1808 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1809 (match_operand:SI 2 "const_int_operand" "")
1810 (match_operand:SI 3 "const_int_operand" "")))]
1812 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1813 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1815 HOST_WIDE_INT temp = INTVAL (operands[2]);
1817 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1818 operands[3] = GEN_INT (32 - temp);
1823 [(set (match_operand:SI 0 "s_register_operand" "")
1824 (match_operator:SI 1 "shiftable_operator"
1825 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1826 (match_operand:SI 3 "const_int_operand" "")
1827 (match_operand:SI 4 "const_int_operand" ""))
1828 (match_operand:SI 5 "s_register_operand" "")]))
1829 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1831 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1834 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1837 HOST_WIDE_INT temp = INTVAL (operands[3]);
1839 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1840 operands[4] = GEN_INT (32 - temp);
1844 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1845 ;;; represented by the bitfield, then this will produce incorrect results.
1846 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1847 ;;; which have a real bit-field insert instruction, the truncation happens
1848 ;;; in the bit-field insert instruction itself. Since arm does not have a
1849 ;;; bit-field insert instruction, we would have to emit code here to truncate
1850 ;;; the value before we insert. This loses some of the advantage of having
1851 ;;; this insv pattern, so this pattern needs to be reevalutated.
1853 (define_expand "insv"
1854 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1855 (match_operand:SI 1 "general_operand" "")
1856 (match_operand:SI 2 "general_operand" ""))
1857 (match_operand:SI 3 "reg_or_int_operand" ""))]
1861 int start_bit = INTVAL (operands[2]);
1862 int width = INTVAL (operands[1]);
1863 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1864 rtx target, subtarget;
1866 target = operands[0];
1867 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1868 subreg as the final target. */
1869 if (GET_CODE (target) == SUBREG)
1871 subtarget = gen_reg_rtx (SImode);
1872 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1873 < GET_MODE_SIZE (SImode))
1874 target = SUBREG_REG (target);
1879 if (GET_CODE (operands[3]) == CONST_INT)
1881 /* Since we are inserting a known constant, we may be able to
1882 reduce the number of bits that we have to clear so that
1883 the mask becomes simple. */
1884 /* ??? This code does not check to see if the new mask is actually
1885 simpler. It may not be. */
1886 rtx op1 = gen_reg_rtx (SImode);
1887 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1888 start of this pattern. */
1889 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1890 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1892 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1893 emit_insn (gen_iorsi3 (subtarget, op1,
1894 gen_int_mode (op3_value << start_bit, SImode)));
1896 else if (start_bit == 0
1897 && !(const_ok_for_arm (mask)
1898 || const_ok_for_arm (~mask)))
1900 /* A Trick, since we are setting the bottom bits in the word,
1901 we can shift operand[3] up, operand[0] down, OR them together
1902 and rotate the result back again. This takes 3 insns, and
1903 the third might be mergeable into another op. */
1904 /* The shift up copes with the possibility that operand[3] is
1905 wider than the bitfield. */
1906 rtx op0 = gen_reg_rtx (SImode);
1907 rtx op1 = gen_reg_rtx (SImode);
1909 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1910 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1911 emit_insn (gen_iorsi3 (op1, op1, op0));
1912 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1914 else if ((width + start_bit == 32)
1915 && !(const_ok_for_arm (mask)
1916 || const_ok_for_arm (~mask)))
1918 /* Similar trick, but slightly less efficient. */
1920 rtx op0 = gen_reg_rtx (SImode);
1921 rtx op1 = gen_reg_rtx (SImode);
1923 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1924 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1925 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1926 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1930 rtx op0 = GEN_INT (mask);
1931 rtx op1 = gen_reg_rtx (SImode);
1932 rtx op2 = gen_reg_rtx (SImode);
1934 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1936 rtx tmp = gen_reg_rtx (SImode);
1938 emit_insn (gen_movsi (tmp, op0));
1942 /* Mask out any bits in operand[3] that are not needed. */
1943 emit_insn (gen_andsi3 (op1, operands[3], op0));
1945 if (GET_CODE (op0) == CONST_INT
1946 && (const_ok_for_arm (mask << start_bit)
1947 || const_ok_for_arm (~(mask << start_bit))))
1949 op0 = GEN_INT (~(mask << start_bit));
1950 emit_insn (gen_andsi3 (op2, operands[0], op0));
1954 if (GET_CODE (op0) == CONST_INT)
1956 rtx tmp = gen_reg_rtx (SImode);
1958 emit_insn (gen_movsi (tmp, op0));
1963 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1965 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1969 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1971 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1974 if (subtarget != target)
1976 /* If TARGET is still a SUBREG, then it must be wider than a word,
1977 so we must be careful only to set the subword we were asked to. */
1978 if (GET_CODE (target) == SUBREG)
1979 emit_move_insn (target, subtarget);
1981 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1988 ; constants for op 2 will never be given to these patterns.
1989 (define_insn_and_split "*anddi_notdi_di"
1990 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1991 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1992 (match_operand:DI 2 "s_register_operand" "0,r")))]
1995 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1996 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
1997 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2000 operands[3] = gen_highpart (SImode, operands[0]);
2001 operands[0] = gen_lowpart (SImode, operands[0]);
2002 operands[4] = gen_highpart (SImode, operands[1]);
2003 operands[1] = gen_lowpart (SImode, operands[1]);
2004 operands[5] = gen_highpart (SImode, operands[2]);
2005 operands[2] = gen_lowpart (SImode, operands[2]);
2007 [(set_attr "length" "8")
2008 (set_attr "predicable" "yes")]
2011 (define_insn_and_split "*anddi_notzesidi_di"
2012 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2013 (and:DI (not:DI (zero_extend:DI
2014 (match_operand:SI 2 "s_register_operand" "r,r")))
2015 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2018 bic%?\\t%Q0, %Q1, %2
2020 ; (not (zero_extend ...)) allows us to just copy the high word from
2021 ; operand1 to operand0.
2024 && operands[0] != operands[1]"
2025 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2026 (set (match_dup 3) (match_dup 4))]
2029 operands[3] = gen_highpart (SImode, operands[0]);
2030 operands[0] = gen_lowpart (SImode, operands[0]);
2031 operands[4] = gen_highpart (SImode, operands[1]);
2032 operands[1] = gen_lowpart (SImode, operands[1]);
2034 [(set_attr "length" "4,8")
2035 (set_attr "predicable" "yes")]
2038 (define_insn_and_split "*anddi_notsesidi_di"
2039 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2040 (and:DI (not:DI (sign_extend:DI
2041 (match_operand:SI 2 "s_register_operand" "r,r")))
2042 (match_operand:DI 1 "s_register_operand" "0,r")))]
2045 "TARGET_ARM && reload_completed"
2046 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2047 (set (match_dup 3) (and:SI (not:SI
2048 (ashiftrt:SI (match_dup 2) (const_int 31)))
2052 operands[3] = gen_highpart (SImode, operands[0]);
2053 operands[0] = gen_lowpart (SImode, operands[0]);
2054 operands[4] = gen_highpart (SImode, operands[1]);
2055 operands[1] = gen_lowpart (SImode, operands[1]);
2057 [(set_attr "length" "8")
2058 (set_attr "predicable" "yes")]
2061 (define_insn "andsi_notsi_si"
2062 [(set (match_operand:SI 0 "s_register_operand" "=r")
2063 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2064 (match_operand:SI 1 "s_register_operand" "r")))]
2066 "bic%?\\t%0, %1, %2"
2067 [(set_attr "predicable" "yes")]
2070 (define_insn "bicsi3"
2071 [(set (match_operand:SI 0 "register_operand" "=l")
2072 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2073 (match_operand:SI 2 "register_operand" "0")))]
2076 [(set_attr "length" "2")]
2079 (define_insn "andsi_not_shiftsi_si"
2080 [(set (match_operand:SI 0 "s_register_operand" "=r")
2081 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2082 [(match_operand:SI 2 "s_register_operand" "r")
2083 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2084 (match_operand:SI 1 "s_register_operand" "r")))]
2086 "bic%?\\t%0, %1, %2%S4"
2087 [(set_attr "predicable" "yes")
2088 (set_attr "shift" "2")
2089 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2090 (const_string "alu_shift")
2091 (const_string "alu_shift_reg")))]
2094 (define_insn "*andsi_notsi_si_compare0"
2095 [(set (reg:CC_NOOV CC_REGNUM)
2097 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2098 (match_operand:SI 1 "s_register_operand" "r"))
2100 (set (match_operand:SI 0 "s_register_operand" "=r")
2101 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2103 "bic%?s\\t%0, %1, %2"
2104 [(set_attr "conds" "set")]
2107 (define_insn "*andsi_notsi_si_compare0_scratch"
2108 [(set (reg:CC_NOOV CC_REGNUM)
2110 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2111 (match_operand:SI 1 "s_register_operand" "r"))
2113 (clobber (match_scratch:SI 0 "=r"))]
2115 "bic%?s\\t%0, %1, %2"
2116 [(set_attr "conds" "set")]
2119 (define_insn "iordi3"
2120 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2121 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2122 (match_operand:DI 2 "s_register_operand" "r,r")))]
2123 "TARGET_ARM && ! TARGET_IWMMXT"
2125 [(set_attr "length" "8")
2126 (set_attr "predicable" "yes")]
2129 (define_insn "*iordi_zesidi_di"
2130 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2131 (ior:DI (zero_extend:DI
2132 (match_operand:SI 2 "s_register_operand" "r,r"))
2133 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2136 orr%?\\t%Q0, %Q1, %2
2138 [(set_attr "length" "4,8")
2139 (set_attr "predicable" "yes")]
2142 (define_insn "*iordi_sesidi_di"
2143 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2144 (ior:DI (sign_extend:DI
2145 (match_operand:SI 2 "s_register_operand" "r,r"))
2146 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2149 [(set_attr "length" "8")
2150 (set_attr "predicable" "yes")]
2153 (define_expand "iorsi3"
2154 [(set (match_operand:SI 0 "s_register_operand" "")
2155 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2156 (match_operand:SI 2 "reg_or_int_operand" "")))]
2159 if (GET_CODE (operands[2]) == CONST_INT)
2163 arm_split_constant (IOR, SImode, NULL_RTX,
2164 INTVAL (operands[2]), operands[0], operands[1],
2165 optimize && !no_new_pseudos);
2168 else /* TARGET_THUMB */
2169 operands [2] = force_reg (SImode, operands [2]);
2174 (define_insn_and_split "*arm_iorsi3"
2175 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2176 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2177 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2183 && GET_CODE (operands[2]) == CONST_INT
2184 && !const_ok_for_arm (INTVAL (operands[2]))"
2185 [(clobber (const_int 0))]
2187 arm_split_constant (IOR, SImode, curr_insn,
2188 INTVAL (operands[2]), operands[0], operands[1], 0);
2191 [(set_attr "length" "4,16")
2192 (set_attr "predicable" "yes")]
2195 (define_insn "*thumb_iorsi3"
2196 [(set (match_operand:SI 0 "register_operand" "=l")
2197 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2198 (match_operand:SI 2 "register_operand" "l")))]
2201 [(set_attr "length" "2")]
2205 [(match_scratch:SI 3 "r")
2206 (set (match_operand:SI 0 "arm_general_register_operand" "")
2207 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2208 (match_operand:SI 2 "const_int_operand" "")))]
2210 && !const_ok_for_arm (INTVAL (operands[2]))
2211 && const_ok_for_arm (~INTVAL (operands[2]))"
2212 [(set (match_dup 3) (match_dup 2))
2213 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2217 (define_insn "*iorsi3_compare0"
2218 [(set (reg:CC_NOOV CC_REGNUM)
2219 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2220 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2222 (set (match_operand:SI 0 "s_register_operand" "=r")
2223 (ior:SI (match_dup 1) (match_dup 2)))]
2225 "orr%?s\\t%0, %1, %2"
2226 [(set_attr "conds" "set")]
2229 (define_insn "*iorsi3_compare0_scratch"
2230 [(set (reg:CC_NOOV CC_REGNUM)
2231 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2232 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2234 (clobber (match_scratch:SI 0 "=r"))]
2236 "orr%?s\\t%0, %1, %2"
2237 [(set_attr "conds" "set")]
2240 (define_insn "xordi3"
2241 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2242 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2243 (match_operand:DI 2 "s_register_operand" "r,r")))]
2244 "TARGET_ARM && !TARGET_IWMMXT"
2246 [(set_attr "length" "8")
2247 (set_attr "predicable" "yes")]
2250 (define_insn "*xordi_zesidi_di"
2251 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2252 (xor:DI (zero_extend:DI
2253 (match_operand:SI 2 "s_register_operand" "r,r"))
2254 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2257 eor%?\\t%Q0, %Q1, %2
2259 [(set_attr "length" "4,8")
2260 (set_attr "predicable" "yes")]
2263 (define_insn "*xordi_sesidi_di"
2264 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2265 (xor:DI (sign_extend:DI
2266 (match_operand:SI 2 "s_register_operand" "r,r"))
2267 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2270 [(set_attr "length" "8")
2271 (set_attr "predicable" "yes")]
2274 (define_expand "xorsi3"
2275 [(set (match_operand:SI 0 "s_register_operand" "")
2276 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2277 (match_operand:SI 2 "arm_rhs_operand" "")))]
2280 if (GET_CODE (operands[2]) == CONST_INT)
2281 operands[2] = force_reg (SImode, operands[2]);
2285 (define_insn "*arm_xorsi3"
2286 [(set (match_operand:SI 0 "s_register_operand" "=r")
2287 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2288 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2290 "eor%?\\t%0, %1, %2"
2291 [(set_attr "predicable" "yes")]
2294 (define_insn "*thumb_xorsi3"
2295 [(set (match_operand:SI 0 "register_operand" "=l")
2296 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2297 (match_operand:SI 2 "register_operand" "l")))]
2300 [(set_attr "length" "2")]
2303 (define_insn "*xorsi3_compare0"
2304 [(set (reg:CC_NOOV CC_REGNUM)
2305 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2306 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2308 (set (match_operand:SI 0 "s_register_operand" "=r")
2309 (xor:SI (match_dup 1) (match_dup 2)))]
2311 "eor%?s\\t%0, %1, %2"
2312 [(set_attr "conds" "set")]
2315 (define_insn "*xorsi3_compare0_scratch"
2316 [(set (reg:CC_NOOV CC_REGNUM)
2317 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2318 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2322 [(set_attr "conds" "set")]
2325 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2326 ; (NOT D) we can sometimes merge the final NOT into one of the following
2330 [(set (match_operand:SI 0 "s_register_operand" "")
2331 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2332 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2333 (match_operand:SI 3 "arm_rhs_operand" "")))
2334 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2336 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2337 (not:SI (match_dup 3))))
2338 (set (match_dup 0) (not:SI (match_dup 4)))]
2342 (define_insn "*andsi_iorsi3_notsi"
2343 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2344 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2345 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2346 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2348 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2349 [(set_attr "length" "8")
2350 (set_attr "predicable" "yes")]
2354 [(set (match_operand:SI 0 "s_register_operand" "")
2355 (match_operator:SI 1 "logical_binary_operator"
2356 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2357 (match_operand:SI 3 "const_int_operand" "")
2358 (match_operand:SI 4 "const_int_operand" ""))
2359 (match_operator:SI 9 "logical_binary_operator"
2360 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2361 (match_operand:SI 6 "const_int_operand" ""))
2362 (match_operand:SI 7 "s_register_operand" "")])]))
2363 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2365 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2366 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2369 [(ashift:SI (match_dup 2) (match_dup 4))
2373 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2376 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2380 [(set (match_operand:SI 0 "s_register_operand" "")
2381 (match_operator:SI 1 "logical_binary_operator"
2382 [(match_operator:SI 9 "logical_binary_operator"
2383 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2384 (match_operand:SI 6 "const_int_operand" ""))
2385 (match_operand:SI 7 "s_register_operand" "")])
2386 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2387 (match_operand:SI 3 "const_int_operand" "")
2388 (match_operand:SI 4 "const_int_operand" ""))]))
2389 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2391 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2392 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2395 [(ashift:SI (match_dup 2) (match_dup 4))
2399 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2402 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2406 [(set (match_operand:SI 0 "s_register_operand" "")
2407 (match_operator:SI 1 "logical_binary_operator"
2408 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2409 (match_operand:SI 3 "const_int_operand" "")
2410 (match_operand:SI 4 "const_int_operand" ""))
2411 (match_operator:SI 9 "logical_binary_operator"
2412 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2413 (match_operand:SI 6 "const_int_operand" ""))
2414 (match_operand:SI 7 "s_register_operand" "")])]))
2415 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2417 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2418 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2421 [(ashift:SI (match_dup 2) (match_dup 4))
2425 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2428 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2432 [(set (match_operand:SI 0 "s_register_operand" "")
2433 (match_operator:SI 1 "logical_binary_operator"
2434 [(match_operator:SI 9 "logical_binary_operator"
2435 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2436 (match_operand:SI 6 "const_int_operand" ""))
2437 (match_operand:SI 7 "s_register_operand" "")])
2438 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2439 (match_operand:SI 3 "const_int_operand" "")
2440 (match_operand:SI 4 "const_int_operand" ""))]))
2441 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2443 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2444 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2447 [(ashift:SI (match_dup 2) (match_dup 4))
2451 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2454 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2458 ;; Minimum and maximum insns
2460 (define_insn "smaxsi3"
2461 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2462 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2463 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2464 (clobber (reg:CC CC_REGNUM))]
2467 cmp\\t%1, %2\;movlt\\t%0, %2
2468 cmp\\t%1, %2\;movge\\t%0, %1
2469 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2470 [(set_attr "conds" "clob")
2471 (set_attr "length" "8,8,12")]
2474 (define_insn "sminsi3"
2475 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2476 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2477 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2478 (clobber (reg:CC CC_REGNUM))]
2481 cmp\\t%1, %2\;movge\\t%0, %2
2482 cmp\\t%1, %2\;movlt\\t%0, %1
2483 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2484 [(set_attr "conds" "clob")
2485 (set_attr "length" "8,8,12")]
2488 (define_insn "umaxsi3"
2489 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2490 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2491 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2492 (clobber (reg:CC CC_REGNUM))]
2495 cmp\\t%1, %2\;movcc\\t%0, %2
2496 cmp\\t%1, %2\;movcs\\t%0, %1
2497 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2498 [(set_attr "conds" "clob")
2499 (set_attr "length" "8,8,12")]
2502 (define_insn "uminsi3"
2503 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2504 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2505 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2506 (clobber (reg:CC CC_REGNUM))]
2509 cmp\\t%1, %2\;movcs\\t%0, %2
2510 cmp\\t%1, %2\;movcc\\t%0, %1
2511 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2512 [(set_attr "conds" "clob")
2513 (set_attr "length" "8,8,12")]
2516 (define_insn "*store_minmaxsi"
2517 [(set (match_operand:SI 0 "memory_operand" "=m")
2518 (match_operator:SI 3 "minmax_operator"
2519 [(match_operand:SI 1 "s_register_operand" "r")
2520 (match_operand:SI 2 "s_register_operand" "r")]))
2521 (clobber (reg:CC CC_REGNUM))]
2524 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2525 operands[1], operands[2]);
2526 output_asm_insn (\"cmp\\t%1, %2\", operands);
2527 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2528 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2531 [(set_attr "conds" "clob")
2532 (set_attr "length" "12")
2533 (set_attr "type" "store1")]
2536 ; Reject the frame pointer in operand[1], since reloading this after
2537 ; it has been eliminated can cause carnage.
2538 (define_insn "*minmax_arithsi"
2539 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2540 (match_operator:SI 4 "shiftable_operator"
2541 [(match_operator:SI 5 "minmax_operator"
2542 [(match_operand:SI 2 "s_register_operand" "r,r")
2543 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2544 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2545 (clobber (reg:CC CC_REGNUM))]
2546 "TARGET_ARM && !arm_eliminable_register (operands[1])"
2549 enum rtx_code code = GET_CODE (operands[4]);
2551 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2552 operands[2], operands[3]);
2553 output_asm_insn (\"cmp\\t%2, %3\", operands);
2554 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2555 if (which_alternative != 0 || operands[3] != const0_rtx
2556 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2557 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2560 [(set_attr "conds" "clob")
2561 (set_attr "length" "12")]
2565 ;; Shift and rotation insns
2567 (define_expand "ashldi3"
2568 [(set (match_operand:DI 0 "s_register_operand" "")
2569 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2570 (match_operand:SI 2 "reg_or_int_operand" "")))]
2573 if (GET_CODE (operands[2]) == CONST_INT)
2575 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2577 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2580 /* Ideally we shouldn't fail here if we could know that operands[1]
2581 ends up already living in an iwmmxt register. Otherwise it's
2582 cheaper to have the alternate code being generated than moving
2583 values to iwmmxt regs and back. */
2586 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2591 (define_insn "arm_ashldi3_1bit"
2592 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2593 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2595 (clobber (reg:CC CC_REGNUM))]
2597 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2598 [(set_attr "conds" "clob")
2599 (set_attr "length" "8")]
2602 (define_expand "ashlsi3"
2603 [(set (match_operand:SI 0 "s_register_operand" "")
2604 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2605 (match_operand:SI 2 "arm_rhs_operand" "")))]
2608 if (GET_CODE (operands[2]) == CONST_INT
2609 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2611 emit_insn (gen_movsi (operands[0], const0_rtx));
2617 (define_insn "*thumb_ashlsi3"
2618 [(set (match_operand:SI 0 "register_operand" "=l,l")
2619 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2620 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2623 [(set_attr "length" "2")]
2626 (define_expand "ashrdi3"
2627 [(set (match_operand:DI 0 "s_register_operand" "")
2628 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2629 (match_operand:SI 2 "reg_or_int_operand" "")))]
2632 if (GET_CODE (operands[2]) == CONST_INT)
2634 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2636 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2639 /* Ideally we shouldn't fail here if we could know that operands[1]
2640 ends up already living in an iwmmxt register. Otherwise it's
2641 cheaper to have the alternate code being generated than moving
2642 values to iwmmxt regs and back. */
2645 else if (!TARGET_REALLY_IWMMXT)
2650 (define_insn "arm_ashrdi3_1bit"
2651 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2652 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2654 (clobber (reg:CC CC_REGNUM))]
2656 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2657 [(set_attr "conds" "clob")
2658 (set_attr "length" "8")]
2661 (define_expand "ashrsi3"
2662 [(set (match_operand:SI 0 "s_register_operand" "")
2663 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2664 (match_operand:SI 2 "arm_rhs_operand" "")))]
2667 if (GET_CODE (operands[2]) == CONST_INT
2668 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2669 operands[2] = GEN_INT (31);
2673 (define_insn "*thumb_ashrsi3"
2674 [(set (match_operand:SI 0 "register_operand" "=l,l")
2675 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2676 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2679 [(set_attr "length" "2")]
2682 (define_expand "lshrdi3"
2683 [(set (match_operand:DI 0 "s_register_operand" "")
2684 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2685 (match_operand:SI 2 "reg_or_int_operand" "")))]
2688 if (GET_CODE (operands[2]) == CONST_INT)
2690 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2692 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2695 /* Ideally we shouldn't fail here if we could know that operands[1]
2696 ends up already living in an iwmmxt register. Otherwise it's
2697 cheaper to have the alternate code being generated than moving
2698 values to iwmmxt regs and back. */
2701 else if (!TARGET_REALLY_IWMMXT)
2706 (define_insn "arm_lshrdi3_1bit"
2707 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2708 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2710 (clobber (reg:CC CC_REGNUM))]
2712 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2713 [(set_attr "conds" "clob")
2714 (set_attr "length" "8")]
2717 (define_expand "lshrsi3"
2718 [(set (match_operand:SI 0 "s_register_operand" "")
2719 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2720 (match_operand:SI 2 "arm_rhs_operand" "")))]
2723 if (GET_CODE (operands[2]) == CONST_INT
2724 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2726 emit_insn (gen_movsi (operands[0], const0_rtx));
2732 (define_insn "*thumb_lshrsi3"
2733 [(set (match_operand:SI 0 "register_operand" "=l,l")
2734 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2735 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2738 [(set_attr "length" "2")]
2741 (define_expand "rotlsi3"
2742 [(set (match_operand:SI 0 "s_register_operand" "")
2743 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2744 (match_operand:SI 2 "reg_or_int_operand" "")))]
2747 if (GET_CODE (operands[2]) == CONST_INT)
2748 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2751 rtx reg = gen_reg_rtx (SImode);
2752 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2758 (define_expand "rotrsi3"
2759 [(set (match_operand:SI 0 "s_register_operand" "")
2760 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2761 (match_operand:SI 2 "arm_rhs_operand" "")))]
2766 if (GET_CODE (operands[2]) == CONST_INT
2767 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2768 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2770 else /* TARGET_THUMB */
2772 if (GET_CODE (operands [2]) == CONST_INT)
2773 operands [2] = force_reg (SImode, operands[2]);
2778 (define_insn "*thumb_rotrsi3"
2779 [(set (match_operand:SI 0 "register_operand" "=l")
2780 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2781 (match_operand:SI 2 "register_operand" "l")))]
2784 [(set_attr "length" "2")]
2787 (define_insn "*arm_shiftsi3"
2788 [(set (match_operand:SI 0 "s_register_operand" "=r")
2789 (match_operator:SI 3 "shift_operator"
2790 [(match_operand:SI 1 "s_register_operand" "r")
2791 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2794 [(set_attr "predicable" "yes")
2795 (set_attr "shift" "1")
2796 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2797 (const_string "alu_shift")
2798 (const_string "alu_shift_reg")))]
2801 (define_insn "*shiftsi3_compare0"
2802 [(set (reg:CC_NOOV CC_REGNUM)
2803 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2804 [(match_operand:SI 1 "s_register_operand" "r")
2805 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2807 (set (match_operand:SI 0 "s_register_operand" "=r")
2808 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2810 "mov%?s\\t%0, %1%S3"
2811 [(set_attr "conds" "set")
2812 (set_attr "shift" "1")
2813 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2814 (const_string "alu_shift")
2815 (const_string "alu_shift_reg")))]
2818 (define_insn "*shiftsi3_compare0_scratch"
2819 [(set (reg:CC_NOOV CC_REGNUM)
2820 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2821 [(match_operand:SI 1 "s_register_operand" "r")
2822 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2824 (clobber (match_scratch:SI 0 "=r"))]
2826 "mov%?s\\t%0, %1%S3"
2827 [(set_attr "conds" "set")
2828 (set_attr "shift" "1")]
2831 (define_insn "*notsi_shiftsi"
2832 [(set (match_operand:SI 0 "s_register_operand" "=r")
2833 (not:SI (match_operator:SI 3 "shift_operator"
2834 [(match_operand:SI 1 "s_register_operand" "r")
2835 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2838 [(set_attr "predicable" "yes")
2839 (set_attr "shift" "1")
2840 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2841 (const_string "alu_shift")
2842 (const_string "alu_shift_reg")))]
2845 (define_insn "*notsi_shiftsi_compare0"
2846 [(set (reg:CC_NOOV CC_REGNUM)
2847 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2848 [(match_operand:SI 1 "s_register_operand" "r")
2849 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2851 (set (match_operand:SI 0 "s_register_operand" "=r")
2852 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2854 "mvn%?s\\t%0, %1%S3"
2855 [(set_attr "conds" "set")
2856 (set_attr "shift" "1")
2857 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2858 (const_string "alu_shift")
2859 (const_string "alu_shift_reg")))]
2862 (define_insn "*not_shiftsi_compare0_scratch"
2863 [(set (reg:CC_NOOV CC_REGNUM)
2864 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2865 [(match_operand:SI 1 "s_register_operand" "r")
2866 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2868 (clobber (match_scratch:SI 0 "=r"))]
2870 "mvn%?s\\t%0, %1%S3"
2871 [(set_attr "conds" "set")
2872 (set_attr "shift" "1")
2873 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2874 (const_string "alu_shift")
2875 (const_string "alu_shift_reg")))]
2878 ;; We don't really have extzv, but defining this using shifts helps
2879 ;; to reduce register pressure later on.
2881 (define_expand "extzv"
2883 (ashift:SI (match_operand:SI 1 "register_operand" "")
2884 (match_operand:SI 2 "const_int_operand" "")))
2885 (set (match_operand:SI 0 "register_operand" "")
2886 (lshiftrt:SI (match_dup 4)
2887 (match_operand:SI 3 "const_int_operand" "")))]
2891 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2892 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2894 operands[3] = GEN_INT (rshift);
2898 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2902 operands[2] = GEN_INT (lshift);
2903 operands[4] = gen_reg_rtx (SImode);
2908 ;; Unary arithmetic insns
2910 (define_expand "negdi2"
2912 [(set (match_operand:DI 0 "s_register_operand" "")
2913 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2914 (clobber (reg:CC CC_REGNUM))])]
2919 if (GET_CODE (operands[1]) != REG)
2920 operands[1] = force_reg (SImode, operands[1]);
2925 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
2926 ;; The second alternative is to allow the common case of a *full* overlap.
2927 (define_insn "*arm_negdi2"
2928 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2929 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
2930 (clobber (reg:CC CC_REGNUM))]
2932 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
2933 [(set_attr "conds" "clob")
2934 (set_attr "length" "8")]
2937 (define_insn "*thumb_negdi2"
2938 [(set (match_operand:DI 0 "register_operand" "=&l")
2939 (neg:DI (match_operand:DI 1 "register_operand" "l")))
2940 (clobber (reg:CC CC_REGNUM))]
2942 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
2943 [(set_attr "length" "6")]
2946 (define_expand "negsi2"
2947 [(set (match_operand:SI 0 "s_register_operand" "")
2948 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
2953 (define_insn "*arm_negsi2"
2954 [(set (match_operand:SI 0 "s_register_operand" "=r")
2955 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
2957 "rsb%?\\t%0, %1, #0"
2958 [(set_attr "predicable" "yes")]
2961 (define_insn "*thumb_negsi2"
2962 [(set (match_operand:SI 0 "register_operand" "=l")
2963 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
2966 [(set_attr "length" "2")]
2969 (define_expand "negsf2"
2970 [(set (match_operand:SF 0 "s_register_operand" "")
2971 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
2972 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2976 (define_expand "negdf2"
2977 [(set (match_operand:DF 0 "s_register_operand" "")
2978 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
2979 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2982 ;; abssi2 doesn't really clobber the condition codes if a different register
2983 ;; is being set. To keep things simple, assume during rtl manipulations that
2984 ;; it does, but tell the final scan operator the truth. Similarly for
2987 (define_expand "abssi2"
2989 [(set (match_operand:SI 0 "s_register_operand" "")
2990 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
2991 (clobber (reg:CC CC_REGNUM))])]
2995 (define_insn "*arm_abssi2"
2996 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
2997 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
2998 (clobber (reg:CC CC_REGNUM))]
3001 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
3002 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
3003 [(set_attr "conds" "clob,*")
3004 (set_attr "shift" "1")
3005 ;; predicable can't be set based on the variant, so left as no
3006 (set_attr "length" "8")]
3009 (define_insn "*neg_abssi2"
3010 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3011 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
3012 (clobber (reg:CC CC_REGNUM))]
3015 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
3016 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
3017 [(set_attr "conds" "clob,*")
3018 (set_attr "shift" "1")
3019 ;; predicable can't be set based on the variant, so left as no
3020 (set_attr "length" "8")]
3023 (define_expand "abssf2"
3024 [(set (match_operand:SF 0 "s_register_operand" "")
3025 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
3026 "TARGET_ARM && TARGET_HARD_FLOAT"
3029 (define_expand "absdf2"
3030 [(set (match_operand:DF 0 "s_register_operand" "")
3031 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
3032 "TARGET_ARM && TARGET_HARD_FLOAT"
3035 (define_expand "sqrtsf2"
3036 [(set (match_operand:SF 0 "s_register_operand" "")
3037 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
3038 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3041 (define_expand "sqrtdf2"
3042 [(set (match_operand:DF 0 "s_register_operand" "")
3043 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
3044 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3047 (define_insn_and_split "one_cmpldi2"
3048 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3049 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
3052 "TARGET_ARM && reload_completed"
3053 [(set (match_dup 0) (not:SI (match_dup 1)))
3054 (set (match_dup 2) (not:SI (match_dup 3)))]
3057 operands[2] = gen_highpart (SImode, operands[0]);
3058 operands[0] = gen_lowpart (SImode, operands[0]);
3059 operands[3] = gen_highpart (SImode, operands[1]);
3060 operands[1] = gen_lowpart (SImode, operands[1]);
3062 [(set_attr "length" "8")
3063 (set_attr "predicable" "yes")]
3066 (define_expand "one_cmplsi2"
3067 [(set (match_operand:SI 0 "s_register_operand" "")
3068 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
3073 (define_insn "*arm_one_cmplsi2"
3074 [(set (match_operand:SI 0 "s_register_operand" "=r")
3075 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
3078 [(set_attr "predicable" "yes")]
3081 (define_insn "*thumb_one_cmplsi2"
3082 [(set (match_operand:SI 0 "register_operand" "=l")
3083 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3086 [(set_attr "length" "2")]
3089 (define_insn "*notsi_compare0"
3090 [(set (reg:CC_NOOV CC_REGNUM)
3091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3093 (set (match_operand:SI 0 "s_register_operand" "=r")
3094 (not:SI (match_dup 1)))]
3097 [(set_attr "conds" "set")]
3100 (define_insn "*notsi_compare0_scratch"
3101 [(set (reg:CC_NOOV CC_REGNUM)
3102 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3104 (clobber (match_scratch:SI 0 "=r"))]
3107 [(set_attr "conds" "set")]
3110 ;; Fixed <--> Floating conversion insns
3112 (define_expand "floatsisf2"
3113 [(set (match_operand:SF 0 "s_register_operand" "")
3114 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3115 "TARGET_ARM && TARGET_HARD_FLOAT"
3117 if (TARGET_MAVERICK)
3119 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3124 (define_expand "floatsidf2"
3125 [(set (match_operand:DF 0 "s_register_operand" "")
3126 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3127 "TARGET_ARM && TARGET_HARD_FLOAT"
3129 if (TARGET_MAVERICK)
3131 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3136 (define_expand "fix_truncsfsi2"
3137 [(set (match_operand:SI 0 "s_register_operand" "")
3138 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3139 "TARGET_ARM && TARGET_HARD_FLOAT"
3141 if (TARGET_MAVERICK)
3143 if (!cirrus_fp_register (operands[0], SImode))
3144 operands[0] = force_reg (SImode, operands[0]);
3145 if (!cirrus_fp_register (operands[1], SFmode))
3146 operands[1] = force_reg (SFmode, operands[0]);
3147 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3152 (define_expand "fix_truncdfsi2"
3153 [(set (match_operand:SI 0 "s_register_operand" "")
3154 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3155 "TARGET_ARM && TARGET_HARD_FLOAT"
3157 if (TARGET_MAVERICK)
3159 if (!cirrus_fp_register (operands[1], DFmode))
3160 operands[1] = force_reg (DFmode, operands[0]);
3161 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3168 (define_expand "truncdfsf2"
3169 [(set (match_operand:SF 0 "s_register_operand" "")
3171 (match_operand:DF 1 "s_register_operand" "")))]
3172 "TARGET_ARM && TARGET_HARD_FLOAT"
3176 ;; Zero and sign extension instructions.
3178 (define_insn "zero_extendsidi2"
3179 [(set (match_operand:DI 0 "s_register_operand" "=r")
3180 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3183 if (REGNO (operands[1])
3184 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3185 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3186 return \"mov%?\\t%R0, #0\";
3188 [(set_attr "length" "8")
3189 (set_attr "predicable" "yes")]
3192 (define_insn "zero_extendqidi2"
3193 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3194 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3197 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3198 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3199 [(set_attr "length" "8")
3200 (set_attr "predicable" "yes")
3201 (set_attr "type" "*,load_byte")
3202 (set_attr "pool_range" "*,4092")
3203 (set_attr "neg_pool_range" "*,4084")]
3206 (define_insn "extendsidi2"
3207 [(set (match_operand:DI 0 "s_register_operand" "=r")
3208 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3211 if (REGNO (operands[1])
3212 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3213 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3214 return \"mov%?\\t%R0, %Q0, asr #31\";
3216 [(set_attr "length" "8")
3217 (set_attr "shift" "1")
3218 (set_attr "predicable" "yes")]
3221 (define_expand "zero_extendhisi2"
3223 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3225 (set (match_operand:SI 0 "s_register_operand" "")
3226 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3230 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3232 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3233 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3237 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3239 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3243 if (!s_register_operand (operands[1], HImode))
3244 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3248 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3249 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3253 operands[1] = gen_lowpart (SImode, operands[1]);
3254 operands[2] = gen_reg_rtx (SImode);
3258 (define_insn "*thumb_zero_extendhisi2"
3259 [(set (match_operand:SI 0 "register_operand" "=l")
3260 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3261 "TARGET_THUMB && !arm_arch6"
3263 rtx mem = XEXP (operands[1], 0);
3265 if (GET_CODE (mem) == CONST)
3266 mem = XEXP (mem, 0);
3268 if (GET_CODE (mem) == LABEL_REF)
3269 return \"ldr\\t%0, %1\";
3271 if (GET_CODE (mem) == PLUS)
3273 rtx a = XEXP (mem, 0);
3274 rtx b = XEXP (mem, 1);
3276 /* This can happen due to bugs in reload. */
3277 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3280 ops[0] = operands[0];
3283 output_asm_insn (\"mov %0, %1\", ops);
3285 XEXP (mem, 0) = operands[0];
3288 else if ( GET_CODE (a) == LABEL_REF
3289 && GET_CODE (b) == CONST_INT)
3290 return \"ldr\\t%0, %1\";
3293 return \"ldrh\\t%0, %1\";
3295 [(set_attr "length" "4")
3296 (set_attr "type" "load_byte")
3297 (set_attr "pool_range" "60")]
3300 (define_insn "*thumb_zero_extendhisi2_v6"
3301 [(set (match_operand:SI 0 "register_operand" "=l,l")
3302 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3303 "TARGET_THUMB && arm_arch6"
3307 if (which_alternative == 0)
3308 return \"uxth\\t%0, %1\";
3310 mem = XEXP (operands[1], 0);
3312 if (GET_CODE (mem) == CONST)
3313 mem = XEXP (mem, 0);
3315 if (GET_CODE (mem) == LABEL_REF)
3316 return \"ldr\\t%0, %1\";
3318 if (GET_CODE (mem) == PLUS)
3320 rtx a = XEXP (mem, 0);
3321 rtx b = XEXP (mem, 1);
3323 /* This can happen due to bugs in reload. */
3324 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3327 ops[0] = operands[0];
3330 output_asm_insn (\"mov %0, %1\", ops);
3332 XEXP (mem, 0) = operands[0];
3335 else if ( GET_CODE (a) == LABEL_REF
3336 && GET_CODE (b) == CONST_INT)
3337 return \"ldr\\t%0, %1\";
3340 return \"ldrh\\t%0, %1\";
3342 [(set_attr "length" "2,4")
3343 (set_attr "type" "alu_shift,load_byte")
3344 (set_attr "pool_range" "*,60")]
3347 (define_insn "*arm_zero_extendhisi2"
3348 [(set (match_operand:SI 0 "s_register_operand" "=r")
3349 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3350 "TARGET_ARM && arm_arch4 && !arm_arch6"
3352 [(set_attr "type" "load_byte")
3353 (set_attr "predicable" "yes")
3354 (set_attr "pool_range" "256")
3355 (set_attr "neg_pool_range" "244")]
3358 (define_insn "*arm_zero_extendhisi2_v6"
3359 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3360 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3361 "TARGET_ARM && arm_arch6"
3365 [(set_attr "type" "alu_shift,load_byte")
3366 (set_attr "predicable" "yes")
3367 (set_attr "pool_range" "*,256")
3368 (set_attr "neg_pool_range" "*,244")]
3371 (define_insn "*arm_zero_extendhisi2addsi"
3372 [(set (match_operand:SI 0 "s_register_operand" "=r")
3373 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3374 (match_operand:SI 2 "s_register_operand" "r")))]
3375 "TARGET_ARM && arm_arch6"
3376 "uxtah%?\\t%0, %2, %1"
3377 [(set_attr "type" "alu_shift")
3378 (set_attr "predicable" "yes")]
3382 [(set (match_operand:SI 0 "s_register_operand" "")
3383 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3384 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3385 "TARGET_ARM && (!arm_arch4)"
3386 [(set (match_dup 2) (match_dup 1))
3387 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
3389 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3395 [(set (match_operand:SI 0 "s_register_operand" "")
3396 (match_operator:SI 3 "shiftable_operator"
3397 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3398 (match_operand:SI 4 "s_register_operand" "")]))
3399 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3400 "TARGET_ARM && (!arm_arch4)"
3401 [(set (match_dup 2) (match_dup 1))
3404 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3406 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3411 (define_expand "zero_extendqisi2"
3412 [(set (match_operand:SI 0 "s_register_operand" "")
3413 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3416 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3420 emit_insn (gen_andsi3 (operands[0],
3421 gen_lowpart (SImode, operands[1]),
3424 else /* TARGET_THUMB */
3426 rtx temp = gen_reg_rtx (SImode);
3429 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3430 operands[1] = gen_lowpart (SImode, operands[1]);
3433 ops[1] = operands[1];
3434 ops[2] = GEN_INT (24);
3436 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3437 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3439 ops[0] = operands[0];
3441 ops[2] = GEN_INT (24);
3443 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3444 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3451 (define_insn "*thumb_zero_extendqisi2"
3452 [(set (match_operand:SI 0 "register_operand" "=l")
3453 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3454 "TARGET_THUMB && !arm_arch6"
3456 [(set_attr "length" "2")
3457 (set_attr "type" "load_byte")
3458 (set_attr "pool_range" "32")]
3461 (define_insn "*thumb_zero_extendqisi2_v6"
3462 [(set (match_operand:SI 0 "register_operand" "=l,l")
3463 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3464 "TARGET_THUMB && arm_arch6"
3468 [(set_attr "length" "2,2")
3469 (set_attr "type" "alu_shift,load_byte")
3470 (set_attr "pool_range" "*,32")]
3473 (define_insn "*arm_zero_extendqisi2"
3474 [(set (match_operand:SI 0 "s_register_operand" "=r")
3475 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3476 "TARGET_ARM && !arm_arch6"
3477 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3478 [(set_attr "type" "load_byte")
3479 (set_attr "predicable" "yes")
3480 (set_attr "pool_range" "4096")
3481 (set_attr "neg_pool_range" "4084")]
3484 (define_insn "*arm_zero_extendqisi2_v6"
3485 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3486 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3487 "TARGET_ARM && arm_arch6"
3490 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3491 [(set_attr "type" "alu_shift,load_byte")
3492 (set_attr "predicable" "yes")
3493 (set_attr "pool_range" "*,4096")
3494 (set_attr "neg_pool_range" "*,4084")]
3497 (define_insn "*arm_zero_extendqisi2addsi"
3498 [(set (match_operand:SI 0 "s_register_operand" "=r")
3499 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3500 (match_operand:SI 2 "s_register_operand" "r")))]
3501 "TARGET_ARM && arm_arch6"
3502 "uxtab%?\\t%0, %2, %1"
3503 [(set_attr "predicable" "yes")
3504 (set_attr "type" "alu_shift")]
3508 [(set (match_operand:SI 0 "s_register_operand" "")
3509 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3510 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3511 "TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3512 [(set (match_dup 2) (match_dup 1))
3513 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3517 (define_insn "*compareqi_eq0"
3518 [(set (reg:CC_Z CC_REGNUM)
3519 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3523 [(set_attr "conds" "set")]
3526 (define_expand "extendhisi2"
3528 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3530 (set (match_operand:SI 0 "s_register_operand" "")
3531 (ashiftrt:SI (match_dup 2)
3536 if (GET_CODE (operands[1]) == MEM)
3540 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3545 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3546 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3551 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3553 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3557 if (!s_register_operand (operands[1], HImode))
3558 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3563 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3565 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3566 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3571 operands[1] = gen_lowpart (SImode, operands[1]);
3572 operands[2] = gen_reg_rtx (SImode);
3576 (define_insn "thumb_extendhisi2"
3577 [(set (match_operand:SI 0 "register_operand" "=l")
3578 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
3579 (clobber (match_scratch:SI 2 "=&l"))]
3580 "TARGET_THUMB && !arm_arch6"
3584 rtx mem = XEXP (operands[1], 0);
3586 /* This code used to try to use 'V', and fix the address only if it was
3587 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3588 range of QImode offsets, and offsettable_address_p does a QImode
3591 if (GET_CODE (mem) == CONST)
3592 mem = XEXP (mem, 0);
3594 if (GET_CODE (mem) == LABEL_REF)
3595 return \"ldr\\t%0, %1\";
3597 if (GET_CODE (mem) == PLUS)
3599 rtx a = XEXP (mem, 0);
3600 rtx b = XEXP (mem, 1);
3602 if (GET_CODE (a) == LABEL_REF
3603 && GET_CODE (b) == CONST_INT)
3604 return \"ldr\\t%0, %1\";
3606 if (GET_CODE (b) == REG)
3607 return \"ldrsh\\t%0, %1\";
3615 ops[2] = const0_rtx;
3618 if (GET_CODE (ops[1]) != REG)
3624 ops[0] = operands[0];
3625 ops[3] = operands[2];
3626 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3629 [(set_attr "length" "4")
3630 (set_attr "type" "load_byte")
3631 (set_attr "pool_range" "1020")]
3634 ;; We used to have an early-clobber on the scratch register here.
3635 ;; However, there's a bug somewhere in reload which means that this
3636 ;; can be partially ignored during spill allocation if the memory
3637 ;; address also needs reloading; this causes an abort later on when
3638 ;; we try to verify the operands. Fortunately, we don't really need
3639 ;; the early-clobber: we can always use operand 0 if operand 2
3640 ;; overlaps the address.
3641 (define_insn "*thumb_extendhisi2_insn_v6"
3642 [(set (match_operand:SI 0 "register_operand" "=l,l")
3643 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
3644 (clobber (match_scratch:SI 2 "=X,l"))]
3645 "TARGET_THUMB && arm_arch6"
3651 if (which_alternative == 0)
3652 return \"sxth\\t%0, %1\";
3654 mem = XEXP (operands[1], 0);
3656 /* This code used to try to use 'V', and fix the address only if it was
3657 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3658 range of QImode offsets, and offsettable_address_p does a QImode
3661 if (GET_CODE (mem) == CONST)
3662 mem = XEXP (mem, 0);
3664 if (GET_CODE (mem) == LABEL_REF)
3665 return \"ldr\\t%0, %1\";
3667 if (GET_CODE (mem) == PLUS)
3669 rtx a = XEXP (mem, 0);
3670 rtx b = XEXP (mem, 1);
3672 if (GET_CODE (a) == LABEL_REF
3673 && GET_CODE (b) == CONST_INT)
3674 return \"ldr\\t%0, %1\";
3676 if (GET_CODE (b) == REG)
3677 return \"ldrsh\\t%0, %1\";
3685 ops[2] = const0_rtx;
3688 if (GET_CODE (ops[1]) != REG)
3694 ops[0] = operands[0];
3695 if (reg_mentioned_p (operands[2], ops[1]))
3698 ops[3] = operands[2];
3699 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3702 [(set_attr "length" "2,4")
3703 (set_attr "type" "alu_shift,load_byte")
3704 (set_attr "pool_range" "*,1020")]
3707 (define_expand "extendhisi2_mem"
3708 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3710 (zero_extend:SI (match_dup 7)))
3711 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
3712 (set (match_operand:SI 0 "" "")
3713 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
3718 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3720 mem1 = gen_rtx_MEM (QImode, addr);
3721 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3722 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3723 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3724 operands[0] = gen_lowpart (SImode, operands[0]);
3726 operands[2] = gen_reg_rtx (SImode);
3727 operands[3] = gen_reg_rtx (SImode);
3728 operands[6] = gen_reg_rtx (SImode);
3731 if (BYTES_BIG_ENDIAN)
3733 operands[4] = operands[2];
3734 operands[5] = operands[3];
3738 operands[4] = operands[3];
3739 operands[5] = operands[2];
3744 (define_insn "*arm_extendhisi2"
3745 [(set (match_operand:SI 0 "s_register_operand" "=r")
3746 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3747 "TARGET_ARM && arm_arch4 && !arm_arch6"
3749 [(set_attr "type" "load_byte")
3750 (set_attr "predicable" "yes")
3751 (set_attr "pool_range" "256")
3752 (set_attr "neg_pool_range" "244")]
3755 (define_insn "*arm_extendhisi2_v6"
3756 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3757 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3758 "TARGET_ARM && arm_arch6"
3762 [(set_attr "type" "alu_shift,load_byte")
3763 (set_attr "predicable" "yes")
3764 (set_attr "pool_range" "*,256")
3765 (set_attr "neg_pool_range" "*,244")]
3768 (define_insn "*arm_extendhisi2addsi"
3769 [(set (match_operand:SI 0 "s_register_operand" "=r")
3770 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3771 (match_operand:SI 2 "s_register_operand" "r")))]
3772 "TARGET_ARM && arm_arch6"
3773 "sxtah%?\\t%0, %2, %1"
3777 [(set (match_operand:SI 0 "s_register_operand" "")
3778 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3779 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3780 "TARGET_ARM && (!arm_arch4)"
3781 [(set (match_dup 2) (match_dup 1))
3782 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
3784 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3790 [(set (match_operand:SI 0 "s_register_operand" "")
3791 (match_operator:SI 3 "shiftable_operator"
3792 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3793 (match_operand:SI 4 "s_register_operand" "")]))
3794 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3795 "TARGET_ARM && (!arm_arch4)"
3796 [(set (match_dup 2) (match_dup 1))
3799 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3800 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3805 (define_expand "extendqihi2"
3807 (ashift:SI (match_operand:QI 1 "general_operand" "")
3809 (set (match_operand:HI 0 "s_register_operand" "")
3810 (ashiftrt:SI (match_dup 2)
3815 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
3817 emit_insn (gen_rtx_SET (VOIDmode,
3819 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
3822 if (!s_register_operand (operands[1], QImode))
3823 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3824 operands[0] = gen_lowpart (SImode, operands[0]);
3825 operands[1] = gen_lowpart (SImode, operands[1]);
3826 operands[2] = gen_reg_rtx (SImode);
3830 (define_insn "*extendqihi_insn"
3831 [(set (match_operand:HI 0 "s_register_operand" "=r")
3832 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
3833 "TARGET_ARM && arm_arch4"
3835 [(set_attr "type" "load_byte")
3836 (set_attr "predicable" "yes")
3837 (set_attr "pool_range" "256")
3838 (set_attr "neg_pool_range" "244")]
3841 (define_expand "extendqisi2"
3843 (ashift:SI (match_operand:QI 1 "general_operand" "")
3845 (set (match_operand:SI 0 "s_register_operand" "")
3846 (ashiftrt:SI (match_dup 2)
3851 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3853 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3854 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3858 if (!s_register_operand (operands[1], QImode))
3859 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3863 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3864 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3868 operands[1] = gen_lowpart (SImode, operands[1]);
3869 operands[2] = gen_reg_rtx (SImode);
3873 (define_insn "*arm_extendqisi"
3874 [(set (match_operand:SI 0 "s_register_operand" "=r")
3875 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
3876 "TARGET_ARM && arm_arch4 && !arm_arch6"
3878 [(set_attr "type" "load_byte")
3879 (set_attr "predicable" "yes")
3880 (set_attr "pool_range" "256")
3881 (set_attr "neg_pool_range" "244")]
3884 (define_insn "*arm_extendqisi_v6"
3885 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3886 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
3887 "TARGET_ARM && arm_arch6"
3891 [(set_attr "type" "alu_shift,load_byte")
3892 (set_attr "predicable" "yes")
3893 (set_attr "pool_range" "*,256")
3894 (set_attr "neg_pool_range" "*,244")]
3897 (define_insn "*arm_extendqisi2addsi"
3898 [(set (match_operand:SI 0 "s_register_operand" "=r")
3899 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3900 (match_operand:SI 2 "s_register_operand" "r")))]
3901 "TARGET_ARM && arm_arch6"
3902 "sxtab%?\\t%0, %2, %1"
3903 [(set_attr "type" "alu_shift")
3904 (set_attr "predicable" "yes")]
3907 (define_insn "*thumb_extendqisi2"
3908 [(set (match_operand:SI 0 "register_operand" "=l,l")
3909 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
3910 "TARGET_THUMB && !arm_arch6"
3914 rtx mem = XEXP (operands[1], 0);
3916 if (GET_CODE (mem) == CONST)
3917 mem = XEXP (mem, 0);
3919 if (GET_CODE (mem) == LABEL_REF)
3920 return \"ldr\\t%0, %1\";
3922 if (GET_CODE (mem) == PLUS
3923 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3924 return \"ldr\\t%0, %1\";
3926 if (which_alternative == 0)
3927 return \"ldrsb\\t%0, %1\";
3929 ops[0] = operands[0];
3931 if (GET_CODE (mem) == PLUS)
3933 rtx a = XEXP (mem, 0);
3934 rtx b = XEXP (mem, 1);
3939 if (GET_CODE (a) == REG)
3941 if (GET_CODE (b) == REG)
3942 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3943 else if (REGNO (a) == REGNO (ops[0]))
3945 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3946 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3947 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3950 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3952 else if (GET_CODE (b) != REG)
3956 if (REGNO (b) == REGNO (ops[0]))
3958 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3959 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3960 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3963 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3966 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3968 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3969 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3970 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3975 ops[2] = const0_rtx;
3977 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3981 [(set_attr "length" "2,6")
3982 (set_attr "type" "load_byte,load_byte")
3983 (set_attr "pool_range" "32,32")]
3986 (define_insn "*thumb_extendqisi2_v6"
3987 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
3988 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
3989 "TARGET_THUMB && arm_arch6"
3995 if (which_alternative == 0)
3996 return \"sxtb\\t%0, %1\";
3998 mem = XEXP (operands[1], 0);
4000 if (GET_CODE (mem) == CONST)
4001 mem = XEXP (mem, 0);
4003 if (GET_CODE (mem) == LABEL_REF)
4004 return \"ldr\\t%0, %1\";
4006 if (GET_CODE (mem) == PLUS
4007 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
4008 return \"ldr\\t%0, %1\";
4010 if (which_alternative == 0)
4011 return \"ldrsb\\t%0, %1\";
4013 ops[0] = operands[0];
4015 if (GET_CODE (mem) == PLUS)
4017 rtx a = XEXP (mem, 0);
4018 rtx b = XEXP (mem, 1);
4023 if (GET_CODE (a) == REG)
4025 if (GET_CODE (b) == REG)
4026 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
4027 else if (REGNO (a) == REGNO (ops[0]))
4029 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
4030 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4033 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4035 else if (GET_CODE (b) != REG)
4039 if (REGNO (b) == REGNO (ops[0]))
4041 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
4042 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4045 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4048 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
4050 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
4051 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4056 ops[2] = const0_rtx;
4058 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4062 [(set_attr "length" "2,2,4")
4063 (set_attr "type" "alu_shift,load_byte,load_byte")
4064 (set_attr "pool_range" "*,32,32")]
4067 (define_expand "extendsfdf2"
4068 [(set (match_operand:DF 0 "s_register_operand" "")
4069 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
4070 "TARGET_ARM && TARGET_HARD_FLOAT"
4074 ;; Move insns (including loads and stores)
4076 ;; XXX Just some ideas about movti.
4077 ;; I don't think these are a good idea on the arm, there just aren't enough
4079 ;;(define_expand "loadti"
4080 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4081 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4084 ;;(define_expand "storeti"
4085 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4086 ;; (match_operand:TI 1 "s_register_operand" ""))]
4089 ;;(define_expand "movti"
4090 ;; [(set (match_operand:TI 0 "general_operand" "")
4091 ;; (match_operand:TI 1 "general_operand" ""))]
4097 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4098 ;; operands[1] = copy_to_reg (operands[1]);
4099 ;; if (GET_CODE (operands[0]) == MEM)
4100 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4101 ;; else if (GET_CODE (operands[1]) == MEM)
4102 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4106 ;; emit_insn (insn);
4110 ;; Recognize garbage generated above.
4113 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4114 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4118 ;; register mem = (which_alternative < 3);
4119 ;; register const char *template;
4121 ;; operands[mem] = XEXP (operands[mem], 0);
4122 ;; switch (which_alternative)
4124 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4125 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4126 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4127 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4128 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4129 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4131 ;; output_asm_insn (template, operands);
4135 (define_expand "movdi"
4136 [(set (match_operand:DI 0 "general_operand" "")
4137 (match_operand:DI 1 "general_operand" ""))]
4142 if (!no_new_pseudos)
4144 if (GET_CODE (operands[0]) != REG)
4145 operands[1] = force_reg (DImode, operands[1]);
4151 (define_insn "*arm_movdi"
4152 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
4153 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
4155 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4158 switch (which_alternative)
4165 return output_move_double (operands);
4168 [(set_attr "length" "8,12,16,8,8")
4169 (set_attr "type" "*,*,*,load2,store2")
4170 (set_attr "pool_range" "*,*,*,1020,*")
4171 (set_attr "neg_pool_range" "*,*,*,1008,*")]
4175 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4176 (match_operand:ANY64 1 "const_double_operand" ""))]
4179 && (arm_const_double_inline_cost (operands[1])
4180 <= ((optimize_size || arm_ld_sched) ? 3 : 4))"
4183 arm_split_constant (SET, SImode, curr_insn,
4184 INTVAL (gen_lowpart (SImode, operands[1])),
4185 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
4186 arm_split_constant (SET, SImode, curr_insn,
4187 INTVAL (gen_highpart_mode (SImode,
4188 GET_MODE (operands[0]),
4190 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
4196 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4197 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
4198 "TARGET_EITHER && reload_completed"
4199 [(set (match_dup 0) (match_dup 1))
4200 (set (match_dup 2) (match_dup 3))]
4202 operands[2] = gen_highpart (SImode, operands[0]);
4203 operands[3] = gen_highpart (SImode, operands[1]);
4204 operands[0] = gen_lowpart (SImode, operands[0]);
4205 operands[1] = gen_lowpart (SImode, operands[1]);
4207 /* Handle a partial overlap. */
4208 if (rtx_equal_p (operands[0], operands[3]))
4210 rtx tmp0 = operands[0];
4211 rtx tmp1 = operands[1];
4213 operands[0] = operands[2];
4214 operands[1] = operands[3];
4221 ;; We can't actually do base+index doubleword loads if the index and
4222 ;; destination overlap. Split here so that we at least have chance to
4225 [(set (match_operand:DI 0 "s_register_operand" "")
4226 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
4227 (match_operand:SI 2 "s_register_operand" ""))))]
4229 && reg_overlap_mentioned_p (operands[0], operands[1])
4230 && reg_overlap_mentioned_p (operands[0], operands[2])"
4232 (plus:SI (match_dup 1)
4235 (mem:DI (match_dup 4)))]
4237 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
4241 ;;; ??? This should have alternatives for constants.
4242 ;;; ??? This was originally identical to the movdf_insn pattern.
4243 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4244 ;;; thumb_reorg with a memory reference.
4245 (define_insn "*thumb_movdi_insn"
4246 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4247 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4249 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4250 && ( register_operand (operands[0], DImode)
4251 || register_operand (operands[1], DImode))"
4254 switch (which_alternative)
4258 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4259 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4260 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4262 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4264 operands[1] = GEN_INT (- INTVAL (operands[1]));
4265 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4267 return \"ldmia\\t%1, {%0, %H0}\";
4269 return \"stmia\\t%0, {%1, %H1}\";
4271 return thumb_load_double_from_address (operands);
4273 operands[2] = gen_rtx_MEM (SImode,
4274 plus_constant (XEXP (operands[0], 0), 4));
4275 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4278 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4279 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4280 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4283 [(set_attr "length" "4,4,6,2,2,6,4,4")
4284 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4285 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4288 (define_expand "movsi"
4289 [(set (match_operand:SI 0 "general_operand" "")
4290 (match_operand:SI 1 "general_operand" ""))]
4295 /* Everything except mem = const or mem = mem can be done easily. */
4296 if (GET_CODE (operands[0]) == MEM)
4297 operands[1] = force_reg (SImode, operands[1]);
4298 if (arm_general_register_operand (operands[0], SImode)
4299 && GET_CODE (operands[1]) == CONST_INT
4300 && !(const_ok_for_arm (INTVAL (operands[1]))
4301 || const_ok_for_arm (~INTVAL (operands[1]))))
4303 arm_split_constant (SET, SImode, NULL_RTX,
4304 INTVAL (operands[1]), operands[0], NULL_RTX,
4305 optimize && !no_new_pseudos);
4309 else /* TARGET_THUMB.... */
4311 if (!no_new_pseudos)
4313 if (GET_CODE (operands[0]) != REG)
4314 operands[1] = force_reg (SImode, operands[1]);
4319 && (CONSTANT_P (operands[1])
4320 || symbol_mentioned_p (operands[1])
4321 || label_mentioned_p (operands[1])))
4322 operands[1] = legitimize_pic_address (operands[1], SImode,
4323 (no_new_pseudos ? operands[0] : 0));
4327 (define_insn "*arm_movsi_insn"
4328 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4329 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4330 "TARGET_ARM && ! TARGET_IWMMXT
4331 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4332 && ( register_operand (operands[0], SImode)
4333 || register_operand (operands[1], SImode))"
4339 [(set_attr "type" "*,*,load1,store1")
4340 (set_attr "predicable" "yes")
4341 (set_attr "pool_range" "*,*,4096,*")
4342 (set_attr "neg_pool_range" "*,*,4084,*")]
4346 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4347 (match_operand:SI 1 "const_int_operand" ""))]
4349 && (!(const_ok_for_arm (INTVAL (operands[1]))
4350 || const_ok_for_arm (~INTVAL (operands[1]))))"
4351 [(clobber (const_int 0))]
4353 arm_split_constant (SET, SImode, NULL_RTX,
4354 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4359 (define_insn "*thumb_movsi_insn"
4360 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4361 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4363 && ( register_operand (operands[0], SImode)
4364 || register_operand (operands[1], SImode))"
4375 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4376 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4377 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4381 [(set (match_operand:SI 0 "register_operand" "")
4382 (match_operand:SI 1 "const_int_operand" ""))]
4383 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4384 [(set (match_dup 0) (match_dup 1))
4385 (set (match_dup 0) (neg:SI (match_dup 0)))]
4386 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4390 [(set (match_operand:SI 0 "register_operand" "")
4391 (match_operand:SI 1 "const_int_operand" ""))]
4392 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4393 [(set (match_dup 0) (match_dup 1))
4394 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4397 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4398 unsigned HOST_WIDE_INT mask = 0xff;
4401 for (i = 0; i < 25; i++)
4402 if ((val & (mask << i)) == val)
4405 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4409 operands[1] = GEN_INT (val >> i);
4410 operands[2] = GEN_INT (i);
4414 ;; When generating pic, we need to load the symbol offset into a register.
4415 ;; So that the optimizer does not confuse this with a normal symbol load
4416 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4417 ;; since that is the only type of relocation we can use.
4419 ;; The rather odd constraints on the following are to force reload to leave
4420 ;; the insn alone, and to force the minipool generation pass to then move
4421 ;; the GOT symbol to memory.
4423 (define_insn "pic_load_addr_arm"
4424 [(set (match_operand:SI 0 "s_register_operand" "=r")
4425 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4426 "TARGET_ARM && flag_pic"
4428 [(set_attr "type" "load1")
4429 (set (attr "pool_range") (const_int 4096))
4430 (set (attr "neg_pool_range") (const_int 4084))]
4433 (define_insn "pic_load_addr_thumb"
4434 [(set (match_operand:SI 0 "s_register_operand" "=l")
4435 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4436 "TARGET_THUMB && flag_pic"
4438 [(set_attr "type" "load1")
4439 (set (attr "pool_range") (const_int 1024))]
4442 ;; This variant is used for AOF assembly, since it needs to mention the
4443 ;; pic register in the rtl.
4444 (define_expand "pic_load_addr_based"
4445 [(set (match_operand:SI 0 "s_register_operand" "")
4446 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4447 "TARGET_ARM && flag_pic"
4448 "operands[2] = pic_offset_table_rtx;"
4451 (define_insn "*pic_load_addr_based_insn"
4452 [(set (match_operand:SI 0 "s_register_operand" "=r")
4453 (unspec:SI [(match_operand 1 "" "")
4454 (match_operand 2 "s_register_operand" "r")]
4456 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4458 #ifdef AOF_ASSEMBLER
4459 operands[1] = aof_pic_entry (operands[1]);
4461 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4464 [(set_attr "type" "load1")
4465 (set (attr "pool_range")
4466 (if_then_else (eq_attr "is_thumb" "yes")
4469 (set (attr "neg_pool_range")
4470 (if_then_else (eq_attr "is_thumb" "yes")
4475 (define_insn "pic_add_dot_plus_four"
4476 [(set (match_operand:SI 0 "register_operand" "+r")
4477 (unspec:SI [(plus:SI (match_dup 0)
4478 (const (plus:SI (pc) (const_int 4))))]
4480 (use (label_ref (match_operand 1 "" "")))]
4481 "TARGET_THUMB && flag_pic"
4483 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4484 CODE_LABEL_NUMBER (operands[1]));
4485 return \"add\\t%0, %|pc\";
4487 [(set_attr "length" "2")]
4490 (define_insn "pic_add_dot_plus_eight"
4491 [(set (match_operand:SI 0 "register_operand" "+r")
4492 (unspec:SI [(plus:SI (match_dup 0)
4493 (const (plus:SI (pc) (const_int 8))))]
4495 (use (label_ref (match_operand 1 "" "")))]
4496 "TARGET_ARM && flag_pic"
4498 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4499 CODE_LABEL_NUMBER (operands[1]));
4500 return \"add%?\\t%0, %|pc, %0\";
4502 [(set_attr "predicable" "yes")]
4505 (define_expand "builtin_setjmp_receiver"
4506 [(label_ref (match_operand 0 "" ""))]
4510 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
4512 arm_load_pic_register (3);
4516 ;; If copying one reg to another we can set the condition codes according to
4517 ;; its value. Such a move is common after a return from subroutine and the
4518 ;; result is being tested against zero.
4520 (define_insn "*movsi_compare0"
4521 [(set (reg:CC CC_REGNUM)
4522 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4524 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4529 sub%?s\\t%0, %1, #0"
4530 [(set_attr "conds" "set")]
4533 ;; Subroutine to store a half word from a register into memory.
4534 ;; Operand 0 is the source register (HImode)
4535 ;; Operand 1 is the destination address in a register (SImode)
4537 ;; In both this routine and the next, we must be careful not to spill
4538 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4539 ;; can generate unrecognizable rtl.
4541 (define_expand "storehi"
4542 [;; store the low byte
4543 (set (match_operand 1 "" "") (match_dup 3))
4544 ;; extract the high byte
4546 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4547 ;; store the high byte
4548 (set (match_dup 4) (match_dup 5))]
4552 rtx op1 = operands[1];
4553 rtx addr = XEXP (op1, 0);
4554 enum rtx_code code = GET_CODE (addr);
4556 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4558 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4560 operands[4] = adjust_address (op1, QImode, 1);
4561 operands[1] = adjust_address (operands[1], QImode, 0);
4562 operands[3] = gen_lowpart (QImode, operands[0]);
4563 operands[0] = gen_lowpart (SImode, operands[0]);
4564 operands[2] = gen_reg_rtx (SImode);
4565 operands[5] = gen_lowpart (QImode, operands[2]);
4569 (define_expand "storehi_bigend"
4570 [(set (match_dup 4) (match_dup 3))
4572 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4573 (set (match_operand 1 "" "") (match_dup 5))]
4577 rtx op1 = operands[1];
4578 rtx addr = XEXP (op1, 0);
4579 enum rtx_code code = GET_CODE (addr);
4581 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4583 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4585 operands[4] = adjust_address (op1, QImode, 1);
4586 operands[1] = adjust_address (operands[1], QImode, 0);
4587 operands[3] = gen_lowpart (QImode, operands[0]);
4588 operands[0] = gen_lowpart (SImode, operands[0]);
4589 operands[2] = gen_reg_rtx (SImode);
4590 operands[5] = gen_lowpart (QImode, operands[2]);
4594 ;; Subroutine to store a half word integer constant into memory.
4595 (define_expand "storeinthi"
4596 [(set (match_operand 0 "" "")
4597 (match_operand 1 "" ""))
4598 (set (match_dup 3) (match_dup 2))]
4602 HOST_WIDE_INT value = INTVAL (operands[1]);
4603 rtx addr = XEXP (operands[0], 0);
4604 rtx op0 = operands[0];
4605 enum rtx_code code = GET_CODE (addr);
4607 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4609 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4611 operands[1] = gen_reg_rtx (SImode);
4612 if (BYTES_BIG_ENDIAN)
4614 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4615 if ((value & 255) == ((value >> 8) & 255))
4616 operands[2] = operands[1];
4619 operands[2] = gen_reg_rtx (SImode);
4620 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4625 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4626 if ((value & 255) == ((value >> 8) & 255))
4627 operands[2] = operands[1];
4630 operands[2] = gen_reg_rtx (SImode);
4631 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4635 operands[3] = adjust_address (op0, QImode, 1);
4636 operands[0] = adjust_address (operands[0], QImode, 0);
4637 operands[2] = gen_lowpart (QImode, operands[2]);
4638 operands[1] = gen_lowpart (QImode, operands[1]);
4642 (define_expand "storehi_single_op"
4643 [(set (match_operand:HI 0 "memory_operand" "")
4644 (match_operand:HI 1 "general_operand" ""))]
4645 "TARGET_ARM && arm_arch4"
4647 if (!s_register_operand (operands[1], HImode))
4648 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4652 (define_expand "movhi"
4653 [(set (match_operand:HI 0 "general_operand" "")
4654 (match_operand:HI 1 "general_operand" ""))]
4659 if (!no_new_pseudos)
4661 if (GET_CODE (operands[0]) == MEM)
4665 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4668 if (GET_CODE (operands[1]) == CONST_INT)
4669 emit_insn (gen_storeinthi (operands[0], operands[1]));
4672 if (GET_CODE (operands[1]) == MEM)
4673 operands[1] = force_reg (HImode, operands[1]);
4674 if (BYTES_BIG_ENDIAN)
4675 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4677 emit_insn (gen_storehi (operands[1], operands[0]));
4681 /* Sign extend a constant, and keep it in an SImode reg. */
4682 else if (GET_CODE (operands[1]) == CONST_INT)
4684 rtx reg = gen_reg_rtx (SImode);
4685 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4687 /* If the constant is already valid, leave it alone. */
4688 if (!const_ok_for_arm (val))
4690 /* If setting all the top bits will make the constant
4691 loadable in a single instruction, then set them.
4692 Otherwise, sign extend the number. */
4694 if (const_ok_for_arm (~(val | ~0xffff)))
4696 else if (val & 0x8000)
4700 emit_insn (gen_movsi (reg, GEN_INT (val)));
4701 operands[1] = gen_lowpart (HImode, reg);
4703 else if (arm_arch4 && optimize && !no_new_pseudos
4704 && GET_CODE (operands[1]) == MEM)
4706 rtx reg = gen_reg_rtx (SImode);
4708 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4709 operands[1] = gen_lowpart (HImode, reg);
4711 else if (!arm_arch4)
4713 if (GET_CODE (operands[1]) == MEM)
4716 rtx offset = const0_rtx;
4717 rtx reg = gen_reg_rtx (SImode);
4719 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4720 || (GET_CODE (base) == PLUS
4721 && (GET_CODE (offset = XEXP (base, 1))
4723 && ((INTVAL(offset) & 1) != 1)
4724 && GET_CODE (base = XEXP (base, 0)) == REG))
4725 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4727 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4730 new = gen_rtx_MEM (SImode,
4731 plus_constant (base, new_offset));
4732 MEM_COPY_ATTRIBUTES (new, operands[1]);
4733 emit_insn (gen_movsi (reg, new));
4734 if (((INTVAL (offset) & 2) != 0)
4735 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4737 rtx reg2 = gen_reg_rtx (SImode);
4739 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
4744 emit_insn (gen_movhi_bytes (reg, operands[1]));
4746 operands[1] = gen_lowpart (HImode, reg);
4750 /* Handle loading a large integer during reload. */
4751 else if (GET_CODE (operands[1]) == CONST_INT
4752 && !const_ok_for_arm (INTVAL (operands[1]))
4753 && !const_ok_for_arm (~INTVAL (operands[1])))
4755 /* Writing a constant to memory needs a scratch, which should
4756 be handled with SECONDARY_RELOADs. */
4757 if (GET_CODE (operands[0]) != REG)
4760 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4761 emit_insn (gen_movsi (operands[0], operands[1]));
4765 else /* TARGET_THUMB */
4767 if (!no_new_pseudos)
4769 if (GET_CODE (operands[0]) != REG)
4770 operands[1] = force_reg (HImode, operands[1]);
4772 /* ??? We shouldn't really get invalid addresses here, but this can
4773 happen if we are passed a SP (never OK for HImode/QImode) or
4774 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4775 HImode/QImode) relative address. */
4776 /* ??? This should perhaps be fixed elsewhere, for instance, in
4777 fixup_stack_1, by checking for other kinds of invalid addresses,
4778 e.g. a bare reference to a virtual register. This may confuse the
4779 alpha though, which must handle this case differently. */
4780 if (GET_CODE (operands[0]) == MEM
4781 && !memory_address_p (GET_MODE (operands[0]),
4782 XEXP (operands[0], 0)))
4784 = replace_equiv_address (operands[0],
4785 copy_to_reg (XEXP (operands[0], 0)));
4787 if (GET_CODE (operands[1]) == MEM
4788 && !memory_address_p (GET_MODE (operands[1]),
4789 XEXP (operands[1], 0)))
4791 = replace_equiv_address (operands[1],
4792 copy_to_reg (XEXP (operands[1], 0)));
4794 /* Handle loading a large integer during reload. */
4795 else if (GET_CODE (operands[1]) == CONST_INT
4796 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4798 /* Writing a constant to memory needs a scratch, which should
4799 be handled with SECONDARY_RELOADs. */
4800 if (GET_CODE (operands[0]) != REG)
4803 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4804 emit_insn (gen_movsi (operands[0], operands[1]));
4811 (define_insn "*thumb_movhi_insn"
4812 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4813 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4815 && ( register_operand (operands[0], HImode)
4816 || register_operand (operands[1], HImode))"
4818 switch (which_alternative)
4820 case 0: return \"add %0, %1, #0\";
4821 case 2: return \"strh %1, %0\";
4822 case 3: return \"mov %0, %1\";
4823 case 4: return \"mov %0, %1\";
4824 case 5: return \"mov %0, %1\";
4827 /* The stack pointer can end up being taken as an index register.
4828 Catch this case here and deal with it. */
4829 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4830 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4831 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4834 ops[0] = operands[0];
4835 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4837 output_asm_insn (\"mov %0, %1\", ops);
4839 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4842 return \"ldrh %0, %1\";
4844 [(set_attr "length" "2,4,2,2,2,2")
4845 (set_attr "type" "*,load1,store1,*,*,*")]
4849 (define_expand "movhi_bytes"
4850 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4852 (zero_extend:SI (match_dup 6)))
4853 (set (match_operand:SI 0 "" "")
4854 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4859 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4861 mem1 = gen_rtx_MEM (QImode, addr);
4862 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4863 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4864 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4865 operands[0] = gen_lowpart (SImode, operands[0]);
4867 operands[2] = gen_reg_rtx (SImode);
4868 operands[3] = gen_reg_rtx (SImode);
4871 if (BYTES_BIG_ENDIAN)
4873 operands[4] = operands[2];
4874 operands[5] = operands[3];
4878 operands[4] = operands[3];
4879 operands[5] = operands[2];
4884 (define_expand "movhi_bigend"
4886 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4889 (ashiftrt:SI (match_dup 2) (const_int 16)))
4890 (set (match_operand:HI 0 "s_register_operand" "")
4894 operands[2] = gen_reg_rtx (SImode);
4895 operands[3] = gen_reg_rtx (SImode);
4896 operands[4] = gen_lowpart (HImode, operands[3]);
4900 ;; Pattern to recognize insn generated default case above
4901 (define_insn "*movhi_insn_arch4"
4902 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4903 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4906 && (GET_CODE (operands[1]) != CONST_INT
4907 || const_ok_for_arm (INTVAL (operands[1]))
4908 || const_ok_for_arm (~INTVAL (operands[1])))"
4910 mov%?\\t%0, %1\\t%@ movhi
4911 mvn%?\\t%0, #%B1\\t%@ movhi
4912 str%?h\\t%1, %0\\t%@ movhi
4913 ldr%?h\\t%0, %1\\t%@ movhi"
4914 [(set_attr "type" "*,*,store1,load1")
4915 (set_attr "predicable" "yes")
4916 (set_attr "pool_range" "*,*,*,256")
4917 (set_attr "neg_pool_range" "*,*,*,244")]
4920 (define_insn "*movhi_bytes"
4921 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4922 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4925 mov%?\\t%0, %1\\t%@ movhi
4926 mvn%?\\t%0, #%B1\\t%@ movhi"
4927 [(set_attr "predicable" "yes")]
4930 (define_insn "thumb_movhi_clobber"
4931 [(set (match_operand:HI 0 "memory_operand" "=m")
4932 (match_operand:HI 1 "register_operand" "l"))
4933 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4939 ;; We use a DImode scratch because we may occasionally need an additional
4940 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4941 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4942 (define_expand "reload_outhi"
4943 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4944 (match_operand:HI 1 "s_register_operand" "r")
4945 (match_operand:DI 2 "s_register_operand" "=&l")])]
4948 arm_reload_out_hi (operands);
4950 thumb_reload_out_hi (operands);
4955 (define_expand "reload_inhi"
4956 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4957 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4958 (match_operand:DI 2 "s_register_operand" "=&r")])]
4962 arm_reload_in_hi (operands);
4964 thumb_reload_out_hi (operands);
4968 (define_expand "movqi"
4969 [(set (match_operand:QI 0 "general_operand" "")
4970 (match_operand:QI 1 "general_operand" ""))]
4975 /* Everything except mem = const or mem = mem can be done easily */
4977 if (!no_new_pseudos)
4979 if (GET_CODE (operands[1]) == CONST_INT)
4981 rtx reg = gen_reg_rtx (SImode);
4983 emit_insn (gen_movsi (reg, operands[1]));
4984 operands[1] = gen_lowpart (QImode, reg);
4986 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4988 rtx reg = gen_reg_rtx (SImode);
4990 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4991 operands[1] = gen_lowpart (QImode, reg);
4993 if (GET_CODE (operands[0]) == MEM)
4994 operands[1] = force_reg (QImode, operands[1]);
4997 else /* TARGET_THUMB */
4999 if (!no_new_pseudos)
5001 if (GET_CODE (operands[0]) != REG)
5002 operands[1] = force_reg (QImode, operands[1]);
5004 /* ??? We shouldn't really get invalid addresses here, but this can
5005 happen if we are passed a SP (never OK for HImode/QImode) or
5006 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
5007 HImode/QImode) relative address. */
5008 /* ??? This should perhaps be fixed elsewhere, for instance, in
5009 fixup_stack_1, by checking for other kinds of invalid addresses,
5010 e.g. a bare reference to a virtual register. This may confuse the
5011 alpha though, which must handle this case differently. */
5012 if (GET_CODE (operands[0]) == MEM
5013 && !memory_address_p (GET_MODE (operands[0]),
5014 XEXP (operands[0], 0)))
5016 = replace_equiv_address (operands[0],
5017 copy_to_reg (XEXP (operands[0], 0)));
5018 if (GET_CODE (operands[1]) == MEM
5019 && !memory_address_p (GET_MODE (operands[1]),
5020 XEXP (operands[1], 0)))
5022 = replace_equiv_address (operands[1],
5023 copy_to_reg (XEXP (operands[1], 0)));
5025 /* Handle loading a large integer during reload. */
5026 else if (GET_CODE (operands[1]) == CONST_INT
5027 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
5029 /* Writing a constant to memory needs a scratch, which should
5030 be handled with SECONDARY_RELOADs. */
5031 if (GET_CODE (operands[0]) != REG)
5034 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5035 emit_insn (gen_movsi (operands[0], operands[1]));
5043 (define_insn "*arm_movqi_insn"
5044 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5045 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
5047 && ( register_operand (operands[0], QImode)
5048 || register_operand (operands[1], QImode))"
5054 [(set_attr "type" "*,*,load1,store1")
5055 (set_attr "predicable" "yes")]
5058 (define_insn "*thumb_movqi_insn"
5059 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5060 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5062 && ( register_operand (operands[0], QImode)
5063 || register_operand (operands[1], QImode))"
5071 [(set_attr "length" "2")
5072 (set_attr "type" "*,load1,store1,*,*,*")
5073 (set_attr "pool_range" "*,32,*,*,*,*")]
5076 (define_expand "movsf"
5077 [(set (match_operand:SF 0 "general_operand" "")
5078 (match_operand:SF 1 "general_operand" ""))]
5083 if (GET_CODE (operands[0]) == MEM)
5084 operands[1] = force_reg (SFmode, operands[1]);
5086 else /* TARGET_THUMB */
5088 if (!no_new_pseudos)
5090 if (GET_CODE (operands[0]) != REG)
5091 operands[1] = force_reg (SFmode, operands[1]);
5098 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5099 (match_operand:SF 1 "immediate_operand" ""))]
5101 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5103 && GET_CODE (operands[1]) == CONST_DOUBLE"
5104 [(set (match_dup 2) (match_dup 3))]
5106 operands[2] = gen_lowpart (SImode, operands[0]);
5107 operands[3] = gen_lowpart (SImode, operands[1]);
5108 if (operands[2] == 0 || operands[3] == 0)
5113 (define_insn "*arm_movsf_soft_insn"
5114 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5115 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5117 && TARGET_SOFT_FLOAT
5118 && (GET_CODE (operands[0]) != MEM
5119 || register_operand (operands[1], SFmode))"
5122 ldr%?\\t%0, %1\\t%@ float
5123 str%?\\t%1, %0\\t%@ float"
5124 [(set_attr "length" "4,4,4")
5125 (set_attr "predicable" "yes")
5126 (set_attr "type" "*,load1,store1")
5127 (set_attr "pool_range" "*,4096,*")
5128 (set_attr "neg_pool_range" "*,4084,*")]
5131 ;;; ??? This should have alternatives for constants.
5132 (define_insn "*thumb_movsf_insn"
5133 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5134 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5136 && ( register_operand (operands[0], SFmode)
5137 || register_operand (operands[1], SFmode))"
5146 [(set_attr "length" "2")
5147 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5148 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5151 (define_expand "movdf"
5152 [(set (match_operand:DF 0 "general_operand" "")
5153 (match_operand:DF 1 "general_operand" ""))]
5158 if (GET_CODE (operands[0]) == MEM)
5159 operands[1] = force_reg (DFmode, operands[1]);
5161 else /* TARGET_THUMB */
5163 if (!no_new_pseudos)
5165 if (GET_CODE (operands[0]) != REG)
5166 operands[1] = force_reg (DFmode, operands[1]);
5172 ;; Reloading a df mode value stored in integer regs to memory can require a
5174 (define_expand "reload_outdf"
5175 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5176 (match_operand:DF 1 "s_register_operand" "r")
5177 (match_operand:SI 2 "s_register_operand" "=&r")]
5181 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5184 operands[2] = XEXP (operands[0], 0);
5185 else if (code == POST_INC || code == PRE_DEC)
5187 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5188 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5189 emit_insn (gen_movdi (operands[0], operands[1]));
5192 else if (code == PRE_INC)
5194 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5196 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5199 else if (code == POST_DEC)
5200 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5202 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5203 XEXP (XEXP (operands[0], 0), 1)));
5205 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5208 if (code == POST_DEC)
5209 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5215 (define_insn "*movdf_soft_insn"
5216 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
5217 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
5218 "TARGET_ARM && TARGET_SOFT_FLOAT
5221 switch (which_alternative)
5228 return output_move_double (operands);
5231 [(set_attr "length" "8,12,16,8,8")
5232 (set_attr "type" "*,*,*,load2,store2")
5233 (set_attr "pool_range" "1020")
5234 (set_attr "neg_pool_range" "1008")]
5237 ;;; ??? This should have alternatives for constants.
5238 ;;; ??? This was originally identical to the movdi_insn pattern.
5239 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5240 ;;; thumb_reorg with a memory reference.
5241 (define_insn "*thumb_movdf_insn"
5242 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5243 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5245 && ( register_operand (operands[0], DFmode)
5246 || register_operand (operands[1], DFmode))"
5248 switch (which_alternative)
5252 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5253 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5254 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5256 return \"ldmia\\t%1, {%0, %H0}\";
5258 return \"stmia\\t%0, {%1, %H1}\";
5260 return thumb_load_double_from_address (operands);
5262 operands[2] = gen_rtx_MEM (SImode,
5263 plus_constant (XEXP (operands[0], 0), 4));
5264 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5267 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5268 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5269 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5272 [(set_attr "length" "4,2,2,6,4,4")
5273 (set_attr "type" "*,load2,store2,load2,store2,*")
5274 (set_attr "pool_range" "*,*,*,1020,*,*")]
5277 (define_expand "movxf"
5278 [(set (match_operand:XF 0 "general_operand" "")
5279 (match_operand:XF 1 "general_operand" ""))]
5280 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
5282 if (GET_CODE (operands[0]) == MEM)
5283 operands[1] = force_reg (XFmode, operands[1]);
5288 (define_expand "movv2si"
5289 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5290 (match_operand:V2SI 1 "general_operand" ""))]
5291 "TARGET_REALLY_IWMMXT"
5295 (define_expand "movv4hi"
5296 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5297 (match_operand:V4HI 1 "general_operand" ""))]
5298 "TARGET_REALLY_IWMMXT"
5302 (define_expand "movv8qi"
5303 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5304 (match_operand:V8QI 1 "general_operand" ""))]
5305 "TARGET_REALLY_IWMMXT"
5310 ;; load- and store-multiple insns
5311 ;; The arm can load/store any set of registers, provided that they are in
5312 ;; ascending order; but that is beyond GCC so stick with what it knows.
5314 (define_expand "load_multiple"
5315 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5316 (match_operand:SI 1 "" ""))
5317 (use (match_operand:SI 2 "" ""))])]
5320 HOST_WIDE_INT offset = 0;
5322 /* Support only fixed point registers. */
5323 if (GET_CODE (operands[2]) != CONST_INT
5324 || INTVAL (operands[2]) > 14
5325 || INTVAL (operands[2]) < 2
5326 || GET_CODE (operands[1]) != MEM
5327 || GET_CODE (operands[0]) != REG
5328 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5329 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5333 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5334 force_reg (SImode, XEXP (operands[1], 0)),
5335 TRUE, FALSE, operands[1], &offset);
5338 ;; Load multiple with write-back
5340 (define_insn "*ldmsi_postinc4"
5341 [(match_parallel 0 "load_multiple_operation"
5342 [(set (match_operand:SI 1 "s_register_operand" "=r")
5343 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5345 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5346 (mem:SI (match_dup 2)))
5347 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5348 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5349 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5350 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5351 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5352 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5353 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5354 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5355 [(set_attr "type" "load4")
5356 (set_attr "predicable" "yes")]
5359 (define_insn "*ldmsi_postinc4_thumb"
5360 [(match_parallel 0 "load_multiple_operation"
5361 [(set (match_operand:SI 1 "s_register_operand" "=l")
5362 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5364 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5365 (mem:SI (match_dup 2)))
5366 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5367 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5368 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5369 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5370 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5371 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5372 "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
5373 "ldmia\\t%1!, {%3, %4, %5, %6}"
5374 [(set_attr "type" "load4")]
5377 (define_insn "*ldmsi_postinc3"
5378 [(match_parallel 0 "load_multiple_operation"
5379 [(set (match_operand:SI 1 "s_register_operand" "=r")
5380 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5382 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5383 (mem:SI (match_dup 2)))
5384 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5385 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5386 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5387 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5388 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5389 "ldm%?ia\\t%1!, {%3, %4, %5}"
5390 [(set_attr "type" "load3")
5391 (set_attr "predicable" "yes")]
5394 (define_insn "*ldmsi_postinc2"
5395 [(match_parallel 0 "load_multiple_operation"
5396 [(set (match_operand:SI 1 "s_register_operand" "=r")
5397 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5399 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5400 (mem:SI (match_dup 2)))
5401 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5402 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5403 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5404 "ldm%?ia\\t%1!, {%3, %4}"
5405 [(set_attr "type" "load2")
5406 (set_attr "predicable" "yes")]
5409 ;; Ordinary load multiple
5411 (define_insn "*ldmsi4"
5412 [(match_parallel 0 "load_multiple_operation"
5413 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5414 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5415 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5416 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5417 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5418 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5419 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5420 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5421 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5422 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5423 [(set_attr "type" "load4")
5424 (set_attr "predicable" "yes")]
5427 (define_insn "*ldmsi3"
5428 [(match_parallel 0 "load_multiple_operation"
5429 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5430 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5431 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5432 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5433 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5434 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5435 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5436 "ldm%?ia\\t%1, {%2, %3, %4}"
5437 [(set_attr "type" "load3")
5438 (set_attr "predicable" "yes")]
5441 (define_insn "*ldmsi2"
5442 [(match_parallel 0 "load_multiple_operation"
5443 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5444 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5445 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5446 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5447 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5448 "ldm%?ia\\t%1, {%2, %3}"
5449 [(set_attr "type" "load2")
5450 (set_attr "predicable" "yes")]
5453 (define_expand "store_multiple"
5454 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5455 (match_operand:SI 1 "" ""))
5456 (use (match_operand:SI 2 "" ""))])]
5459 HOST_WIDE_INT offset = 0;
5461 /* Support only fixed point registers. */
5462 if (GET_CODE (operands[2]) != CONST_INT
5463 || INTVAL (operands[2]) > 14
5464 || INTVAL (operands[2]) < 2
5465 || GET_CODE (operands[1]) != REG
5466 || GET_CODE (operands[0]) != MEM
5467 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5468 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5472 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5473 force_reg (SImode, XEXP (operands[0], 0)),
5474 TRUE, FALSE, operands[0], &offset);
5477 ;; Store multiple with write-back
5479 (define_insn "*stmsi_postinc4"
5480 [(match_parallel 0 "store_multiple_operation"
5481 [(set (match_operand:SI 1 "s_register_operand" "=r")
5482 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5484 (set (mem:SI (match_dup 2))
5485 (match_operand:SI 3 "arm_hard_register_operand" ""))
5486 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5487 (match_operand:SI 4 "arm_hard_register_operand" ""))
5488 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5489 (match_operand:SI 5 "arm_hard_register_operand" ""))
5490 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5491 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5492 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5493 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5494 [(set_attr "predicable" "yes")
5495 (set_attr "type" "store4")]
5498 (define_insn "*stmsi_postinc4_thumb"
5499 [(match_parallel 0 "store_multiple_operation"
5500 [(set (match_operand:SI 1 "s_register_operand" "=l")
5501 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5503 (set (mem:SI (match_dup 2))
5504 (match_operand:SI 3 "arm_hard_register_operand" ""))
5505 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5506 (match_operand:SI 4 "arm_hard_register_operand" ""))
5507 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5508 (match_operand:SI 5 "arm_hard_register_operand" ""))
5509 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5510 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5511 "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
5512 "stmia\\t%1!, {%3, %4, %5, %6}"
5513 [(set_attr "type" "store4")]
5516 (define_insn "*stmsi_postinc3"
5517 [(match_parallel 0 "store_multiple_operation"
5518 [(set (match_operand:SI 1 "s_register_operand" "=r")
5519 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5521 (set (mem:SI (match_dup 2))
5522 (match_operand:SI 3 "arm_hard_register_operand" ""))
5523 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5524 (match_operand:SI 4 "arm_hard_register_operand" ""))
5525 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5526 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5527 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5528 "stm%?ia\\t%1!, {%3, %4, %5}"
5529 [(set_attr "predicable" "yes")
5530 (set_attr "type" "store3")]
5533 (define_insn "*stmsi_postinc2"
5534 [(match_parallel 0 "store_multiple_operation"
5535 [(set (match_operand:SI 1 "s_register_operand" "=r")
5536 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5538 (set (mem:SI (match_dup 2))
5539 (match_operand:SI 3 "arm_hard_register_operand" ""))
5540 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5541 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5542 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5543 "stm%?ia\\t%1!, {%3, %4}"
5544 [(set_attr "predicable" "yes")
5545 (set_attr "type" "store2")]
5548 ;; Ordinary store multiple
5550 (define_insn "*stmsi4"
5551 [(match_parallel 0 "store_multiple_operation"
5552 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5553 (match_operand:SI 2 "arm_hard_register_operand" ""))
5554 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5555 (match_operand:SI 3 "arm_hard_register_operand" ""))
5556 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5557 (match_operand:SI 4 "arm_hard_register_operand" ""))
5558 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5559 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5560 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5561 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5562 [(set_attr "predicable" "yes")
5563 (set_attr "type" "store4")]
5566 (define_insn "*stmsi3"
5567 [(match_parallel 0 "store_multiple_operation"
5568 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5569 (match_operand:SI 2 "arm_hard_register_operand" ""))
5570 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5571 (match_operand:SI 3 "arm_hard_register_operand" ""))
5572 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5573 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5574 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5575 "stm%?ia\\t%1, {%2, %3, %4}"
5576 [(set_attr "predicable" "yes")
5577 (set_attr "type" "store3")]
5580 (define_insn "*stmsi2"
5581 [(match_parallel 0 "store_multiple_operation"
5582 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5583 (match_operand:SI 2 "arm_hard_register_operand" ""))
5584 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5585 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5586 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5587 "stm%?ia\\t%1, {%2, %3}"
5588 [(set_attr "predicable" "yes")
5589 (set_attr "type" "store2")]
5592 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5593 ;; We could let this apply for blocks of less than this, but it clobbers so
5594 ;; many registers that there is then probably a better way.
5596 (define_expand "movmemqi"
5597 [(match_operand:BLK 0 "general_operand" "")
5598 (match_operand:BLK 1 "general_operand" "")
5599 (match_operand:SI 2 "const_int_operand" "")
5600 (match_operand:SI 3 "const_int_operand" "")]
5605 if (arm_gen_movmemqi (operands))
5609 else /* TARGET_THUMB */
5611 if ( INTVAL (operands[3]) != 4
5612 || INTVAL (operands[2]) > 48)
5615 thumb_expand_movmemqi (operands);
5621 ;; Thumb block-move insns
5623 (define_insn "movmem12b"
5624 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5625 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5626 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5627 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5628 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5629 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5630 (set (match_operand:SI 0 "register_operand" "=l")
5631 (plus:SI (match_dup 2) (const_int 12)))
5632 (set (match_operand:SI 1 "register_operand" "=l")
5633 (plus:SI (match_dup 3) (const_int 12)))
5634 (clobber (match_scratch:SI 4 "=&l"))
5635 (clobber (match_scratch:SI 5 "=&l"))
5636 (clobber (match_scratch:SI 6 "=&l"))]
5638 "* return thumb_output_move_mem_multiple (3, operands);"
5639 [(set_attr "length" "4")
5640 ; This isn't entirely accurate... It loads as well, but in terms of
5641 ; scheduling the following insn it is better to consider it as a store
5642 (set_attr "type" "store3")]
5645 (define_insn "movmem8b"
5646 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5647 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5648 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5649 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5650 (set (match_operand:SI 0 "register_operand" "=l")
5651 (plus:SI (match_dup 2) (const_int 8)))
5652 (set (match_operand:SI 1 "register_operand" "=l")
5653 (plus:SI (match_dup 3) (const_int 8)))
5654 (clobber (match_scratch:SI 4 "=&l"))
5655 (clobber (match_scratch:SI 5 "=&l"))]
5657 "* return thumb_output_move_mem_multiple (2, operands);"
5658 [(set_attr "length" "4")
5659 ; This isn't entirely accurate... It loads as well, but in terms of
5660 ; scheduling the following insn it is better to consider it as a store
5661 (set_attr "type" "store2")]
5666 ;; Compare & branch insns
5667 ;; The range calculations are based as follows:
5668 ;; For forward branches, the address calculation returns the address of
5669 ;; the next instruction. This is 2 beyond the branch instruction.
5670 ;; For backward branches, the address calculation returns the address of
5671 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5672 ;; instruction for the shortest sequence, and 4 before the branch instruction
5673 ;; if we have to jump around an unconditional branch.
5674 ;; To the basic branch range the PC offset must be added (this is +4).
5675 ;; So for forward branches we have
5676 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5677 ;; And for backward branches we have
5678 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5680 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5681 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5683 (define_expand "cbranchsi4"
5684 [(set (pc) (if_then_else
5685 (match_operator 0 "arm_comparison_operator"
5686 [(match_operand:SI 1 "s_register_operand" "")
5687 (match_operand:SI 2 "nonmemory_operand" "")])
5688 (label_ref (match_operand 3 "" ""))
5692 if (thumb_cmpneg_operand (operands[2], SImode))
5694 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5695 operands[3], operands[0]));
5698 if (!thumb_cmp_operand (operands[2], SImode))
5699 operands[2] = force_reg (SImode, operands[2]);
5702 (define_insn "*cbranchsi4_insn"
5703 [(set (pc) (if_then_else
5704 (match_operator 0 "arm_comparison_operator"
5705 [(match_operand:SI 1 "s_register_operand" "l,*h")
5706 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5707 (label_ref (match_operand 3 "" ""))
5711 output_asm_insn (\"cmp\\t%1, %2\", operands);
5713 switch (get_attr_length (insn))
5715 case 4: return \"b%d0\\t%l3\";
5716 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5717 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5720 [(set (attr "far_jump")
5722 (eq_attr "length" "8")
5723 (const_string "yes")
5724 (const_string "no")))
5725 (set (attr "length")
5727 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5728 (le (minus (match_dup 3) (pc)) (const_int 256)))
5731 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5732 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5737 (define_insn "cbranchsi4_scratch"
5738 [(set (pc) (if_then_else
5739 (match_operator 4 "arm_comparison_operator"
5740 [(match_operand:SI 1 "s_register_operand" "l,0")
5741 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5742 (label_ref (match_operand 3 "" ""))
5744 (clobber (match_scratch:SI 0 "=l,l"))]
5747 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5749 switch (get_attr_length (insn))
5751 case 4: return \"b%d4\\t%l3\";
5752 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5753 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5756 [(set (attr "far_jump")
5758 (eq_attr "length" "8")
5759 (const_string "yes")
5760 (const_string "no")))
5761 (set (attr "length")
5763 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5764 (le (minus (match_dup 3) (pc)) (const_int 256)))
5767 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5768 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5772 (define_insn "*movsi_cbranchsi4"
5775 (match_operator 3 "arm_comparison_operator"
5776 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5778 (label_ref (match_operand 2 "" ""))
5780 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5784 if (which_alternative == 0)
5785 output_asm_insn (\"cmp\t%0, #0\", operands);
5786 else if (which_alternative == 1)
5787 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5790 output_asm_insn (\"cmp\t%1, #0\", operands);
5791 if (which_alternative == 2)
5792 output_asm_insn (\"mov\t%0, %1\", operands);
5794 output_asm_insn (\"str\t%1, %0\", operands);
5796 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5798 case 4: return \"b%d3\\t%l2\";
5799 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5800 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5803 [(set (attr "far_jump")
5805 (ior (and (gt (symbol_ref ("which_alternative"))
5807 (eq_attr "length" "8"))
5808 (eq_attr "length" "10"))
5809 (const_string "yes")
5810 (const_string "no")))
5811 (set (attr "length")
5813 (le (symbol_ref ("which_alternative"))
5816 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5817 (le (minus (match_dup 2) (pc)) (const_int 256)))
5820 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5821 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5825 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5826 (le (minus (match_dup 2) (pc)) (const_int 256)))
5829 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5830 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5835 (define_insn "*negated_cbranchsi4"
5838 (match_operator 0 "equality_operator"
5839 [(match_operand:SI 1 "s_register_operand" "l")
5840 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5841 (label_ref (match_operand 3 "" ""))
5845 output_asm_insn (\"cmn\\t%1, %2\", operands);
5846 switch (get_attr_length (insn))
5848 case 4: return \"b%d0\\t%l3\";
5849 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5850 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5853 [(set (attr "far_jump")
5855 (eq_attr "length" "8")
5856 (const_string "yes")
5857 (const_string "no")))
5858 (set (attr "length")
5860 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5861 (le (minus (match_dup 3) (pc)) (const_int 256)))
5864 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5865 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5870 (define_insn "*tbit_cbranch"
5873 (match_operator 0 "equality_operator"
5874 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5876 (match_operand:SI 2 "const_int_operand" "i"))
5878 (label_ref (match_operand 3 "" ""))
5880 (clobber (match_scratch:SI 4 "=l"))]
5885 op[0] = operands[4];
5886 op[1] = operands[1];
5887 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5889 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5890 switch (get_attr_length (insn))
5892 case 4: return \"b%d0\\t%l3\";
5893 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5894 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5897 [(set (attr "far_jump")
5899 (eq_attr "length" "8")
5900 (const_string "yes")
5901 (const_string "no")))
5902 (set (attr "length")
5904 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5905 (le (minus (match_dup 3) (pc)) (const_int 256)))
5908 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5909 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5914 (define_insn "*tstsi3_cbranch"
5917 (match_operator 3 "equality_operator"
5918 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5919 (match_operand:SI 1 "s_register_operand" "l"))
5921 (label_ref (match_operand 2 "" ""))
5926 output_asm_insn (\"tst\\t%0, %1\", operands);
5927 switch (get_attr_length (insn))
5929 case 4: return \"b%d3\\t%l2\";
5930 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5931 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5934 [(set (attr "far_jump")
5936 (eq_attr "length" "8")
5937 (const_string "yes")
5938 (const_string "no")))
5939 (set (attr "length")
5941 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5942 (le (minus (match_dup 2) (pc)) (const_int 256)))
5945 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5946 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5951 (define_insn "*andsi3_cbranch"
5954 (match_operator 5 "equality_operator"
5955 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5956 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5958 (label_ref (match_operand 4 "" ""))
5960 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5961 (and:SI (match_dup 2) (match_dup 3)))
5962 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5966 if (which_alternative == 0)
5967 output_asm_insn (\"and\\t%0, %3\", operands);
5968 else if (which_alternative == 1)
5970 output_asm_insn (\"and\\t%1, %3\", operands);
5971 output_asm_insn (\"mov\\t%0, %1\", operands);
5975 output_asm_insn (\"and\\t%1, %3\", operands);
5976 output_asm_insn (\"str\\t%1, %0\", operands);
5979 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5981 case 4: return \"b%d5\\t%l4\";
5982 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5983 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5986 [(set (attr "far_jump")
5988 (ior (and (eq (symbol_ref ("which_alternative"))
5990 (eq_attr "length" "8"))
5991 (eq_attr "length" "10"))
5992 (const_string "yes")
5993 (const_string "no")))
5994 (set (attr "length")
5996 (eq (symbol_ref ("which_alternative"))
5999 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6000 (le (minus (match_dup 4) (pc)) (const_int 256)))
6003 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6004 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6008 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6009 (le (minus (match_dup 4) (pc)) (const_int 256)))
6012 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6013 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6018 (define_insn "*orrsi3_cbranch_scratch"
6021 (match_operator 4 "equality_operator"
6022 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
6023 (match_operand:SI 2 "s_register_operand" "l"))
6025 (label_ref (match_operand 3 "" ""))
6027 (clobber (match_scratch:SI 0 "=l"))]
6031 output_asm_insn (\"orr\\t%0, %2\", operands);
6032 switch (get_attr_length (insn))
6034 case 4: return \"b%d4\\t%l3\";
6035 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6036 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6039 [(set (attr "far_jump")
6041 (eq_attr "length" "8")
6042 (const_string "yes")
6043 (const_string "no")))
6044 (set (attr "length")
6046 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6047 (le (minus (match_dup 3) (pc)) (const_int 256)))
6050 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6051 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6056 (define_insn "*orrsi3_cbranch"
6059 (match_operator 5 "equality_operator"
6060 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6061 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6063 (label_ref (match_operand 4 "" ""))
6065 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6066 (ior:SI (match_dup 2) (match_dup 3)))
6067 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6071 if (which_alternative == 0)
6072 output_asm_insn (\"orr\\t%0, %3\", operands);
6073 else if (which_alternative == 1)
6075 output_asm_insn (\"orr\\t%1, %3\", operands);
6076 output_asm_insn (\"mov\\t%0, %1\", operands);
6080 output_asm_insn (\"orr\\t%1, %3\", operands);
6081 output_asm_insn (\"str\\t%1, %0\", operands);
6084 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6086 case 4: return \"b%d5\\t%l4\";
6087 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6088 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6091 [(set (attr "far_jump")
6093 (ior (and (eq (symbol_ref ("which_alternative"))
6095 (eq_attr "length" "8"))
6096 (eq_attr "length" "10"))
6097 (const_string "yes")
6098 (const_string "no")))
6099 (set (attr "length")
6101 (eq (symbol_ref ("which_alternative"))
6104 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6105 (le (minus (match_dup 4) (pc)) (const_int 256)))
6108 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6109 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6113 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6114 (le (minus (match_dup 4) (pc)) (const_int 256)))
6117 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6118 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6123 (define_insn "*xorsi3_cbranch_scratch"
6126 (match_operator 4 "equality_operator"
6127 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6128 (match_operand:SI 2 "s_register_operand" "l"))
6130 (label_ref (match_operand 3 "" ""))
6132 (clobber (match_scratch:SI 0 "=l"))]
6136 output_asm_insn (\"eor\\t%0, %2\", operands);
6137 switch (get_attr_length (insn))
6139 case 4: return \"b%d4\\t%l3\";
6140 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6141 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6144 [(set (attr "far_jump")
6146 (eq_attr "length" "8")
6147 (const_string "yes")
6148 (const_string "no")))
6149 (set (attr "length")
6151 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6152 (le (minus (match_dup 3) (pc)) (const_int 256)))
6155 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6156 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6161 (define_insn "*xorsi3_cbranch"
6164 (match_operator 5 "equality_operator"
6165 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6166 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6168 (label_ref (match_operand 4 "" ""))
6170 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6171 (xor:SI (match_dup 2) (match_dup 3)))
6172 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6176 if (which_alternative == 0)
6177 output_asm_insn (\"eor\\t%0, %3\", operands);
6178 else if (which_alternative == 1)
6180 output_asm_insn (\"eor\\t%1, %3\", operands);
6181 output_asm_insn (\"mov\\t%0, %1\", operands);
6185 output_asm_insn (\"eor\\t%1, %3\", operands);
6186 output_asm_insn (\"str\\t%1, %0\", operands);
6189 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6191 case 4: return \"b%d5\\t%l4\";
6192 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6193 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6196 [(set (attr "far_jump")
6198 (ior (and (eq (symbol_ref ("which_alternative"))
6200 (eq_attr "length" "8"))
6201 (eq_attr "length" "10"))
6202 (const_string "yes")
6203 (const_string "no")))
6204 (set (attr "length")
6206 (eq (symbol_ref ("which_alternative"))
6209 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6210 (le (minus (match_dup 4) (pc)) (const_int 256)))
6213 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6214 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6218 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6219 (le (minus (match_dup 4) (pc)) (const_int 256)))
6222 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6223 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6228 (define_insn "*bicsi3_cbranch_scratch"
6231 (match_operator 4 "equality_operator"
6232 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6233 (match_operand:SI 1 "s_register_operand" "0"))
6235 (label_ref (match_operand 3 "" ""))
6237 (clobber (match_scratch:SI 0 "=l"))]
6241 output_asm_insn (\"bic\\t%0, %2\", operands);
6242 switch (get_attr_length (insn))
6244 case 4: return \"b%d4\\t%l3\";
6245 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6246 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6249 [(set (attr "far_jump")
6251 (eq_attr "length" "8")
6252 (const_string "yes")
6253 (const_string "no")))
6254 (set (attr "length")
6256 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6257 (le (minus (match_dup 3) (pc)) (const_int 256)))
6260 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6261 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6266 (define_insn "*bicsi3_cbranch"
6269 (match_operator 5 "equality_operator"
6270 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
6271 (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
6273 (label_ref (match_operand 4 "" ""))
6275 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
6276 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6277 (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
6281 if (which_alternative == 0)
6282 output_asm_insn (\"bic\\t%0, %3\", operands);
6283 else if (which_alternative <= 2)
6285 output_asm_insn (\"bic\\t%1, %3\", operands);
6286 /* It's ok if OP0 is a lo-reg, even though the mov will set the
6287 conditions again, since we're only testing for equality. */
6288 output_asm_insn (\"mov\\t%0, %1\", operands);
6292 output_asm_insn (\"bic\\t%1, %3\", operands);
6293 output_asm_insn (\"str\\t%1, %0\", operands);
6296 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6298 case 4: return \"b%d5\\t%l4\";
6299 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6300 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6303 [(set (attr "far_jump")
6305 (ior (and (eq (symbol_ref ("which_alternative"))
6307 (eq_attr "length" "8"))
6308 (eq_attr "length" "10"))
6309 (const_string "yes")
6310 (const_string "no")))
6311 (set (attr "length")
6313 (eq (symbol_ref ("which_alternative"))
6316 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6317 (le (minus (match_dup 4) (pc)) (const_int 256)))
6320 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6321 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6325 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6326 (le (minus (match_dup 4) (pc)) (const_int 256)))
6329 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6330 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6335 (define_insn "*cbranchne_decr1"
6337 (if_then_else (match_operator 3 "equality_operator"
6338 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6340 (label_ref (match_operand 4 "" ""))
6342 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6343 (plus:SI (match_dup 2) (const_int -1)))
6344 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6349 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6351 VOIDmode, operands[2], const1_rtx);
6352 cond[1] = operands[4];
6354 if (which_alternative == 0)
6355 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6356 else if (which_alternative == 1)
6358 /* We must provide an alternative for a hi reg because reload
6359 cannot handle output reloads on a jump instruction, but we
6360 can't subtract into that. Fortunately a mov from lo to hi
6361 does not clobber the condition codes. */
6362 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6363 output_asm_insn (\"mov\\t%0, %1\", operands);
6367 /* Similarly, but the target is memory. */
6368 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6369 output_asm_insn (\"str\\t%1, %0\", operands);
6372 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6375 output_asm_insn (\"b%d0\\t%l1\", cond);
6378 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6379 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6381 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6382 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6386 [(set (attr "far_jump")
6388 (ior (and (eq (symbol_ref ("which_alternative"))
6390 (eq_attr "length" "8"))
6391 (eq_attr "length" "10"))
6392 (const_string "yes")
6393 (const_string "no")))
6394 (set_attr_alternative "length"
6398 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6399 (le (minus (match_dup 4) (pc)) (const_int 256)))
6402 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6403 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6408 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6409 (le (minus (match_dup 4) (pc)) (const_int 256)))
6412 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6413 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6418 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6419 (le (minus (match_dup 4) (pc)) (const_int 256)))
6422 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6423 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6428 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6429 (le (minus (match_dup 4) (pc)) (const_int 256)))
6432 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6433 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6438 (define_insn "*addsi3_cbranch"
6441 (match_operator 4 "comparison_operator"
6443 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6444 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6446 (label_ref (match_operand 5 "" ""))
6449 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6450 (plus:SI (match_dup 2) (match_dup 3)))
6451 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6453 && (GET_CODE (operands[4]) == EQ
6454 || GET_CODE (operands[4]) == NE
6455 || GET_CODE (operands[4]) == GE
6456 || GET_CODE (operands[4]) == LT)"
6462 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6463 cond[1] = operands[2];
6464 cond[2] = operands[3];
6466 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6467 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6469 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6471 if (which_alternative >= 3
6472 && which_alternative < 4)
6473 output_asm_insn (\"mov\\t%0, %1\", operands);
6474 else if (which_alternative >= 4)
6475 output_asm_insn (\"str\\t%1, %0\", operands);
6477 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6480 return \"b%d4\\t%l5\";
6482 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6484 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6488 [(set (attr "far_jump")
6490 (ior (and (lt (symbol_ref ("which_alternative"))
6492 (eq_attr "length" "8"))
6493 (eq_attr "length" "10"))
6494 (const_string "yes")
6495 (const_string "no")))
6496 (set (attr "length")
6498 (lt (symbol_ref ("which_alternative"))
6501 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6502 (le (minus (match_dup 5) (pc)) (const_int 256)))
6505 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6506 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6510 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6511 (le (minus (match_dup 5) (pc)) (const_int 256)))
6514 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6515 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6520 (define_insn "*addsi3_cbranch_scratch"
6523 (match_operator 3 "comparison_operator"
6525 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6526 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
6528 (label_ref (match_operand 4 "" ""))
6530 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6532 && (GET_CODE (operands[3]) == EQ
6533 || GET_CODE (operands[3]) == NE
6534 || GET_CODE (operands[3]) == GE
6535 || GET_CODE (operands[3]) == LT)"
6538 switch (which_alternative)
6541 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6544 output_asm_insn (\"cmn\t%1, %2\", operands);
6547 if (INTVAL (operands[2]) < 0)
6548 output_asm_insn (\"sub\t%0, %1, %2\", operands);
6550 output_asm_insn (\"add\t%0, %1, %2\", operands);
6553 if (INTVAL (operands[2]) < 0)
6554 output_asm_insn (\"sub\t%0, %0, %2\", operands);
6556 output_asm_insn (\"add\t%0, %0, %2\", operands);
6560 switch (get_attr_length (insn))
6563 return \"b%d3\\t%l4\";
6565 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6567 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6571 [(set (attr "far_jump")
6573 (eq_attr "length" "8")
6574 (const_string "yes")
6575 (const_string "no")))
6576 (set (attr "length")
6578 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6579 (le (minus (match_dup 4) (pc)) (const_int 256)))
6582 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6583 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6588 (define_insn "*subsi3_cbranch"
6591 (match_operator 4 "comparison_operator"
6593 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6594 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6596 (label_ref (match_operand 5 "" ""))
6598 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6599 (minus:SI (match_dup 2) (match_dup 3)))
6600 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6602 && (GET_CODE (operands[4]) == EQ
6603 || GET_CODE (operands[4]) == NE
6604 || GET_CODE (operands[4]) == GE
6605 || GET_CODE (operands[4]) == LT)"
6608 if (which_alternative == 0)
6609 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6610 else if (which_alternative == 1)
6612 /* We must provide an alternative for a hi reg because reload
6613 cannot handle output reloads on a jump instruction, but we
6614 can't subtract into that. Fortunately a mov from lo to hi
6615 does not clobber the condition codes. */
6616 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6617 output_asm_insn (\"mov\\t%0, %1\", operands);
6621 /* Similarly, but the target is memory. */
6622 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6623 output_asm_insn (\"str\\t%1, %0\", operands);
6626 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6629 return \"b%d4\\t%l5\";
6631 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6633 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6637 [(set (attr "far_jump")
6639 (ior (and (eq (symbol_ref ("which_alternative"))
6641 (eq_attr "length" "8"))
6642 (eq_attr "length" "10"))
6643 (const_string "yes")
6644 (const_string "no")))
6645 (set (attr "length")
6647 (eq (symbol_ref ("which_alternative"))
6650 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6651 (le (minus (match_dup 5) (pc)) (const_int 256)))
6654 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6655 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6659 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6660 (le (minus (match_dup 5) (pc)) (const_int 256)))
6663 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6664 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6669 (define_insn "*subsi3_cbranch_scratch"
6672 (match_operator 0 "arm_comparison_operator"
6673 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6674 (match_operand:SI 2 "nonmemory_operand" "l"))
6676 (label_ref (match_operand 3 "" ""))
6679 && (GET_CODE (operands[0]) == EQ
6680 || GET_CODE (operands[0]) == NE
6681 || GET_CODE (operands[0]) == GE
6682 || GET_CODE (operands[0]) == LT)"
6684 output_asm_insn (\"cmp\\t%1, %2\", operands);
6685 switch (get_attr_length (insn))
6687 case 4: return \"b%d0\\t%l3\";
6688 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6689 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6692 [(set (attr "far_jump")
6694 (eq_attr "length" "8")
6695 (const_string "yes")
6696 (const_string "no")))
6697 (set (attr "length")
6699 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6700 (le (minus (match_dup 3) (pc)) (const_int 256)))
6703 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6704 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6709 ;; Comparison and test insns
6711 (define_expand "cmpsi"
6712 [(match_operand:SI 0 "s_register_operand" "")
6713 (match_operand:SI 1 "arm_add_operand" "")]
6716 arm_compare_op0 = operands[0];
6717 arm_compare_op1 = operands[1];
6722 (define_expand "cmpsf"
6723 [(match_operand:SF 0 "s_register_operand" "")
6724 (match_operand:SF 1 "arm_float_compare_operand" "")]
6725 "TARGET_ARM && TARGET_HARD_FLOAT"
6727 arm_compare_op0 = operands[0];
6728 arm_compare_op1 = operands[1];
6733 (define_expand "cmpdf"
6734 [(match_operand:DF 0 "s_register_operand" "")
6735 (match_operand:DF 1 "arm_float_compare_operand" "")]
6736 "TARGET_ARM && TARGET_HARD_FLOAT"
6738 arm_compare_op0 = operands[0];
6739 arm_compare_op1 = operands[1];
6744 (define_insn "*arm_cmpsi_insn"
6745 [(set (reg:CC CC_REGNUM)
6746 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6747 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6752 [(set_attr "conds" "set")]
6755 (define_insn "*cmpsi_shiftsi"
6756 [(set (reg:CC CC_REGNUM)
6757 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6758 (match_operator:SI 3 "shift_operator"
6759 [(match_operand:SI 1 "s_register_operand" "r")
6760 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6763 [(set_attr "conds" "set")
6764 (set_attr "shift" "1")
6765 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6766 (const_string "alu_shift")
6767 (const_string "alu_shift_reg")))]
6770 (define_insn "*cmpsi_shiftsi_swp"
6771 [(set (reg:CC_SWP CC_REGNUM)
6772 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6773 [(match_operand:SI 1 "s_register_operand" "r")
6774 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6775 (match_operand:SI 0 "s_register_operand" "r")))]
6778 [(set_attr "conds" "set")
6779 (set_attr "shift" "1")
6780 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6781 (const_string "alu_shift")
6782 (const_string "alu_shift_reg")))]
6785 (define_insn "*cmpsi_negshiftsi_si"
6786 [(set (reg:CC_Z CC_REGNUM)
6788 (neg:SI (match_operator:SI 1 "shift_operator"
6789 [(match_operand:SI 2 "s_register_operand" "r")
6790 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6791 (match_operand:SI 0 "s_register_operand" "r")))]
6794 [(set_attr "conds" "set")
6795 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6796 (const_string "alu_shift")
6797 (const_string "alu_shift_reg")))]
6800 ;; Cirrus SF compare instruction
6801 (define_insn "*cirrus_cmpsf"
6802 [(set (reg:CCFP CC_REGNUM)
6803 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6804 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6805 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6806 "cfcmps%?\\tr15, %V0, %V1"
6807 [(set_attr "type" "mav_farith")
6808 (set_attr "cirrus" "compare")]
6811 ;; Cirrus DF compare instruction
6812 (define_insn "*cirrus_cmpdf"
6813 [(set (reg:CCFP CC_REGNUM)
6814 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6815 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6816 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6817 "cfcmpd%?\\tr15, %V0, %V1"
6818 [(set_attr "type" "mav_farith")
6819 (set_attr "cirrus" "compare")]
6822 ;; Cirrus DI compare instruction
6823 (define_expand "cmpdi"
6824 [(match_operand:DI 0 "cirrus_fp_register" "")
6825 (match_operand:DI 1 "cirrus_fp_register" "")]
6826 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6828 arm_compare_op0 = operands[0];
6829 arm_compare_op1 = operands[1];
6833 (define_insn "*cirrus_cmpdi"
6834 [(set (reg:CC CC_REGNUM)
6835 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6836 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6837 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6838 "cfcmp64%?\\tr15, %V0, %V1"
6839 [(set_attr "type" "mav_farith")
6840 (set_attr "cirrus" "compare")]
6843 ; This insn allows redundant compares to be removed by cse, nothing should
6844 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6845 ; is deleted later on. The match_dup will match the mode here, so that
6846 ; mode changes of the condition codes aren't lost by this even though we don't
6847 ; specify what they are.
6849 (define_insn "*deleted_compare"
6850 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6852 "\\t%@ deleted compare"
6853 [(set_attr "conds" "set")
6854 (set_attr "length" "0")]
6858 ;; Conditional branch insns
6860 (define_expand "beq"
6862 (if_then_else (eq (match_dup 1) (const_int 0))
6863 (label_ref (match_operand 0 "" ""))
6866 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6869 (define_expand "bne"
6871 (if_then_else (ne (match_dup 1) (const_int 0))
6872 (label_ref (match_operand 0 "" ""))
6875 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6878 (define_expand "bgt"
6880 (if_then_else (gt (match_dup 1) (const_int 0))
6881 (label_ref (match_operand 0 "" ""))
6884 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6887 (define_expand "ble"
6889 (if_then_else (le (match_dup 1) (const_int 0))
6890 (label_ref (match_operand 0 "" ""))
6893 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6896 (define_expand "bge"
6898 (if_then_else (ge (match_dup 1) (const_int 0))
6899 (label_ref (match_operand 0 "" ""))
6902 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6905 (define_expand "blt"
6907 (if_then_else (lt (match_dup 1) (const_int 0))
6908 (label_ref (match_operand 0 "" ""))
6911 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6914 (define_expand "bgtu"
6916 (if_then_else (gtu (match_dup 1) (const_int 0))
6917 (label_ref (match_operand 0 "" ""))
6920 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6923 (define_expand "bleu"
6925 (if_then_else (leu (match_dup 1) (const_int 0))
6926 (label_ref (match_operand 0 "" ""))
6929 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6932 (define_expand "bgeu"
6934 (if_then_else (geu (match_dup 1) (const_int 0))
6935 (label_ref (match_operand 0 "" ""))
6938 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6941 (define_expand "bltu"
6943 (if_then_else (ltu (match_dup 1) (const_int 0))
6944 (label_ref (match_operand 0 "" ""))
6947 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6950 (define_expand "bunordered"
6952 (if_then_else (unordered (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 (UNORDERED, arm_compare_op0,
6960 (define_expand "bordered"
6962 (if_then_else (ordered (match_dup 1) (const_int 0))
6963 (label_ref (match_operand 0 "" ""))
6965 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6966 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6970 (define_expand "bungt"
6972 (if_then_else (ungt (match_dup 1) (const_int 0))
6973 (label_ref (match_operand 0 "" ""))
6975 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6976 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
6979 (define_expand "bunlt"
6981 (if_then_else (unlt (match_dup 1) (const_int 0))
6982 (label_ref (match_operand 0 "" ""))
6984 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6985 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6988 (define_expand "bunge"
6990 (if_then_else (unge (match_dup 1) (const_int 0))
6991 (label_ref (match_operand 0 "" ""))
6993 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6994 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6997 (define_expand "bunle"
6999 (if_then_else (unle (match_dup 1) (const_int 0))
7000 (label_ref (match_operand 0 "" ""))
7002 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7003 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
7006 ;; The following two patterns need two branch instructions, since there is
7007 ;; no single instruction that will handle all cases.
7008 (define_expand "buneq"
7010 (if_then_else (uneq (match_dup 1) (const_int 0))
7011 (label_ref (match_operand 0 "" ""))
7013 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7014 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
7017 (define_expand "bltgt"
7019 (if_then_else (ltgt (match_dup 1) (const_int 0))
7020 (label_ref (match_operand 0 "" ""))
7022 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7023 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
7027 ;; Patterns to match conditional branch insns.
7030 ; Special pattern to match UNEQ.
7031 (define_insn "*arm_buneq"
7033 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7034 (label_ref (match_operand 0 "" ""))
7036 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7038 if (arm_ccfsm_state != 0)
7041 return \"bvs\\t%l0\;beq\\t%l0\";
7043 [(set_attr "conds" "jump_clob")
7044 (set_attr "length" "8")]
7047 ; Special pattern to match LTGT.
7048 (define_insn "*arm_bltgt"
7050 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7051 (label_ref (match_operand 0 "" ""))
7053 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7055 if (arm_ccfsm_state != 0)
7058 return \"bmi\\t%l0\;bgt\\t%l0\";
7060 [(set_attr "conds" "jump_clob")
7061 (set_attr "length" "8")]
7064 (define_insn "*arm_cond_branch"
7066 (if_then_else (match_operator 1 "arm_comparison_operator"
7067 [(match_operand 2 "cc_register" "") (const_int 0)])
7068 (label_ref (match_operand 0 "" ""))
7072 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7074 arm_ccfsm_state += 2;
7077 return \"b%d1\\t%l0\";
7079 [(set_attr "conds" "use")
7080 (set_attr "type" "branch")]
7083 ; Special pattern to match reversed UNEQ.
7084 (define_insn "*arm_buneq_reversed"
7086 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7088 (label_ref (match_operand 0 "" ""))))]
7089 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7091 if (arm_ccfsm_state != 0)
7094 return \"bmi\\t%l0\;bgt\\t%l0\";
7096 [(set_attr "conds" "jump_clob")
7097 (set_attr "length" "8")]
7100 ; Special pattern to match reversed LTGT.
7101 (define_insn "*arm_bltgt_reversed"
7103 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7105 (label_ref (match_operand 0 "" ""))))]
7106 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7108 if (arm_ccfsm_state != 0)
7111 return \"bvs\\t%l0\;beq\\t%l0\";
7113 [(set_attr "conds" "jump_clob")
7114 (set_attr "length" "8")]
7117 (define_insn "*arm_cond_branch_reversed"
7119 (if_then_else (match_operator 1 "arm_comparison_operator"
7120 [(match_operand 2 "cc_register" "") (const_int 0)])
7122 (label_ref (match_operand 0 "" ""))))]
7125 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7127 arm_ccfsm_state += 2;
7130 return \"b%D1\\t%l0\";
7132 [(set_attr "conds" "use")
7133 (set_attr "type" "branch")]
7140 (define_expand "seq"
7141 [(set (match_operand:SI 0 "s_register_operand" "")
7142 (eq:SI (match_dup 1) (const_int 0)))]
7144 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7147 (define_expand "sne"
7148 [(set (match_operand:SI 0 "s_register_operand" "")
7149 (ne:SI (match_dup 1) (const_int 0)))]
7151 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7154 (define_expand "sgt"
7155 [(set (match_operand:SI 0 "s_register_operand" "")
7156 (gt:SI (match_dup 1) (const_int 0)))]
7158 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7161 (define_expand "sle"
7162 [(set (match_operand:SI 0 "s_register_operand" "")
7163 (le:SI (match_dup 1) (const_int 0)))]
7165 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7168 (define_expand "sge"
7169 [(set (match_operand:SI 0 "s_register_operand" "")
7170 (ge:SI (match_dup 1) (const_int 0)))]
7172 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7175 (define_expand "slt"
7176 [(set (match_operand:SI 0 "s_register_operand" "")
7177 (lt:SI (match_dup 1) (const_int 0)))]
7179 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7182 (define_expand "sgtu"
7183 [(set (match_operand:SI 0 "s_register_operand" "")
7184 (gtu:SI (match_dup 1) (const_int 0)))]
7186 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7189 (define_expand "sleu"
7190 [(set (match_operand:SI 0 "s_register_operand" "")
7191 (leu:SI (match_dup 1) (const_int 0)))]
7193 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7196 (define_expand "sgeu"
7197 [(set (match_operand:SI 0 "s_register_operand" "")
7198 (geu:SI (match_dup 1) (const_int 0)))]
7200 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7203 (define_expand "sltu"
7204 [(set (match_operand:SI 0 "s_register_operand" "")
7205 (ltu:SI (match_dup 1) (const_int 0)))]
7207 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7210 (define_expand "sunordered"
7211 [(set (match_operand:SI 0 "s_register_operand" "")
7212 (unordered:SI (match_dup 1) (const_int 0)))]
7213 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7214 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7218 (define_expand "sordered"
7219 [(set (match_operand:SI 0 "s_register_operand" "")
7220 (ordered:SI (match_dup 1) (const_int 0)))]
7221 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7222 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7226 (define_expand "sungt"
7227 [(set (match_operand:SI 0 "s_register_operand" "")
7228 (ungt:SI (match_dup 1) (const_int 0)))]
7229 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7230 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7234 (define_expand "sunge"
7235 [(set (match_operand:SI 0 "s_register_operand" "")
7236 (unge:SI (match_dup 1) (const_int 0)))]
7237 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7238 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7242 (define_expand "sunlt"
7243 [(set (match_operand:SI 0 "s_register_operand" "")
7244 (unlt:SI (match_dup 1) (const_int 0)))]
7245 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7246 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7250 (define_expand "sunle"
7251 [(set (match_operand:SI 0 "s_register_operand" "")
7252 (unle:SI (match_dup 1) (const_int 0)))]
7253 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7254 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7258 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7259 ;;; simple ARM instructions.
7261 ; (define_expand "suneq"
7262 ; [(set (match_operand:SI 0 "s_register_operand" "")
7263 ; (uneq:SI (match_dup 1) (const_int 0)))]
7264 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7268 ; (define_expand "sltgt"
7269 ; [(set (match_operand:SI 0 "s_register_operand" "")
7270 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7271 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7275 (define_insn "*mov_scc"
7276 [(set (match_operand:SI 0 "s_register_operand" "=r")
7277 (match_operator:SI 1 "arm_comparison_operator"
7278 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7280 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7281 [(set_attr "conds" "use")
7282 (set_attr "length" "8")]
7285 (define_insn "*mov_negscc"
7286 [(set (match_operand:SI 0 "s_register_operand" "=r")
7287 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7288 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7290 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7291 [(set_attr "conds" "use")
7292 (set_attr "length" "8")]
7295 (define_insn "*mov_notscc"
7296 [(set (match_operand:SI 0 "s_register_operand" "=r")
7297 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7298 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7300 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7301 [(set_attr "conds" "use")
7302 (set_attr "length" "8")]
7306 ;; Conditional move insns
7308 (define_expand "movsicc"
7309 [(set (match_operand:SI 0 "s_register_operand" "")
7310 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7311 (match_operand:SI 2 "arm_not_operand" "")
7312 (match_operand:SI 3 "arm_not_operand" "")))]
7316 enum rtx_code code = GET_CODE (operands[1]);
7319 if (code == UNEQ || code == LTGT)
7322 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7323 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7327 (define_expand "movsfcc"
7328 [(set (match_operand:SF 0 "s_register_operand" "")
7329 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7330 (match_operand:SF 2 "s_register_operand" "")
7331 (match_operand:SF 3 "nonmemory_operand" "")))]
7335 enum rtx_code code = GET_CODE (operands[1]);
7338 if (code == UNEQ || code == LTGT)
7341 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7342 Otherwise, ensure it is a valid FP add operand */
7343 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7344 || (!arm_float_add_operand (operands[3], SFmode)))
7345 operands[3] = force_reg (SFmode, operands[3]);
7347 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7348 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7352 (define_expand "movdfcc"
7353 [(set (match_operand:DF 0 "s_register_operand" "")
7354 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7355 (match_operand:DF 2 "s_register_operand" "")
7356 (match_operand:DF 3 "arm_float_add_operand" "")))]
7357 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7360 enum rtx_code code = GET_CODE (operands[1]);
7363 if (code == UNEQ || code == LTGT)
7366 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7367 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7371 (define_insn "*movsicc_insn"
7372 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7374 (match_operator 3 "arm_comparison_operator"
7375 [(match_operand 4 "cc_register" "") (const_int 0)])
7376 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7377 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7384 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7385 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7386 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7387 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7388 [(set_attr "length" "4,4,4,4,8,8,8,8")
7389 (set_attr "conds" "use")]
7392 (define_insn "*movsfcc_soft_insn"
7393 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7394 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7395 [(match_operand 4 "cc_register" "") (const_int 0)])
7396 (match_operand:SF 1 "s_register_operand" "0,r")
7397 (match_operand:SF 2 "s_register_operand" "r,0")))]
7398 "TARGET_ARM && TARGET_SOFT_FLOAT"
7402 [(set_attr "conds" "use")]
7406 ;; Jump and linkage insns
7408 (define_expand "jump"
7410 (label_ref (match_operand 0 "" "")))]
7415 (define_insn "*arm_jump"
7417 (label_ref (match_operand 0 "" "")))]
7421 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7423 arm_ccfsm_state += 2;
7426 return \"b%?\\t%l0\";
7429 [(set_attr "predicable" "yes")]
7432 (define_insn "*thumb_jump"
7434 (label_ref (match_operand 0 "" "")))]
7437 if (get_attr_length (insn) == 2)
7439 return \"bl\\t%l0\\t%@ far jump\";
7441 [(set (attr "far_jump")
7443 (eq_attr "length" "4")
7444 (const_string "yes")
7445 (const_string "no")))
7446 (set (attr "length")
7448 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7449 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7454 (define_expand "call"
7455 [(parallel [(call (match_operand 0 "memory_operand" "")
7456 (match_operand 1 "general_operand" ""))
7457 (use (match_operand 2 "" ""))
7458 (clobber (reg:SI LR_REGNUM))])]
7464 /* In an untyped call, we can get NULL for operand 2. */
7465 if (operands[2] == NULL_RTX)
7466 operands[2] = const0_rtx;
7468 /* This is to decide if we should generate indirect calls by loading the
7469 32 bit address of the callee into a register before performing the
7470 branch and link. operand[2] encodes the long_call/short_call
7471 attribute of the function being called. This attribute is set whenever
7472 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7473 is used, and the short_call attribute can also be set if function is
7474 declared as static or if it has already been defined in the current
7475 compilation unit. See arm.c and arm.h for info about this. The third
7476 parameter to arm_is_longcall_p is used to tell it which pattern
7478 callee = XEXP (operands[0], 0);
7480 if (GET_CODE (callee) != REG
7481 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7482 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7486 (define_insn "*call_reg_armv5"
7487 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7488 (match_operand 1 "" ""))
7489 (use (match_operand 2 "" ""))
7490 (clobber (reg:SI LR_REGNUM))]
7491 "TARGET_ARM && arm_arch5"
7493 [(set_attr "type" "call")]
7496 (define_insn "*call_reg_arm"
7497 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7498 (match_operand 1 "" ""))
7499 (use (match_operand 2 "" ""))
7500 (clobber (reg:SI LR_REGNUM))]
7501 "TARGET_ARM && !arm_arch5"
7503 return output_call (operands);
7505 ;; length is worst case, normally it is only two
7506 [(set_attr "length" "12")
7507 (set_attr "type" "call")]
7510 (define_insn "*call_mem"
7511 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7512 (match_operand 1 "" ""))
7513 (use (match_operand 2 "" ""))
7514 (clobber (reg:SI LR_REGNUM))]
7517 return output_call_mem (operands);
7519 [(set_attr "length" "12")
7520 (set_attr "type" "call")]
7523 (define_insn "*call_reg_thumb_v5"
7524 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7525 (match_operand 1 "" ""))
7526 (use (match_operand 2 "" ""))
7527 (clobber (reg:SI LR_REGNUM))]
7528 "TARGET_THUMB && arm_arch5"
7530 [(set_attr "length" "2")
7531 (set_attr "type" "call")]
7534 (define_insn "*call_reg_thumb"
7535 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7536 (match_operand 1 "" ""))
7537 (use (match_operand 2 "" ""))
7538 (clobber (reg:SI LR_REGNUM))]
7539 "TARGET_THUMB && !arm_arch5"
7542 if (!TARGET_CALLER_INTERWORKING)
7543 return thumb_call_via_reg (operands[0]);
7544 else if (operands[1] == const0_rtx)
7545 return \"bl\\t%__interwork_call_via_%0\";
7546 else if (frame_pointer_needed)
7547 return \"bl\\t%__interwork_r7_call_via_%0\";
7549 return \"bl\\t%__interwork_r11_call_via_%0\";
7551 [(set_attr "type" "call")]
7554 (define_expand "call_value"
7555 [(parallel [(set (match_operand 0 "" "")
7556 (call (match_operand 1 "memory_operand" "")
7557 (match_operand 2 "general_operand" "")))
7558 (use (match_operand 3 "" ""))
7559 (clobber (reg:SI LR_REGNUM))])]
7563 rtx callee = XEXP (operands[1], 0);
7565 /* In an untyped call, we can get NULL for operand 2. */
7566 if (operands[3] == 0)
7567 operands[3] = const0_rtx;
7569 /* See the comment in define_expand \"call\". */
7570 if (GET_CODE (callee) != REG
7571 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7572 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7576 (define_insn "*call_value_reg_armv5"
7577 [(set (match_operand 0 "" "")
7578 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7579 (match_operand 2 "" "")))
7580 (use (match_operand 3 "" ""))
7581 (clobber (reg:SI LR_REGNUM))]
7582 "TARGET_ARM && arm_arch5"
7584 [(set_attr "type" "call")]
7587 (define_insn "*call_value_reg_arm"
7588 [(set (match_operand 0 "" "")
7589 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7590 (match_operand 2 "" "")))
7591 (use (match_operand 3 "" ""))
7592 (clobber (reg:SI LR_REGNUM))]
7593 "TARGET_ARM && !arm_arch5"
7595 return output_call (&operands[1]);
7597 [(set_attr "length" "12")
7598 (set_attr "type" "call")]
7601 (define_insn "*call_value_mem"
7602 [(set (match_operand 0 "" "")
7603 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7604 (match_operand 2 "" "")))
7605 (use (match_operand 3 "" ""))
7606 (clobber (reg:SI LR_REGNUM))]
7607 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7609 return output_call_mem (&operands[1]);
7611 [(set_attr "length" "12")
7612 (set_attr "type" "call")]
7615 (define_insn "*call_value_reg_thumb_v5"
7616 [(set (match_operand 0 "" "")
7617 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7618 (match_operand 2 "" "")))
7619 (use (match_operand 3 "" ""))
7620 (clobber (reg:SI LR_REGNUM))]
7621 "TARGET_THUMB && arm_arch5"
7623 [(set_attr "length" "2")
7624 (set_attr "type" "call")]
7627 (define_insn "*call_value_reg_thumb"
7628 [(set (match_operand 0 "" "")
7629 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7630 (match_operand 2 "" "")))
7631 (use (match_operand 3 "" ""))
7632 (clobber (reg:SI LR_REGNUM))]
7633 "TARGET_THUMB && !arm_arch5"
7636 if (!TARGET_CALLER_INTERWORKING)
7637 return thumb_call_via_reg (operands[1]);
7638 else if (operands[2] == const0_rtx)
7639 return \"bl\\t%__interwork_call_via_%1\";
7640 else if (frame_pointer_needed)
7641 return \"bl\\t%__interwork_r7_call_via_%1\";
7643 return \"bl\\t%__interwork_r11_call_via_%1\";
7645 [(set_attr "type" "call")]
7648 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7649 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7651 (define_insn "*call_symbol"
7652 [(call (mem:SI (match_operand:SI 0 "" ""))
7653 (match_operand 1 "" ""))
7654 (use (match_operand 2 "" ""))
7655 (clobber (reg:SI LR_REGNUM))]
7657 && (GET_CODE (operands[0]) == SYMBOL_REF)
7658 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7661 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7663 [(set_attr "type" "call")]
7666 (define_insn "*call_value_symbol"
7667 [(set (match_operand 0 "" "")
7668 (call (mem:SI (match_operand:SI 1 "" ""))
7669 (match_operand:SI 2 "" "")))
7670 (use (match_operand 3 "" ""))
7671 (clobber (reg:SI LR_REGNUM))]
7673 && (GET_CODE (operands[1]) == SYMBOL_REF)
7674 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7677 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7679 [(set_attr "type" "call")]
7682 (define_insn "*call_insn"
7683 [(call (mem:SI (match_operand:SI 0 "" ""))
7684 (match_operand:SI 1 "" ""))
7685 (use (match_operand 2 "" ""))
7686 (clobber (reg:SI LR_REGNUM))]
7688 && GET_CODE (operands[0]) == SYMBOL_REF
7689 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7691 [(set_attr "length" "4")
7692 (set_attr "type" "call")]
7695 (define_insn "*call_value_insn"
7696 [(set (match_operand 0 "" "")
7697 (call (mem:SI (match_operand 1 "" ""))
7698 (match_operand 2 "" "")))
7699 (use (match_operand 3 "" ""))
7700 (clobber (reg:SI LR_REGNUM))]
7702 && GET_CODE (operands[1]) == SYMBOL_REF
7703 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7705 [(set_attr "length" "4")
7706 (set_attr "type" "call")]
7709 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7710 (define_expand "sibcall"
7711 [(parallel [(call (match_operand 0 "memory_operand" "")
7712 (match_operand 1 "general_operand" ""))
7714 (use (match_operand 2 "" ""))])]
7718 if (operands[2] == NULL_RTX)
7719 operands[2] = const0_rtx;
7723 (define_expand "sibcall_value"
7724 [(parallel [(set (match_operand 0 "" "")
7725 (call (match_operand 1 "memory_operand" "")
7726 (match_operand 2 "general_operand" "")))
7728 (use (match_operand 3 "" ""))])]
7732 if (operands[3] == NULL_RTX)
7733 operands[3] = const0_rtx;
7737 (define_insn "*sibcall_insn"
7738 [(call (mem:SI (match_operand:SI 0 "" "X"))
7739 (match_operand 1 "" ""))
7741 (use (match_operand 2 "" ""))]
7742 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7744 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7746 [(set_attr "type" "call")]
7749 (define_insn "*sibcall_value_insn"
7750 [(set (match_operand 0 "" "")
7751 (call (mem:SI (match_operand:SI 1 "" "X"))
7752 (match_operand 2 "" "")))
7754 (use (match_operand 3 "" ""))]
7755 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7757 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7759 [(set_attr "type" "call")]
7762 ;; Often the return insn will be the same as loading from memory, so set attr
7763 (define_insn "return"
7765 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7768 if (arm_ccfsm_state == 2)
7770 arm_ccfsm_state += 2;
7773 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7775 [(set_attr "type" "load1")
7776 (set_attr "length" "12")
7777 (set_attr "predicable" "yes")]
7780 (define_insn "*cond_return"
7782 (if_then_else (match_operator 0 "arm_comparison_operator"
7783 [(match_operand 1 "cc_register" "") (const_int 0)])
7786 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7789 if (arm_ccfsm_state == 2)
7791 arm_ccfsm_state += 2;
7794 return output_return_instruction (operands[0], TRUE, FALSE);
7796 [(set_attr "conds" "use")
7797 (set_attr "length" "12")
7798 (set_attr "type" "load1")]
7801 (define_insn "*cond_return_inverted"
7803 (if_then_else (match_operator 0 "arm_comparison_operator"
7804 [(match_operand 1 "cc_register" "") (const_int 0)])
7807 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7810 if (arm_ccfsm_state == 2)
7812 arm_ccfsm_state += 2;
7815 return output_return_instruction (operands[0], TRUE, TRUE);
7817 [(set_attr "conds" "use")
7818 (set_attr "length" "12")
7819 (set_attr "type" "load1")]
7822 ;; Generate a sequence of instructions to determine if the processor is
7823 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7826 (define_expand "return_addr_mask"
7828 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7830 (set (match_operand:SI 0 "s_register_operand" "")
7831 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7833 (const_int 67108860)))] ; 0x03fffffc
7836 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7839 (define_insn "*check_arch2"
7840 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7841 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7844 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7845 [(set_attr "length" "8")
7846 (set_attr "conds" "set")]
7849 ;; Call subroutine returning any type.
7851 (define_expand "untyped_call"
7852 [(parallel [(call (match_operand 0 "" "")
7854 (match_operand 1 "" "")
7855 (match_operand 2 "" "")])]
7860 rtx par = gen_rtx_PARALLEL (VOIDmode,
7861 rtvec_alloc (XVECLEN (operands[2], 0)));
7862 rtx addr = gen_reg_rtx (Pmode);
7866 emit_move_insn (addr, XEXP (operands[1], 0));
7867 mem = change_address (operands[1], BLKmode, addr);
7869 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7871 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7873 /* Default code only uses r0 as a return value, but we could
7874 be using anything up to 4 registers. */
7875 if (REGNO (src) == R0_REGNUM)
7876 src = gen_rtx_REG (TImode, R0_REGNUM);
7878 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7880 size += GET_MODE_SIZE (GET_MODE (src));
7883 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7888 for (i = 0; i < XVECLEN (par, 0); i++)
7890 HOST_WIDE_INT offset = 0;
7891 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
7894 emit_move_insn (addr, plus_constant (addr, size));
7896 mem = change_address (mem, GET_MODE (reg), NULL);
7897 if (REGNO (reg) == R0_REGNUM)
7899 /* On thumb we have to use a write-back instruction. */
7900 emit_insn (arm_gen_store_multiple (R0_REGNUM, 4, addr, TRUE,
7901 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
7902 size = TARGET_ARM ? 16 : 0;
7906 emit_move_insn (mem, reg);
7907 size = GET_MODE_SIZE (GET_MODE (reg));
7911 /* The optimizer does not know that the call sets the function value
7912 registers we stored in the result block. We avoid problems by
7913 claiming that all hard registers are used and clobbered at this
7915 emit_insn (gen_blockage ());
7921 (define_expand "untyped_return"
7922 [(match_operand:BLK 0 "memory_operand" "")
7923 (match_operand 1 "" "")]
7928 rtx addr = gen_reg_rtx (Pmode);
7932 emit_move_insn (addr, XEXP (operands[0], 0));
7933 mem = change_address (operands[0], BLKmode, addr);
7935 for (i = 0; i < XVECLEN (operands[1], 0); i++)
7937 HOST_WIDE_INT offset = 0;
7938 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
7941 emit_move_insn (addr, plus_constant (addr, size));
7943 mem = change_address (mem, GET_MODE (reg), NULL);
7944 if (REGNO (reg) == R0_REGNUM)
7946 /* On thumb we have to use a write-back instruction. */
7947 emit_insn (arm_gen_load_multiple (R0_REGNUM, 4, addr, TRUE,
7948 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
7949 size = TARGET_ARM ? 16 : 0;
7953 emit_move_insn (reg, mem);
7954 size = GET_MODE_SIZE (GET_MODE (reg));
7958 /* Emit USE insns before the return. */
7959 for (i = 0; i < XVECLEN (operands[1], 0); i++)
7960 emit_insn (gen_rtx_USE (VOIDmode,
7961 SET_DEST (XVECEXP (operands[1], 0, i))));
7963 /* Construct the return. */
7964 expand_naked_return ();
7970 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7971 ;; all of memory. This blocks insns from being moved across this point.
7973 (define_insn "blockage"
7974 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7977 [(set_attr "length" "0")
7978 (set_attr "type" "block")]
7981 (define_expand "casesi"
7982 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7983 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7984 (match_operand:SI 2 "const_int_operand" "") ; total range
7985 (match_operand:SI 3 "" "") ; table label
7986 (match_operand:SI 4 "" "")] ; Out of range label
7991 if (operands[1] != const0_rtx)
7993 reg = gen_reg_rtx (SImode);
7995 emit_insn (gen_addsi3 (reg, operands[0],
7996 GEN_INT (-INTVAL (operands[1]))));
8000 if (!const_ok_for_arm (INTVAL (operands[2])))
8001 operands[2] = force_reg (SImode, operands[2]);
8003 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
8009 ;; The USE in this pattern is needed to tell flow analysis that this is
8010 ;; a CASESI insn. It has no other purpose.
8011 (define_insn "casesi_internal"
8012 [(parallel [(set (pc)
8014 (leu (match_operand:SI 0 "s_register_operand" "r")
8015 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8016 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8017 (label_ref (match_operand 2 "" ""))))
8018 (label_ref (match_operand 3 "" ""))))
8019 (clobber (reg:CC CC_REGNUM))
8020 (use (label_ref (match_dup 2)))])]
8024 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8025 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8027 [(set_attr "conds" "clob")
8028 (set_attr "length" "12")]
8031 (define_expand "indirect_jump"
8033 (match_operand:SI 0 "s_register_operand" ""))]
8038 ;; NB Never uses BX.
8039 (define_insn "*arm_indirect_jump"
8041 (match_operand:SI 0 "s_register_operand" "r"))]
8043 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8044 [(set_attr "predicable" "yes")]
8047 (define_insn "*load_indirect_jump"
8049 (match_operand:SI 0 "memory_operand" "m"))]
8051 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8052 [(set_attr "type" "load1")
8053 (set_attr "pool_range" "4096")
8054 (set_attr "neg_pool_range" "4084")
8055 (set_attr "predicable" "yes")]
8058 ;; NB Never uses BX.
8059 (define_insn "*thumb_indirect_jump"
8061 (match_operand:SI 0 "register_operand" "l*r"))]
8064 [(set_attr "conds" "clob")
8065 (set_attr "length" "2")]
8076 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8077 return \"mov\\tr8, r8\";
8079 [(set (attr "length")
8080 (if_then_else (eq_attr "is_thumb" "yes")
8086 ;; Patterns to allow combination of arithmetic, cond code and shifts
8088 (define_insn "*arith_shiftsi"
8089 [(set (match_operand:SI 0 "s_register_operand" "=r")
8090 (match_operator:SI 1 "shiftable_operator"
8091 [(match_operator:SI 3 "shift_operator"
8092 [(match_operand:SI 4 "s_register_operand" "r")
8093 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8094 (match_operand:SI 2 "s_register_operand" "r")]))]
8096 "%i1%?\\t%0, %2, %4%S3"
8097 [(set_attr "predicable" "yes")
8098 (set_attr "shift" "4")
8099 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8100 (const_string "alu_shift")
8101 (const_string "alu_shift_reg")))]
8105 [(set (match_operand:SI 0 "s_register_operand" "")
8106 (match_operator:SI 1 "shiftable_operator"
8107 [(match_operator:SI 2 "shiftable_operator"
8108 [(match_operator:SI 3 "shift_operator"
8109 [(match_operand:SI 4 "s_register_operand" "")
8110 (match_operand:SI 5 "reg_or_int_operand" "")])
8111 (match_operand:SI 6 "s_register_operand" "")])
8112 (match_operand:SI 7 "arm_rhs_operand" "")]))
8113 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8116 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8119 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8122 (define_insn "*arith_shiftsi_compare0"
8123 [(set (reg:CC_NOOV CC_REGNUM)
8124 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8125 [(match_operator:SI 3 "shift_operator"
8126 [(match_operand:SI 4 "s_register_operand" "r")
8127 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8128 (match_operand:SI 2 "s_register_operand" "r")])
8130 (set (match_operand:SI 0 "s_register_operand" "=r")
8131 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8134 "%i1%?s\\t%0, %2, %4%S3"
8135 [(set_attr "conds" "set")
8136 (set_attr "shift" "4")
8137 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8138 (const_string "alu_shift")
8139 (const_string "alu_shift_reg")))]
8142 (define_insn "*arith_shiftsi_compare0_scratch"
8143 [(set (reg:CC_NOOV CC_REGNUM)
8144 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8145 [(match_operator:SI 3 "shift_operator"
8146 [(match_operand:SI 4 "s_register_operand" "r")
8147 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8148 (match_operand:SI 2 "s_register_operand" "r")])
8150 (clobber (match_scratch:SI 0 "=r"))]
8152 "%i1%?s\\t%0, %2, %4%S3"
8153 [(set_attr "conds" "set")
8154 (set_attr "shift" "4")
8155 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8156 (const_string "alu_shift")
8157 (const_string "alu_shift_reg")))]
8160 (define_insn "*sub_shiftsi"
8161 [(set (match_operand:SI 0 "s_register_operand" "=r")
8162 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8163 (match_operator:SI 2 "shift_operator"
8164 [(match_operand:SI 3 "s_register_operand" "r")
8165 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
8167 "sub%?\\t%0, %1, %3%S2"
8168 [(set_attr "predicable" "yes")
8169 (set_attr "shift" "3")
8170 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8171 (const_string "alu_shift")
8172 (const_string "alu_shift_reg")))]
8175 (define_insn "*sub_shiftsi_compare0"
8176 [(set (reg:CC_NOOV CC_REGNUM)
8178 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8179 (match_operator:SI 2 "shift_operator"
8180 [(match_operand:SI 3 "s_register_operand" "r")
8181 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8183 (set (match_operand:SI 0 "s_register_operand" "=r")
8184 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
8187 "sub%?s\\t%0, %1, %3%S2"
8188 [(set_attr "conds" "set")
8189 (set_attr "shift" "3")
8190 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8191 (const_string "alu_shift")
8192 (const_string "alu_shift_reg")))]
8195 (define_insn "*sub_shiftsi_compare0_scratch"
8196 [(set (reg:CC_NOOV CC_REGNUM)
8198 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8199 (match_operator:SI 2 "shift_operator"
8200 [(match_operand:SI 3 "s_register_operand" "r")
8201 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8203 (clobber (match_scratch:SI 0 "=r"))]
8205 "sub%?s\\t%0, %1, %3%S2"
8206 [(set_attr "conds" "set")
8207 (set_attr "shift" "3")
8208 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8209 (const_string "alu_shift")
8210 (const_string "alu_shift_reg")))]
8215 (define_insn "*and_scc"
8216 [(set (match_operand:SI 0 "s_register_operand" "=r")
8217 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8218 [(match_operand 3 "cc_register" "") (const_int 0)])
8219 (match_operand:SI 2 "s_register_operand" "r")))]
8221 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8222 [(set_attr "conds" "use")
8223 (set_attr "length" "8")]
8226 (define_insn "*ior_scc"
8227 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8228 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8229 [(match_operand 3 "cc_register" "") (const_int 0)])
8230 (match_operand:SI 1 "s_register_operand" "0,?r")))]
8234 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8235 [(set_attr "conds" "use")
8236 (set_attr "length" "4,8")]
8239 (define_insn "*compare_scc"
8240 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8241 (match_operator:SI 1 "arm_comparison_operator"
8242 [(match_operand:SI 2 "s_register_operand" "r,r")
8243 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8244 (clobber (reg:CC CC_REGNUM))]
8247 if (operands[3] == const0_rtx)
8249 if (GET_CODE (operands[1]) == LT)
8250 return \"mov\\t%0, %2, lsr #31\";
8252 if (GET_CODE (operands[1]) == GE)
8253 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8255 if (GET_CODE (operands[1]) == EQ)
8256 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8259 if (GET_CODE (operands[1]) == NE)
8261 if (which_alternative == 1)
8262 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8263 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8265 if (which_alternative == 1)
8266 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8268 output_asm_insn (\"cmp\\t%2, %3\", operands);
8269 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8271 [(set_attr "conds" "clob")
8272 (set_attr "length" "12")]
8275 (define_insn "*cond_move"
8276 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8277 (if_then_else:SI (match_operator 3 "equality_operator"
8278 [(match_operator 4 "arm_comparison_operator"
8279 [(match_operand 5 "cc_register" "") (const_int 0)])
8281 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8282 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8285 if (GET_CODE (operands[3]) == NE)
8287 if (which_alternative != 1)
8288 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8289 if (which_alternative != 0)
8290 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8293 if (which_alternative != 0)
8294 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8295 if (which_alternative != 1)
8296 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8299 [(set_attr "conds" "use")
8300 (set_attr "length" "4,4,8")]
8303 (define_insn "*cond_arith"
8304 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8305 (match_operator:SI 5 "shiftable_operator"
8306 [(match_operator:SI 4 "arm_comparison_operator"
8307 [(match_operand:SI 2 "s_register_operand" "r,r")
8308 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8309 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8310 (clobber (reg:CC CC_REGNUM))]
8313 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8314 return \"%i5\\t%0, %1, %2, lsr #31\";
8316 output_asm_insn (\"cmp\\t%2, %3\", operands);
8317 if (GET_CODE (operands[5]) == AND)
8318 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8319 else if (GET_CODE (operands[5]) == MINUS)
8320 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8321 else if (which_alternative != 0)
8322 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8323 return \"%i5%d4\\t%0, %1, #1\";
8325 [(set_attr "conds" "clob")
8326 (set_attr "length" "12")]
8329 (define_insn "*cond_sub"
8330 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8331 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8332 (match_operator:SI 4 "arm_comparison_operator"
8333 [(match_operand:SI 2 "s_register_operand" "r,r")
8334 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8335 (clobber (reg:CC CC_REGNUM))]
8338 output_asm_insn (\"cmp\\t%2, %3\", operands);
8339 if (which_alternative != 0)
8340 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8341 return \"sub%d4\\t%0, %1, #1\";
8343 [(set_attr "conds" "clob")
8344 (set_attr "length" "8,12")]
8347 (define_insn "*cmp_ite0"
8348 [(set (match_operand 6 "dominant_cc_register" "")
8351 (match_operator 4 "arm_comparison_operator"
8352 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8353 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8354 (match_operator:SI 5 "arm_comparison_operator"
8355 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8356 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8362 static const char * const opcodes[4][2] =
8364 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8365 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8366 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8367 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8368 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8369 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8370 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8371 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8374 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8376 return opcodes[which_alternative][swap];
8378 [(set_attr "conds" "set")
8379 (set_attr "length" "8")]
8382 (define_insn "*cmp_ite1"
8383 [(set (match_operand 6 "dominant_cc_register" "")
8386 (match_operator 4 "arm_comparison_operator"
8387 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8388 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8389 (match_operator:SI 5 "arm_comparison_operator"
8390 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8391 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8397 static const char * const opcodes[4][2] =
8399 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8400 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8401 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8402 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8403 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8404 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8405 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8406 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8409 comparison_dominates_p (GET_CODE (operands[5]),
8410 reverse_condition (GET_CODE (operands[4])));
8412 return opcodes[which_alternative][swap];
8414 [(set_attr "conds" "set")
8415 (set_attr "length" "8")]
8418 (define_insn "*cmp_and"
8419 [(set (match_operand 6 "dominant_cc_register" "")
8422 (match_operator 4 "arm_comparison_operator"
8423 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8424 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8425 (match_operator:SI 5 "arm_comparison_operator"
8426 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8427 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8432 static const char *const opcodes[4][2] =
8434 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8435 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8436 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8437 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8438 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8439 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8440 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8441 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8444 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8446 return opcodes[which_alternative][swap];
8448 [(set_attr "conds" "set")
8449 (set_attr "predicable" "no")
8450 (set_attr "length" "8")]
8453 (define_insn "*cmp_ior"
8454 [(set (match_operand 6 "dominant_cc_register" "")
8457 (match_operator 4 "arm_comparison_operator"
8458 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8459 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8460 (match_operator:SI 5 "arm_comparison_operator"
8461 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8462 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8467 static const char *const opcodes[4][2] =
8469 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8470 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8471 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8472 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8473 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8474 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8475 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8476 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8479 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8481 return opcodes[which_alternative][swap];
8484 [(set_attr "conds" "set")
8485 (set_attr "length" "8")]
8488 (define_insn_and_split "*ior_scc_scc"
8489 [(set (match_operand:SI 0 "s_register_operand" "=r")
8490 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8491 [(match_operand:SI 1 "s_register_operand" "r")
8492 (match_operand:SI 2 "arm_add_operand" "rIL")])
8493 (match_operator:SI 6 "arm_comparison_operator"
8494 [(match_operand:SI 4 "s_register_operand" "r")
8495 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8496 (clobber (reg:CC CC_REGNUM))]
8498 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8501 "TARGET_ARM && reload_completed"
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 "*ior_scc_scc_cmp"
8519 [(set (match_operand 0 "dominant_cc_register" "")
8520 (compare (ior: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 (ior: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 (define_insn_and_split "*and_scc_scc"
8545 [(set (match_operand:SI 0 "s_register_operand" "=r")
8546 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8547 [(match_operand:SI 1 "s_register_operand" "r")
8548 (match_operand:SI 2 "arm_add_operand" "rIL")])
8549 (match_operator:SI 6 "arm_comparison_operator"
8550 [(match_operand:SI 4 "s_register_operand" "r")
8551 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8552 (clobber (reg:CC CC_REGNUM))]
8554 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8557 "TARGET_ARM && reload_completed
8558 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8563 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8564 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8566 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8568 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8571 [(set_attr "conds" "clob")
8572 (set_attr "length" "16")])
8574 ; If the above pattern is followed by a CMP insn, then the compare is
8575 ; redundant, since we can rework the conditional instruction that follows.
8576 (define_insn_and_split "*and_scc_scc_cmp"
8577 [(set (match_operand 0 "dominant_cc_register" "")
8578 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8579 [(match_operand:SI 1 "s_register_operand" "r")
8580 (match_operand:SI 2 "arm_add_operand" "rIL")])
8581 (match_operator:SI 6 "arm_comparison_operator"
8582 [(match_operand:SI 4 "s_register_operand" "r")
8583 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8585 (set (match_operand:SI 7 "s_register_operand" "=r")
8586 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8587 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8590 "TARGET_ARM && reload_completed"
8594 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8595 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8597 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8599 [(set_attr "conds" "set")
8600 (set_attr "length" "16")])
8602 ;; If there is no dominance in the comparison, then we can still save an
8603 ;; instruction in the AND case, since we can know that the second compare
8604 ;; need only zero the value if false (if true, then the value is already
8606 (define_insn_and_split "*and_scc_scc_nodom"
8607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8608 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8609 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8610 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8611 (match_operator:SI 6 "arm_comparison_operator"
8612 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8613 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8614 (clobber (reg:CC CC_REGNUM))]
8616 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8619 "TARGET_ARM && reload_completed"
8620 [(parallel [(set (match_dup 0)
8621 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8622 (clobber (reg:CC CC_REGNUM))])
8623 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8625 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8628 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8629 operands[4], operands[5]),
8631 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8633 [(set_attr "conds" "clob")
8634 (set_attr "length" "20")])
8637 [(set (reg:CC_NOOV CC_REGNUM)
8638 (compare:CC_NOOV (ior:SI
8639 (and:SI (match_operand:SI 0 "s_register_operand" "")
8641 (match_operator:SI 1 "comparison_operator"
8642 [(match_operand:SI 2 "s_register_operand" "")
8643 (match_operand:SI 3 "arm_add_operand" "")]))
8645 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8648 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8650 (set (reg:CC_NOOV CC_REGNUM)
8651 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8656 [(set (reg:CC_NOOV CC_REGNUM)
8657 (compare:CC_NOOV (ior:SI
8658 (match_operator:SI 1 "comparison_operator"
8659 [(match_operand:SI 2 "s_register_operand" "")
8660 (match_operand:SI 3 "arm_add_operand" "")])
8661 (and:SI (match_operand:SI 0 "s_register_operand" "")
8664 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8667 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8669 (set (reg:CC_NOOV CC_REGNUM)
8670 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8674 (define_insn "*negscc"
8675 [(set (match_operand:SI 0 "s_register_operand" "=r")
8676 (neg:SI (match_operator 3 "arm_comparison_operator"
8677 [(match_operand:SI 1 "s_register_operand" "r")
8678 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8679 (clobber (reg:CC CC_REGNUM))]
8682 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8683 return \"mov\\t%0, %1, asr #31\";
8685 if (GET_CODE (operands[3]) == NE)
8686 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8688 if (GET_CODE (operands[3]) == GT)
8689 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8691 output_asm_insn (\"cmp\\t%1, %2\", operands);
8692 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8693 return \"mvn%d3\\t%0, #0\";
8695 [(set_attr "conds" "clob")
8696 (set_attr "length" "12")]
8699 (define_insn "movcond"
8700 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8702 (match_operator 5 "arm_comparison_operator"
8703 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8704 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8705 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8706 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8707 (clobber (reg:CC CC_REGNUM))]
8710 if (GET_CODE (operands[5]) == LT
8711 && (operands[4] == const0_rtx))
8713 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8715 if (operands[2] == const0_rtx)
8716 return \"and\\t%0, %1, %3, asr #31\";
8717 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8719 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8721 if (operands[1] == const0_rtx)
8722 return \"bic\\t%0, %2, %3, asr #31\";
8723 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8725 /* The only case that falls through to here is when both ops 1 & 2
8729 if (GET_CODE (operands[5]) == GE
8730 && (operands[4] == const0_rtx))
8732 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8734 if (operands[2] == const0_rtx)
8735 return \"bic\\t%0, %1, %3, asr #31\";
8736 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8738 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8740 if (operands[1] == const0_rtx)
8741 return \"and\\t%0, %2, %3, asr #31\";
8742 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8744 /* The only case that falls through to here is when both ops 1 & 2
8747 if (GET_CODE (operands[4]) == CONST_INT
8748 && !const_ok_for_arm (INTVAL (operands[4])))
8749 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8751 output_asm_insn (\"cmp\\t%3, %4\", operands);
8752 if (which_alternative != 0)
8753 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8754 if (which_alternative != 1)
8755 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8758 [(set_attr "conds" "clob")
8759 (set_attr "length" "8,8,12")]
8762 (define_insn "*ifcompare_plus_move"
8763 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8764 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8765 [(match_operand:SI 4 "s_register_operand" "r,r")
8766 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8768 (match_operand:SI 2 "s_register_operand" "r,r")
8769 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8770 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8771 (clobber (reg:CC CC_REGNUM))]
8774 [(set_attr "conds" "clob")
8775 (set_attr "length" "8,12")]
8778 (define_insn "*if_plus_move"
8779 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8781 (match_operator 4 "arm_comparison_operator"
8782 [(match_operand 5 "cc_register" "") (const_int 0)])
8784 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8785 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8786 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8790 sub%d4\\t%0, %2, #%n3
8791 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8792 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8793 [(set_attr "conds" "use")
8794 (set_attr "length" "4,4,8,8")
8795 (set_attr "type" "*,*,*,*")]
8798 (define_insn "*ifcompare_move_plus"
8799 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8800 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8801 [(match_operand:SI 4 "s_register_operand" "r,r")
8802 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8803 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8805 (match_operand:SI 2 "s_register_operand" "r,r")
8806 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8807 (clobber (reg:CC CC_REGNUM))]
8810 [(set_attr "conds" "clob")
8811 (set_attr "length" "8,12")]
8814 (define_insn "*if_move_plus"
8815 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8817 (match_operator 4 "arm_comparison_operator"
8818 [(match_operand 5 "cc_register" "") (const_int 0)])
8819 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8821 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8822 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8826 sub%D4\\t%0, %2, #%n3
8827 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8828 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8829 [(set_attr "conds" "use")
8830 (set_attr "length" "4,4,8,8")
8831 (set_attr "type" "*,*,*,*")]
8834 (define_insn "*ifcompare_arith_arith"
8835 [(set (match_operand:SI 0 "s_register_operand" "=r")
8836 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8837 [(match_operand:SI 5 "s_register_operand" "r")
8838 (match_operand:SI 6 "arm_add_operand" "rIL")])
8839 (match_operator:SI 8 "shiftable_operator"
8840 [(match_operand:SI 1 "s_register_operand" "r")
8841 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8842 (match_operator:SI 7 "shiftable_operator"
8843 [(match_operand:SI 3 "s_register_operand" "r")
8844 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8845 (clobber (reg:CC CC_REGNUM))]
8848 [(set_attr "conds" "clob")
8849 (set_attr "length" "12")]
8852 (define_insn "*if_arith_arith"
8853 [(set (match_operand:SI 0 "s_register_operand" "=r")
8854 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8855 [(match_operand 8 "cc_register" "") (const_int 0)])
8856 (match_operator:SI 6 "shiftable_operator"
8857 [(match_operand:SI 1 "s_register_operand" "r")
8858 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8859 (match_operator:SI 7 "shiftable_operator"
8860 [(match_operand:SI 3 "s_register_operand" "r")
8861 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8863 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8864 [(set_attr "conds" "use")
8865 (set_attr "length" "8")]
8868 (define_insn "*ifcompare_arith_move"
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 2 "s_register_operand" "r,r")
8872 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8873 (match_operator:SI 7 "shiftable_operator"
8874 [(match_operand:SI 4 "s_register_operand" "r,r")
8875 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8876 (match_operand:SI 1 "arm_rhs_operand" "0,?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[3] == const0_rtx
8884 && GET_CODE (operands[7]) != AND
8885 && GET_CODE (operands[5]) == REG
8886 && GET_CODE (operands[1]) == REG
8887 && REGNO (operands[1]) == REGNO (operands[4])
8888 && REGNO (operands[4]) != REGNO (operands[0]))
8890 if (GET_CODE (operands[6]) == LT)
8891 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8892 else if (GET_CODE (operands[6]) == GE)
8893 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8895 if (GET_CODE (operands[3]) == CONST_INT
8896 && !const_ok_for_arm (INTVAL (operands[3])))
8897 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8899 output_asm_insn (\"cmp\\t%2, %3\", operands);
8900 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8901 if (which_alternative != 0)
8902 return \"mov%D6\\t%0, %1\";
8905 [(set_attr "conds" "clob")
8906 (set_attr "length" "8,12")]
8909 (define_insn "*if_arith_move"
8910 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8911 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8912 [(match_operand 6 "cc_register" "") (const_int 0)])
8913 (match_operator:SI 5 "shiftable_operator"
8914 [(match_operand:SI 2 "s_register_operand" "r,r")
8915 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8916 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8920 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8921 [(set_attr "conds" "use")
8922 (set_attr "length" "4,8")
8923 (set_attr "type" "*,*")]
8926 (define_insn "*ifcompare_move_arith"
8927 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8928 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8929 [(match_operand:SI 4 "s_register_operand" "r,r")
8930 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8931 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8932 (match_operator:SI 7 "shiftable_operator"
8933 [(match_operand:SI 2 "s_register_operand" "r,r")
8934 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8935 (clobber (reg:CC CC_REGNUM))]
8938 /* If we have an operation where (op x 0) is the identity operation and
8939 the conditional operator is LT or GE and we are comparing against zero and
8940 everything is in registers then we can do this in two instructions */
8941 if (operands[5] == const0_rtx
8942 && GET_CODE (operands[7]) != AND
8943 && GET_CODE (operands[3]) == REG
8944 && GET_CODE (operands[1]) == REG
8945 && REGNO (operands[1]) == REGNO (operands[2])
8946 && REGNO (operands[2]) != REGNO (operands[0]))
8948 if (GET_CODE (operands[6]) == GE)
8949 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8950 else if (GET_CODE (operands[6]) == LT)
8951 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8954 if (GET_CODE (operands[5]) == CONST_INT
8955 && !const_ok_for_arm (INTVAL (operands[5])))
8956 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8958 output_asm_insn (\"cmp\\t%4, %5\", operands);
8960 if (which_alternative != 0)
8961 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8962 return \"%I7%D6\\t%0, %2, %3\";
8964 [(set_attr "conds" "clob")
8965 (set_attr "length" "8,12")]
8968 (define_insn "*if_move_arith"
8969 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8971 (match_operator 4 "arm_comparison_operator"
8972 [(match_operand 6 "cc_register" "") (const_int 0)])
8973 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8974 (match_operator:SI 5 "shiftable_operator"
8975 [(match_operand:SI 2 "s_register_operand" "r,r")
8976 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8980 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8981 [(set_attr "conds" "use")
8982 (set_attr "length" "4,8")
8983 (set_attr "type" "*,*")]
8986 (define_insn "*ifcompare_move_not"
8987 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8989 (match_operator 5 "arm_comparison_operator"
8990 [(match_operand:SI 3 "s_register_operand" "r,r")
8991 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8992 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8994 (match_operand:SI 2 "s_register_operand" "r,r"))))
8995 (clobber (reg:CC CC_REGNUM))]
8998 [(set_attr "conds" "clob")
8999 (set_attr "length" "8,12")]
9002 (define_insn "*if_move_not"
9003 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9005 (match_operator 4 "arm_comparison_operator"
9006 [(match_operand 3 "cc_register" "") (const_int 0)])
9007 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9008 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9012 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9013 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9014 [(set_attr "conds" "use")
9015 (set_attr "length" "4,8,8")]
9018 (define_insn "*ifcompare_not_move"
9019 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9021 (match_operator 5 "arm_comparison_operator"
9022 [(match_operand:SI 3 "s_register_operand" "r,r")
9023 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9025 (match_operand:SI 2 "s_register_operand" "r,r"))
9026 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9027 (clobber (reg:CC CC_REGNUM))]
9030 [(set_attr "conds" "clob")
9031 (set_attr "length" "8,12")]
9034 (define_insn "*if_not_move"
9035 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9037 (match_operator 4 "arm_comparison_operator"
9038 [(match_operand 3 "cc_register" "") (const_int 0)])
9039 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9040 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9044 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9045 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9046 [(set_attr "conds" "use")
9047 (set_attr "length" "4,8,8")]
9050 (define_insn "*ifcompare_shift_move"
9051 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9053 (match_operator 6 "arm_comparison_operator"
9054 [(match_operand:SI 4 "s_register_operand" "r,r")
9055 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9056 (match_operator:SI 7 "shift_operator"
9057 [(match_operand:SI 2 "s_register_operand" "r,r")
9058 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9059 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9060 (clobber (reg:CC CC_REGNUM))]
9063 [(set_attr "conds" "clob")
9064 (set_attr "length" "8,12")]
9067 (define_insn "*if_shift_move"
9068 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9070 (match_operator 5 "arm_comparison_operator"
9071 [(match_operand 6 "cc_register" "") (const_int 0)])
9072 (match_operator:SI 4 "shift_operator"
9073 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9074 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9075 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9079 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9080 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9081 [(set_attr "conds" "use")
9082 (set_attr "shift" "2")
9083 (set_attr "length" "4,8,8")
9084 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9085 (const_string "alu_shift")
9086 (const_string "alu_shift_reg")))]
9089 (define_insn "*ifcompare_move_shift"
9090 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9092 (match_operator 6 "arm_comparison_operator"
9093 [(match_operand:SI 4 "s_register_operand" "r,r")
9094 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9095 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9096 (match_operator:SI 7 "shift_operator"
9097 [(match_operand:SI 2 "s_register_operand" "r,r")
9098 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9099 (clobber (reg:CC CC_REGNUM))]
9102 [(set_attr "conds" "clob")
9103 (set_attr "length" "8,12")]
9106 (define_insn "*if_move_shift"
9107 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9109 (match_operator 5 "arm_comparison_operator"
9110 [(match_operand 6 "cc_register" "") (const_int 0)])
9111 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9112 (match_operator:SI 4 "shift_operator"
9113 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9114 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9118 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9119 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9120 [(set_attr "conds" "use")
9121 (set_attr "shift" "2")
9122 (set_attr "length" "4,8,8")
9123 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9124 (const_string "alu_shift")
9125 (const_string "alu_shift_reg")))]
9128 (define_insn "*ifcompare_shift_shift"
9129 [(set (match_operand:SI 0 "s_register_operand" "=r")
9131 (match_operator 7 "arm_comparison_operator"
9132 [(match_operand:SI 5 "s_register_operand" "r")
9133 (match_operand:SI 6 "arm_add_operand" "rIL")])
9134 (match_operator:SI 8 "shift_operator"
9135 [(match_operand:SI 1 "s_register_operand" "r")
9136 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9137 (match_operator:SI 9 "shift_operator"
9138 [(match_operand:SI 3 "s_register_operand" "r")
9139 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9140 (clobber (reg:CC CC_REGNUM))]
9143 [(set_attr "conds" "clob")
9144 (set_attr "length" "12")]
9147 (define_insn "*if_shift_shift"
9148 [(set (match_operand:SI 0 "s_register_operand" "=r")
9150 (match_operator 5 "arm_comparison_operator"
9151 [(match_operand 8 "cc_register" "") (const_int 0)])
9152 (match_operator:SI 6 "shift_operator"
9153 [(match_operand:SI 1 "s_register_operand" "r")
9154 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9155 (match_operator:SI 7 "shift_operator"
9156 [(match_operand:SI 3 "s_register_operand" "r")
9157 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9159 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9160 [(set_attr "conds" "use")
9161 (set_attr "shift" "1")
9162 (set_attr "length" "8")
9163 (set (attr "type") (if_then_else
9164 (and (match_operand 2 "const_int_operand" "")
9165 (match_operand 4 "const_int_operand" ""))
9166 (const_string "alu_shift")
9167 (const_string "alu_shift_reg")))]
9170 (define_insn "*ifcompare_not_arith"
9171 [(set (match_operand:SI 0 "s_register_operand" "=r")
9173 (match_operator 6 "arm_comparison_operator"
9174 [(match_operand:SI 4 "s_register_operand" "r")
9175 (match_operand:SI 5 "arm_add_operand" "rIL")])
9176 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9177 (match_operator:SI 7 "shiftable_operator"
9178 [(match_operand:SI 2 "s_register_operand" "r")
9179 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9180 (clobber (reg:CC CC_REGNUM))]
9183 [(set_attr "conds" "clob")
9184 (set_attr "length" "12")]
9187 (define_insn "*if_not_arith"
9188 [(set (match_operand:SI 0 "s_register_operand" "=r")
9190 (match_operator 5 "arm_comparison_operator"
9191 [(match_operand 4 "cc_register" "") (const_int 0)])
9192 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9193 (match_operator:SI 6 "shiftable_operator"
9194 [(match_operand:SI 2 "s_register_operand" "r")
9195 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9197 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9198 [(set_attr "conds" "use")
9199 (set_attr "length" "8")]
9202 (define_insn "*ifcompare_arith_not"
9203 [(set (match_operand:SI 0 "s_register_operand" "=r")
9205 (match_operator 6 "arm_comparison_operator"
9206 [(match_operand:SI 4 "s_register_operand" "r")
9207 (match_operand:SI 5 "arm_add_operand" "rIL")])
9208 (match_operator:SI 7 "shiftable_operator"
9209 [(match_operand:SI 2 "s_register_operand" "r")
9210 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9211 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9212 (clobber (reg:CC CC_REGNUM))]
9215 [(set_attr "conds" "clob")
9216 (set_attr "length" "12")]
9219 (define_insn "*if_arith_not"
9220 [(set (match_operand:SI 0 "s_register_operand" "=r")
9222 (match_operator 5 "arm_comparison_operator"
9223 [(match_operand 4 "cc_register" "") (const_int 0)])
9224 (match_operator:SI 6 "shiftable_operator"
9225 [(match_operand:SI 2 "s_register_operand" "r")
9226 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9227 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9229 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9230 [(set_attr "conds" "use")
9231 (set_attr "length" "8")]
9234 (define_insn "*ifcompare_neg_move"
9235 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9237 (match_operator 5 "arm_comparison_operator"
9238 [(match_operand:SI 3 "s_register_operand" "r,r")
9239 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9240 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9241 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9242 (clobber (reg:CC CC_REGNUM))]
9245 [(set_attr "conds" "clob")
9246 (set_attr "length" "8,12")]
9249 (define_insn "*if_neg_move"
9250 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9252 (match_operator 4 "arm_comparison_operator"
9253 [(match_operand 3 "cc_register" "") (const_int 0)])
9254 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9255 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9259 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9260 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9261 [(set_attr "conds" "use")
9262 (set_attr "length" "4,8,8")]
9265 (define_insn "*ifcompare_move_neg"
9266 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9268 (match_operator 5 "arm_comparison_operator"
9269 [(match_operand:SI 3 "s_register_operand" "r,r")
9270 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9271 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9272 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9273 (clobber (reg:CC CC_REGNUM))]
9276 [(set_attr "conds" "clob")
9277 (set_attr "length" "8,12")]
9280 (define_insn "*if_move_neg"
9281 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9283 (match_operator 4 "arm_comparison_operator"
9284 [(match_operand 3 "cc_register" "") (const_int 0)])
9285 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9286 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9290 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9291 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9292 [(set_attr "conds" "use")
9293 (set_attr "length" "4,8,8")]
9296 (define_insn "*arith_adjacentmem"
9297 [(set (match_operand:SI 0 "s_register_operand" "=r")
9298 (match_operator:SI 1 "shiftable_operator"
9299 [(match_operand:SI 2 "memory_operand" "m")
9300 (match_operand:SI 3 "memory_operand" "m")]))
9301 (clobber (match_scratch:SI 4 "=r"))]
9302 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9308 HOST_WIDE_INT val1 = 0, val2 = 0;
9310 if (REGNO (operands[0]) > REGNO (operands[4]))
9312 ldm[1] = operands[4];
9313 ldm[2] = operands[0];
9317 ldm[1] = operands[0];
9318 ldm[2] = operands[4];
9321 base_reg = XEXP (operands[2], 0);
9323 if (!REG_P (base_reg))
9325 val1 = INTVAL (XEXP (base_reg, 1));
9326 base_reg = XEXP (base_reg, 0);
9329 if (!REG_P (XEXP (operands[3], 0)))
9330 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9332 arith[0] = operands[0];
9333 arith[3] = operands[1];
9347 if (val1 !=0 && val2 != 0)
9349 if (val1 == 4 || val2 == 4)
9350 /* Other val must be 8, since we know they are adjacent and neither
9352 output_asm_insn (\"ldm%?ib\\t%0, {%1, %2}\", ldm);
9357 ldm[0] = ops[0] = operands[4];
9359 ops[2] = GEN_INT (val1);
9360 output_add_immediate (ops);
9362 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9364 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9370 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9372 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9377 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9379 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9381 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9384 [(set_attr "length" "12")
9385 (set_attr "predicable" "yes")
9386 (set_attr "type" "load1")]
9389 ;; the arm can support extended pre-inc instructions
9391 ;; In all these cases, we use operands 0 and 1 for the register being
9392 ;; incremented because those are the operands that local-alloc will
9393 ;; tie and these are the pair most likely to be tieable (and the ones
9394 ;; that will benefit the most).
9396 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9397 ;; elimination will cause too many headaches.
9399 (define_insn "*strqi_preinc"
9400 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9401 (match_operand:SI 2 "index_operand" "rJ")))
9402 (match_operand:QI 3 "s_register_operand" "r"))
9403 (set (match_operand:SI 0 "s_register_operand" "=r")
9404 (plus:SI (match_dup 1) (match_dup 2)))]
9406 && !arm_eliminable_register (operands[0])
9407 && !arm_eliminable_register (operands[1])
9408 && !arm_eliminable_register (operands[2])"
9409 "str%?b\\t%3, [%0, %2]!"
9410 [(set_attr "type" "store1")
9411 (set_attr "predicable" "yes")]
9414 (define_insn "*strqi_predec"
9415 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9416 (match_operand:SI 2 "s_register_operand" "r")))
9417 (match_operand:QI 3 "s_register_operand" "r"))
9418 (set (match_operand:SI 0 "s_register_operand" "=r")
9419 (minus:SI (match_dup 1) (match_dup 2)))]
9421 && !arm_eliminable_register (operands[0])
9422 && !arm_eliminable_register (operands[1])
9423 && !arm_eliminable_register (operands[2])"
9424 "str%?b\\t%3, [%0, -%2]!"
9425 [(set_attr "type" "store1")
9426 (set_attr "predicable" "yes")]
9429 (define_insn "*loadqi_preinc"
9430 [(set (match_operand:QI 3 "s_register_operand" "=r")
9431 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9432 (match_operand:SI 2 "index_operand" "rJ"))))
9433 (set (match_operand:SI 0 "s_register_operand" "=r")
9434 (plus:SI (match_dup 1) (match_dup 2)))]
9436 && !arm_eliminable_register (operands[0])
9437 && !arm_eliminable_register (operands[1])
9438 && !arm_eliminable_register (operands[2])"
9439 "ldr%?b\\t%3, [%0, %2]!"
9440 [(set_attr "type" "load_byte")
9441 (set_attr "predicable" "yes")]
9444 (define_insn "*loadqi_predec"
9445 [(set (match_operand:QI 3 "s_register_operand" "=r")
9446 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9447 (match_operand:SI 2 "s_register_operand" "r"))))
9448 (set (match_operand:SI 0 "s_register_operand" "=r")
9449 (minus:SI (match_dup 1) (match_dup 2)))]
9451 && !arm_eliminable_register (operands[0])
9452 && !arm_eliminable_register (operands[1])
9453 && !arm_eliminable_register (operands[2])"
9454 "ldr%?b\\t%3, [%0, -%2]!"
9455 [(set_attr "type" "load_byte")
9456 (set_attr "predicable" "yes")]
9459 (define_insn "*loadqisi_preinc"
9460 [(set (match_operand:SI 3 "s_register_operand" "=r")
9462 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9463 (match_operand:SI 2 "index_operand" "rJ")))))
9464 (set (match_operand:SI 0 "s_register_operand" "=r")
9465 (plus: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%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9471 [(set_attr "type" "load_byte")
9472 (set_attr "predicable" "yes")]
9475 (define_insn "*loadqisi_predec"
9476 [(set (match_operand:SI 3 "s_register_operand" "=r")
9478 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9479 (match_operand:SI 2 "s_register_operand" "r")))))
9480 (set (match_operand:SI 0 "s_register_operand" "=r")
9481 (minus:SI (match_dup 1) (match_dup 2)))]
9483 && !arm_eliminable_register (operands[0])
9484 && !arm_eliminable_register (operands[1])
9485 && !arm_eliminable_register (operands[2])"
9486 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9487 [(set_attr "type" "load_byte")
9488 (set_attr "predicable" "yes")]
9491 (define_insn "*strsi_preinc"
9492 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9493 (match_operand:SI 2 "index_operand" "rJ")))
9494 (match_operand:SI 3 "s_register_operand" "r"))
9495 (set (match_operand:SI 0 "s_register_operand" "=r")
9496 (plus:SI (match_dup 1) (match_dup 2)))]
9498 && !arm_eliminable_register (operands[0])
9499 && !arm_eliminable_register (operands[1])
9500 && !arm_eliminable_register (operands[2])"
9501 "str%?\\t%3, [%0, %2]!"
9502 [(set_attr "type" "store1")
9503 (set_attr "predicable" "yes")]
9506 (define_insn "*strsi_predec"
9507 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9508 (match_operand:SI 2 "s_register_operand" "r")))
9509 (match_operand:SI 3 "s_register_operand" "r"))
9510 (set (match_operand:SI 0 "s_register_operand" "=r")
9511 (minus:SI (match_dup 1) (match_dup 2)))]
9513 && !arm_eliminable_register (operands[0])
9514 && !arm_eliminable_register (operands[1])
9515 && !arm_eliminable_register (operands[2])"
9516 "str%?\\t%3, [%0, -%2]!"
9517 [(set_attr "type" "store1")
9518 (set_attr "predicable" "yes")]
9521 (define_insn "*loadsi_preinc"
9522 [(set (match_operand:SI 3 "s_register_operand" "=r")
9523 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9524 (match_operand:SI 2 "index_operand" "rJ"))))
9525 (set (match_operand:SI 0 "s_register_operand" "=r")
9526 (plus:SI (match_dup 1) (match_dup 2)))]
9528 && !arm_eliminable_register (operands[0])
9529 && !arm_eliminable_register (operands[1])
9530 && !arm_eliminable_register (operands[2])"
9531 "ldr%?\\t%3, [%0, %2]!"
9532 [(set_attr "type" "load1")
9533 (set_attr "predicable" "yes")]
9536 (define_insn "*loadsi_predec"
9537 [(set (match_operand:SI 3 "s_register_operand" "=r")
9538 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9539 (match_operand:SI 2 "s_register_operand" "r"))))
9540 (set (match_operand:SI 0 "s_register_operand" "=r")
9541 (minus:SI (match_dup 1) (match_dup 2)))]
9543 && !arm_eliminable_register (operands[0])
9544 && !arm_eliminable_register (operands[1])
9545 && !arm_eliminable_register (operands[2])"
9546 "ldr%?\\t%3, [%0, -%2]!"
9547 [(set_attr "type" "load1")
9548 (set_attr "predicable" "yes")]
9551 (define_insn "*strqi_shiftpreinc"
9552 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9553 [(match_operand:SI 3 "s_register_operand" "r")
9554 (match_operand:SI 4 "const_shift_operand" "n")])
9555 (match_operand:SI 1 "s_register_operand" "0")))
9556 (match_operand:QI 5 "s_register_operand" "r"))
9557 (set (match_operand:SI 0 "s_register_operand" "=r")
9558 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9561 && !arm_eliminable_register (operands[0])
9562 && !arm_eliminable_register (operands[1])
9563 && !arm_eliminable_register (operands[3])"
9564 "str%?b\\t%5, [%0, %3%S2]!"
9565 [(set_attr "type" "store1")
9566 (set_attr "predicable" "yes")]
9569 (define_insn "*strqi_shiftpredec"
9570 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9571 (match_operator:SI 2 "shift_operator"
9572 [(match_operand:SI 3 "s_register_operand" "r")
9573 (match_operand:SI 4 "const_shift_operand" "n")])))
9574 (match_operand:QI 5 "s_register_operand" "r"))
9575 (set (match_operand:SI 0 "s_register_operand" "=r")
9576 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9579 && !arm_eliminable_register (operands[0])
9580 && !arm_eliminable_register (operands[1])
9581 && !arm_eliminable_register (operands[3])"
9582 "str%?b\\t%5, [%0, -%3%S2]!"
9583 [(set_attr "type" "store1")
9584 (set_attr "predicable" "yes")]
9587 (define_insn "*loadqi_shiftpreinc"
9588 [(set (match_operand:QI 5 "s_register_operand" "=r")
9589 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9590 [(match_operand:SI 3 "s_register_operand" "r")
9591 (match_operand:SI 4 "const_shift_operand" "n")])
9592 (match_operand:SI 1 "s_register_operand" "0"))))
9593 (set (match_operand:SI 0 "s_register_operand" "=r")
9594 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9597 && !arm_eliminable_register (operands[0])
9598 && !arm_eliminable_register (operands[1])
9599 && !arm_eliminable_register (operands[3])"
9600 "ldr%?b\\t%5, [%0, %3%S2]!"
9601 [(set_attr "type" "load_byte")
9602 (set_attr "predicable" "yes")]
9605 (define_insn "*loadqi_shiftpredec"
9606 [(set (match_operand:QI 5 "s_register_operand" "=r")
9607 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9608 (match_operator:SI 2 "shift_operator"
9609 [(match_operand:SI 3 "s_register_operand" "r")
9610 (match_operand:SI 4 "const_shift_operand" "n")]))))
9611 (set (match_operand:SI 0 "s_register_operand" "=r")
9612 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9615 && !arm_eliminable_register (operands[0])
9616 && !arm_eliminable_register (operands[1])
9617 && !arm_eliminable_register (operands[3])"
9618 "ldr%?b\\t%5, [%0, -%3%S2]!"
9619 [(set_attr "type" "load_byte")
9620 (set_attr "predicable" "yes")]
9623 (define_insn "*strsi_shiftpreinc"
9624 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9625 [(match_operand:SI 3 "s_register_operand" "r")
9626 (match_operand:SI 4 "const_shift_operand" "n")])
9627 (match_operand:SI 1 "s_register_operand" "0")))
9628 (match_operand:SI 5 "s_register_operand" "r"))
9629 (set (match_operand:SI 0 "s_register_operand" "=r")
9630 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9633 && !arm_eliminable_register (operands[0])
9634 && !arm_eliminable_register (operands[1])
9635 && !arm_eliminable_register (operands[3])"
9636 "str%?\\t%5, [%0, %3%S2]!"
9637 [(set_attr "type" "store1")
9638 (set_attr "predicable" "yes")]
9641 (define_insn "*strsi_shiftpredec"
9642 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9643 (match_operator:SI 2 "shift_operator"
9644 [(match_operand:SI 3 "s_register_operand" "r")
9645 (match_operand:SI 4 "const_shift_operand" "n")])))
9646 (match_operand:SI 5 "s_register_operand" "r"))
9647 (set (match_operand:SI 0 "s_register_operand" "=r")
9648 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9651 && !arm_eliminable_register (operands[0])
9652 && !arm_eliminable_register (operands[1])
9653 && !arm_eliminable_register (operands[3])"
9654 "str%?\\t%5, [%0, -%3%S2]!"
9655 [(set_attr "type" "store1")
9656 (set_attr "predicable" "yes")]
9659 (define_insn "*loadsi_shiftpreinc"
9660 [(set (match_operand:SI 5 "s_register_operand" "=r")
9661 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9662 [(match_operand:SI 3 "s_register_operand" "r")
9663 (match_operand:SI 4 "const_shift_operand" "n")])
9664 (match_operand:SI 1 "s_register_operand" "0"))))
9665 (set (match_operand:SI 0 "s_register_operand" "=r")
9666 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9669 && !arm_eliminable_register (operands[0])
9670 && !arm_eliminable_register (operands[1])
9671 && !arm_eliminable_register (operands[3])"
9672 "ldr%?\\t%5, [%0, %3%S2]!"
9673 [(set_attr "type" "load1")
9674 (set_attr "predicable" "yes")]
9677 (define_insn "*loadsi_shiftpredec"
9678 [(set (match_operand:SI 5 "s_register_operand" "=r")
9679 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9680 (match_operator:SI 2 "shift_operator"
9681 [(match_operand:SI 3 "s_register_operand" "r")
9682 (match_operand:SI 4 "const_shift_operand" "n")]))))
9683 (set (match_operand:SI 0 "s_register_operand" "=r")
9684 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9687 && !arm_eliminable_register (operands[0])
9688 && !arm_eliminable_register (operands[1])
9689 && !arm_eliminable_register (operands[3])"
9690 "ldr%?\\t%5, [%0, -%3%S2]!"
9691 [(set_attr "type" "load1")
9692 (set_attr "predicable" "yes")])
9694 ; It can also support extended post-inc expressions, but combine doesn't
9696 ; It doesn't seem worth adding peepholes for anything but the most common
9697 ; cases since, unlike combine, the increment must immediately follow the load
9698 ; for this pattern to match.
9699 ; We must watch to see that the source/destination register isn't also the
9700 ; same as the base address register, and that if the index is a register,
9701 ; that it is not the same as the base address register. In such cases the
9702 ; instruction that we would generate would have UNPREDICTABLE behavior so
9706 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9707 (match_operand:QI 2 "s_register_operand" "r"))
9709 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9711 && (REGNO (operands[2]) != REGNO (operands[0]))
9712 && (GET_CODE (operands[1]) != REG
9713 || (REGNO (operands[1]) != REGNO (operands[0])))"
9714 "str%?b\\t%2, [%0], %1"
9718 [(set (match_operand:QI 0 "s_register_operand" "=r")
9719 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9721 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9723 && REGNO (operands[0]) != REGNO(operands[1])
9724 && (GET_CODE (operands[2]) != REG
9725 || REGNO(operands[0]) != REGNO (operands[2]))"
9726 "ldr%?b\\t%0, [%1], %2"
9730 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9731 (match_operand:SI 2 "s_register_operand" "r"))
9733 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9735 && (REGNO (operands[2]) != REGNO (operands[0]))
9736 && (GET_CODE (operands[1]) != REG
9737 || (REGNO (operands[1]) != REGNO (operands[0])))"
9738 "str%?\\t%2, [%0], %1"
9742 [(set (match_operand:SI 0 "s_register_operand" "=r")
9743 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9745 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9747 && REGNO (operands[0]) != REGNO(operands[1])
9748 && (GET_CODE (operands[2]) != REG
9749 || REGNO(operands[0]) != REGNO (operands[2]))"
9750 "ldr%?\\t%0, [%1], %2"
9754 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9755 (match_operand:SI 1 "index_operand" "rJ")))
9756 (match_operand:QI 2 "s_register_operand" "r"))
9757 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9759 && (REGNO (operands[2]) != REGNO (operands[0]))
9760 && (GET_CODE (operands[1]) != REG
9761 || (REGNO (operands[1]) != REGNO (operands[0])))"
9762 "str%?b\\t%2, [%0, %1]!"
9766 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9767 [(match_operand:SI 0 "s_register_operand" "r")
9768 (match_operand:SI 1 "const_int_operand" "n")])
9769 (match_operand:SI 2 "s_register_operand" "+r")))
9770 (match_operand:QI 3 "s_register_operand" "r"))
9771 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9774 && (REGNO (operands[3]) != REGNO (operands[2]))
9775 && (REGNO (operands[0]) != REGNO (operands[2]))"
9776 "str%?b\\t%3, [%2, %0%S4]!"
9779 ; This pattern is never tried by combine, so do it as a peephole
9782 [(set (match_operand:SI 0 "arm_general_register_operand" "")
9783 (match_operand:SI 1 "arm_general_register_operand" ""))
9784 (set (reg:CC CC_REGNUM)
9785 (compare:CC (match_dup 1) (const_int 0)))]
9787 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9788 (set (match_dup 0) (match_dup 1))])]
9792 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9793 ; reversed, check that the memory references aren't volatile.
9796 [(set (match_operand:SI 0 "s_register_operand" "=r")
9797 (match_operand:SI 4 "memory_operand" "m"))
9798 (set (match_operand:SI 1 "s_register_operand" "=r")
9799 (match_operand:SI 5 "memory_operand" "m"))
9800 (set (match_operand:SI 2 "s_register_operand" "=r")
9801 (match_operand:SI 6 "memory_operand" "m"))
9802 (set (match_operand:SI 3 "s_register_operand" "=r")
9803 (match_operand:SI 7 "memory_operand" "m"))]
9804 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9806 return emit_ldm_seq (operands, 4);
9811 [(set (match_operand:SI 0 "s_register_operand" "=r")
9812 (match_operand:SI 3 "memory_operand" "m"))
9813 (set (match_operand:SI 1 "s_register_operand" "=r")
9814 (match_operand:SI 4 "memory_operand" "m"))
9815 (set (match_operand:SI 2 "s_register_operand" "=r")
9816 (match_operand:SI 5 "memory_operand" "m"))]
9817 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9819 return emit_ldm_seq (operands, 3);
9824 [(set (match_operand:SI 0 "s_register_operand" "=r")
9825 (match_operand:SI 2 "memory_operand" "m"))
9826 (set (match_operand:SI 1 "s_register_operand" "=r")
9827 (match_operand:SI 3 "memory_operand" "m"))]
9828 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9830 return emit_ldm_seq (operands, 2);
9835 [(set (match_operand:SI 4 "memory_operand" "=m")
9836 (match_operand:SI 0 "s_register_operand" "r"))
9837 (set (match_operand:SI 5 "memory_operand" "=m")
9838 (match_operand:SI 1 "s_register_operand" "r"))
9839 (set (match_operand:SI 6 "memory_operand" "=m")
9840 (match_operand:SI 2 "s_register_operand" "r"))
9841 (set (match_operand:SI 7 "memory_operand" "=m")
9842 (match_operand:SI 3 "s_register_operand" "r"))]
9843 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9845 return emit_stm_seq (operands, 4);
9850 [(set (match_operand:SI 3 "memory_operand" "=m")
9851 (match_operand:SI 0 "s_register_operand" "r"))
9852 (set (match_operand:SI 4 "memory_operand" "=m")
9853 (match_operand:SI 1 "s_register_operand" "r"))
9854 (set (match_operand:SI 5 "memory_operand" "=m")
9855 (match_operand:SI 2 "s_register_operand" "r"))]
9856 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9858 return emit_stm_seq (operands, 3);
9863 [(set (match_operand:SI 2 "memory_operand" "=m")
9864 (match_operand:SI 0 "s_register_operand" "r"))
9865 (set (match_operand:SI 3 "memory_operand" "=m")
9866 (match_operand:SI 1 "s_register_operand" "r"))]
9867 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9869 return emit_stm_seq (operands, 2);
9874 [(set (match_operand:SI 0 "s_register_operand" "")
9875 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9877 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9878 [(match_operand:SI 3 "s_register_operand" "")
9879 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9880 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9882 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9883 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9888 ;; This split can be used because CC_Z mode implies that the following
9889 ;; branch will be an equality, or an unsigned inequality, so the sign
9890 ;; extension is not needed.
9893 [(set (reg:CC_Z CC_REGNUM)
9895 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9897 (match_operand 1 "const_int_operand" "")))
9898 (clobber (match_scratch:SI 2 ""))]
9900 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9901 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9902 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9903 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9905 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9909 (define_expand "prologue"
9910 [(clobber (const_int 0))]
9913 arm_expand_prologue ();
9915 thumb_expand_prologue ();
9920 (define_expand "epilogue"
9921 [(clobber (const_int 0))]
9924 if (current_function_calls_eh_return)
9925 emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
9927 thumb_expand_epilogue ();
9928 else if (USE_RETURN_INSN (FALSE))
9930 emit_jump_insn (gen_return ());
9933 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9935 gen_rtx_RETURN (VOIDmode)),
9941 ;; Note - although unspec_volatile's USE all hard registers,
9942 ;; USEs are ignored after relaod has completed. Thus we need
9943 ;; to add an unspec of the link register to ensure that flow
9944 ;; does not think that it is unused by the sibcall branch that
9945 ;; will replace the standard function epilogue.
9946 (define_insn "sibcall_epilogue"
9947 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9948 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9951 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9952 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9953 return arm_output_epilogue (next_nonnote_insn (insn));
9955 ;; Length is absolute worst case
9956 [(set_attr "length" "44")
9957 (set_attr "type" "block")
9958 ;; We don't clobber the conditions, but the potential length of this
9959 ;; operation is sufficient to make conditionalizing the sequence
9960 ;; unlikely to be profitable.
9961 (set_attr "conds" "clob")]
9964 (define_insn "*epilogue_insns"
9965 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9969 return arm_output_epilogue (NULL);
9970 else /* TARGET_THUMB */
9971 return thumb_unexpanded_epilogue ();
9973 ; Length is absolute worst case
9974 [(set_attr "length" "44")
9975 (set_attr "type" "block")
9976 ;; We don't clobber the conditions, but the potential length of this
9977 ;; operation is sufficient to make conditionalizing the sequence
9978 ;; unlikely to be profitable.
9979 (set_attr "conds" "clob")]
9982 (define_expand "eh_epilogue"
9983 [(use (match_operand:SI 0 "register_operand" ""))
9984 (use (match_operand:SI 1 "register_operand" ""))
9985 (use (match_operand:SI 2 "register_operand" ""))]
9989 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9990 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9992 rtx ra = gen_rtx_REG (Pmode, 2);
9994 emit_move_insn (ra, operands[2]);
9997 /* This is a hack -- we may have crystalized the function type too
9999 cfun->machine->func_type = 0;
10003 ;; This split is only used during output to reduce the number of patterns
10004 ;; that need assembler instructions adding to them. We allowed the setting
10005 ;; of the conditions to be implicit during rtl generation so that
10006 ;; the conditional compare patterns would work. However this conflicts to
10007 ;; some extent with the conditional data operations, so we have to split them
10011 [(set (match_operand:SI 0 "s_register_operand" "")
10012 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10013 [(match_operand 2 "" "") (match_operand 3 "" "")])
10015 (match_operand 4 "" "")))
10016 (clobber (reg:CC CC_REGNUM))]
10017 "TARGET_ARM && reload_completed"
10018 [(set (match_dup 5) (match_dup 6))
10019 (cond_exec (match_dup 7)
10020 (set (match_dup 0) (match_dup 4)))]
10023 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10024 operands[2], operands[3]);
10025 enum rtx_code rc = GET_CODE (operands[1]);
10027 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10028 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10029 if (mode == CCFPmode || mode == CCFPEmode)
10030 rc = reverse_condition_maybe_unordered (rc);
10032 rc = reverse_condition (rc);
10034 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10039 [(set (match_operand:SI 0 "s_register_operand" "")
10040 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10041 [(match_operand 2 "" "") (match_operand 3 "" "")])
10042 (match_operand 4 "" "")
10044 (clobber (reg:CC CC_REGNUM))]
10045 "TARGET_ARM && reload_completed"
10046 [(set (match_dup 5) (match_dup 6))
10047 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10048 (set (match_dup 0) (match_dup 4)))]
10051 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10052 operands[2], operands[3]);
10054 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10055 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10060 [(set (match_operand:SI 0 "s_register_operand" "")
10061 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10062 [(match_operand 2 "" "") (match_operand 3 "" "")])
10063 (match_operand 4 "" "")
10064 (match_operand 5 "" "")))
10065 (clobber (reg:CC CC_REGNUM))]
10066 "TARGET_ARM && reload_completed"
10067 [(set (match_dup 6) (match_dup 7))
10068 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10069 (set (match_dup 0) (match_dup 4)))
10070 (cond_exec (match_dup 8)
10071 (set (match_dup 0) (match_dup 5)))]
10074 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10075 operands[2], operands[3]);
10076 enum rtx_code rc = GET_CODE (operands[1]);
10078 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10079 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10080 if (mode == CCFPmode || mode == CCFPEmode)
10081 rc = reverse_condition_maybe_unordered (rc);
10083 rc = reverse_condition (rc);
10085 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10090 [(set (match_operand:SI 0 "s_register_operand" "")
10091 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10092 [(match_operand:SI 2 "s_register_operand" "")
10093 (match_operand:SI 3 "arm_add_operand" "")])
10094 (match_operand:SI 4 "arm_rhs_operand" "")
10096 (match_operand:SI 5 "s_register_operand" ""))))
10097 (clobber (reg:CC CC_REGNUM))]
10098 "TARGET_ARM && reload_completed"
10099 [(set (match_dup 6) (match_dup 7))
10100 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10101 (set (match_dup 0) (match_dup 4)))
10102 (cond_exec (match_dup 8)
10103 (set (match_dup 0) (not:SI (match_dup 5))))]
10106 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10107 operands[2], operands[3]);
10108 enum rtx_code rc = GET_CODE (operands[1]);
10110 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10111 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10112 if (mode == CCFPmode || mode == CCFPEmode)
10113 rc = reverse_condition_maybe_unordered (rc);
10115 rc = reverse_condition (rc);
10117 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10121 (define_insn "*cond_move_not"
10122 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10123 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10124 [(match_operand 3 "cc_register" "") (const_int 0)])
10125 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10127 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10131 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10132 [(set_attr "conds" "use")
10133 (set_attr "length" "4,8")]
10136 ;; The next two patterns occur when an AND operation is followed by a
10137 ;; scc insn sequence
10139 (define_insn "*sign_extract_onebit"
10140 [(set (match_operand:SI 0 "s_register_operand" "=r")
10141 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10143 (match_operand:SI 2 "const_int_operand" "n")))
10144 (clobber (reg:CC CC_REGNUM))]
10147 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10148 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10149 return \"mvnne\\t%0, #0\";
10151 [(set_attr "conds" "clob")
10152 (set_attr "length" "8")]
10155 (define_insn "*not_signextract_onebit"
10156 [(set (match_operand:SI 0 "s_register_operand" "=r")
10158 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10160 (match_operand:SI 2 "const_int_operand" "n"))))
10161 (clobber (reg:CC CC_REGNUM))]
10164 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10165 output_asm_insn (\"tst\\t%1, %2\", operands);
10166 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10167 return \"movne\\t%0, #0\";
10169 [(set_attr "conds" "clob")
10170 (set_attr "length" "12")]
10173 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10174 ;; expressions. For simplicity, the first register is also in the unspec
10176 (define_insn "*push_multi"
10177 [(match_parallel 2 "multi_register_push"
10178 [(set (match_operand:BLK 0 "memory_operand" "=m")
10179 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10180 UNSPEC_PUSH_MULT))])]
10184 int num_saves = XVECLEN (operands[2], 0);
10186 /* For the StrongARM at least it is faster to
10187 use STR to store only a single register. */
10188 if (num_saves == 1)
10189 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10195 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10197 for (i = 1; i < num_saves; i++)
10199 strcat (pattern, \", %|\");
10201 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10204 strcat (pattern, \"}\");
10205 output_asm_insn (pattern, operands);
10210 [(set_attr "type" "store4")]
10213 (define_insn "stack_tie"
10214 [(set (mem:BLK (scratch))
10215 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10216 (match_operand:SI 1 "s_register_operand" "r")]
10220 [(set_attr "length" "0")]
10223 ;; Similarly for the floating point registers
10224 (define_insn "*push_fp_multi"
10225 [(match_parallel 2 "multi_register_push"
10226 [(set (match_operand:BLK 0 "memory_operand" "=m")
10227 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10228 UNSPEC_PUSH_MULT))])]
10229 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10234 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10235 output_asm_insn (pattern, operands);
10238 [(set_attr "type" "f_store")]
10241 ;; Special patterns for dealing with the constant pool
10243 (define_insn "align_4"
10244 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10247 assemble_align (32);
10252 (define_insn "align_8"
10253 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10256 assemble_align (64);
10261 (define_insn "consttable_end"
10262 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10265 making_const_table = FALSE;
10270 (define_insn "consttable_1"
10271 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10274 making_const_table = TRUE;
10275 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10276 assemble_zeros (3);
10279 [(set_attr "length" "4")]
10282 (define_insn "consttable_2"
10283 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10286 making_const_table = TRUE;
10287 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10288 assemble_zeros (2);
10291 [(set_attr "length" "4")]
10294 (define_insn "consttable_4"
10295 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10299 making_const_table = TRUE;
10300 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10305 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10306 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10310 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10315 [(set_attr "length" "4")]
10318 (define_insn "consttable_8"
10319 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10323 making_const_table = TRUE;
10324 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10329 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10330 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10334 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10339 [(set_attr "length" "8")]
10342 ;; Miscellaneous Thumb patterns
10344 (define_expand "tablejump"
10345 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10346 (use (label_ref (match_operand 1 "" "")))])]
10351 /* Hopefully, CSE will eliminate this copy. */
10352 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10353 rtx reg2 = gen_reg_rtx (SImode);
10355 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10356 operands[0] = reg2;
10361 ;; NB never uses BX.
10362 (define_insn "*thumb_tablejump"
10363 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10364 (use (label_ref (match_operand 1 "" "")))]
10367 [(set_attr "length" "2")]
10370 ;; V5 Instructions,
10372 (define_insn "clzsi2"
10373 [(set (match_operand:SI 0 "s_register_operand" "=r")
10374 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10375 "TARGET_ARM && arm_arch5"
10377 [(set_attr "predicable" "yes")])
10379 (define_expand "ffssi2"
10380 [(set (match_operand:SI 0 "s_register_operand" "")
10381 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10382 "TARGET_ARM && arm_arch5"
10387 t1 = gen_reg_rtx (SImode);
10388 t2 = gen_reg_rtx (SImode);
10389 t3 = gen_reg_rtx (SImode);
10391 emit_insn (gen_negsi2 (t1, operands[1]));
10392 emit_insn (gen_andsi3 (t2, operands[1], t1));
10393 emit_insn (gen_clzsi2 (t3, t2));
10394 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10399 (define_expand "ctzsi2"
10400 [(set (match_operand:SI 0 "s_register_operand" "")
10401 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10402 "TARGET_ARM && arm_arch5"
10407 t1 = gen_reg_rtx (SImode);
10408 t2 = gen_reg_rtx (SImode);
10409 t3 = gen_reg_rtx (SImode);
10411 emit_insn (gen_negsi2 (t1, operands[1]));
10412 emit_insn (gen_andsi3 (t2, operands[1], t1));
10413 emit_insn (gen_clzsi2 (t3, t2));
10414 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10419 ;; V5E instructions.
10421 (define_insn "prefetch"
10422 [(prefetch (match_operand:SI 0 "address_operand" "p")
10423 (match_operand:SI 1 "" "")
10424 (match_operand:SI 2 "" ""))]
10425 "TARGET_ARM && arm_arch5e"
10428 ;; General predication pattern
10431 [(match_operator 0 "arm_comparison_operator"
10432 [(match_operand 1 "cc_register" "")
10438 (define_insn "prologue_use"
10439 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10441 "%@ %0 needed for prologue"
10445 ;; Patterns for exception handling
10447 (define_expand "eh_return"
10448 [(use (match_operand 0 "general_operand" ""))]
10453 emit_insn (gen_arm_eh_return (operands[0]));
10455 emit_insn (gen_thumb_eh_return (operands[0]));
10460 ;; We can't expand this before we know where the link register is stored.
10461 (define_insn_and_split "arm_eh_return"
10462 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10464 (clobber (match_scratch:SI 1 "=&r"))]
10467 "&& reload_completed"
10471 arm_set_return_address (operands[0], operands[1]);
10476 (define_insn_and_split "thumb_eh_return"
10477 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
10479 (clobber (match_scratch:SI 1 "=&l"))]
10482 "&& reload_completed"
10486 thumb_set_return_address (operands[0], operands[1]);
10491 ;; Load the FPA co-processor patterns
10493 ;; Load the Maverick co-processor patterns
10494 (include "cirrus.md")
10495 ;; Load the Intel Wireless Multimedia Extension patterns
10496 (include "iwmmxt.md")
10497 ;; Load the VFP co-processor patterns