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, 2006, 2007 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 3, 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 COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;;---------------------------------------------------------------------------
32 [(R0_REGNUM 0) ; First CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (CC_REGNUM 24) ; Condition code pseudo register
38 (LAST_ARM_REGNUM 15) ;
39 (FPA_F0_REGNUM 16) ; FIRST_FPA_REGNUM
40 (FPA_F7_REGNUM 23) ; LAST_FPA_REGNUM
43 ;; 3rd operand to select_dominance_cc_mode
52 ;; Note: sin and cos are no-longer used.
53 ;; Unspec constants for Neon are defined in neon.md.
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.
93 (UNSPEC_TLS 20) ; A symbol that has been treated properly for TLS usage.
94 (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
96 (UNSPEC_STACK_ALIGN 20) ; Doubleword aligned stack pointer. Used to
97 ; generate correct unwind information.
98 (UNSPEC_PIC_OFFSET 22) ; A symbolic 12-bit OFFSET that has been treated
99 ; correctly for PIC usage.
103 ;; UNSPEC_VOLATILE Usage:
106 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
108 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
109 ; instruction epilogue sequence that isn't expanded
110 ; into normal RTL. Used for both normal and sibcall
112 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
113 ; for inlined constants.
114 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
116 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
118 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
120 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
122 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
124 (VUNSPEC_POOL_16 8) ; `pool-entry(16)'. An entry in the constant pool for
126 (VUNSPEC_TMRC 9) ; Used by the iWMMXt TMRC instruction.
127 (VUNSPEC_TMCR 10) ; Used by the iWMMXt TMCR instruction.
128 (VUNSPEC_ALIGN8 11) ; 8-byte alignment version of VUNSPEC_ALIGN
129 (VUNSPEC_WCMP_EQ 12) ; Used by the iWMMXt WCMPEQ instructions
130 (VUNSPEC_WCMP_GTU 13) ; Used by the iWMMXt WCMPGTU instructions
131 (VUNSPEC_WCMP_GT 14) ; Used by the iwMMXT WCMPGT instructions
132 (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
137 ;;---------------------------------------------------------------------------
140 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
141 ; generating ARM code. This is used to control the length of some insn
142 ; patterns that share the same RTL in both ARM and Thumb code.
143 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
145 ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
146 ; scheduling decisions for the load unit and the multiplier.
147 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_tune_strongarm")))
149 ; IS_XSCALE is set to 'yes' when compiling for XScale.
150 (define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
152 ;; Operand number of an input operand that is shifted. Zero if the
153 ;; given instruction does not shift one of its input operands.
154 (define_attr "shift" "" (const_int 0))
156 ; Floating Point Unit. If we only have floating point emulation, then there
157 ; is no point in scheduling the floating point insns. (Well, for best
158 ; performance we should try and group them together).
159 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
160 (const (symbol_ref "arm_fpu_attr")))
162 ; LENGTH of an instruction (in bytes)
163 (define_attr "length" "" (const_int 4))
165 ; POOL_RANGE is how far away from a constant pool entry that this insn
166 ; can be placed. If the distance is zero, then this insn will never
167 ; reference the pool.
168 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
169 ; before its address.
170 (define_attr "pool_range" "" (const_int 0))
171 (define_attr "neg_pool_range" "" (const_int 0))
173 ; An assembler sequence may clobber the condition codes without us knowing.
174 ; If such an insn references the pool, then we have no way of knowing how,
175 ; so use the most conservative value for pool_range.
176 (define_asm_attributes
177 [(set_attr "conds" "clob")
178 (set_attr "length" "4")
179 (set_attr "pool_range" "250")])
181 ;; The instruction used to implement a particular pattern. This
182 ;; information is used by pipeline descriptions to provide accurate
183 ;; scheduling information.
186 "mov,mvn,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,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,other"
187 (const_string "other"))
189 ; TYPE attribute is used to detect floating point instructions which, if
190 ; running on a co-processor can run in parallel with other, basic instructions
191 ; If write-buffer scheduling is enabled then it can also be used in the
192 ; scheduling of writes.
194 ; Classification of each insn
195 ; alu any alu instruction that doesn't hit memory or fp
196 ; regs or have a shifted source operand
197 ; alu_shift any data instruction that doesn't hit memory or fp
198 ; regs, but has a source operand shifted by a constant
199 ; alu_shift_reg any data instruction that doesn't hit memory or fp
200 ; regs, but has a source operand shifted by a register value
201 ; mult a multiply instruction
202 ; block blockage insn, this blocks all functional units
203 ; float a floating point arithmetic operation (subject to expansion)
204 ; fdivd DFmode floating point division
205 ; fdivs SFmode floating point division
206 ; fmul Floating point multiply
207 ; ffmul Fast floating point multiply
208 ; farith Floating point arithmetic (4 cycle)
209 ; ffarith Fast floating point arithmetic (2 cycle)
210 ; float_em a floating point arithmetic operation that is normally emulated
211 ; even on a machine with an fpa.
212 ; f_load a floating point load from memory
213 ; f_store a floating point store to memory
214 ; f_load[sd] single/double load from memory
215 ; f_store[sd] single/double store to memory
216 ; f_flag a transfer of co-processor flags to the CPSR
217 ; f_mem_r a transfer of a floating point register to a real reg via mem
218 ; r_mem_f the reverse of f_mem_r
219 ; f_2_r fast transfer float to arm (no memory needed)
220 ; r_2_f fast transfer arm to float
221 ; f_cvt convert floating<->integral
223 ; call a subroutine call
224 ; load_byte load byte(s) from memory to arm registers
225 ; load1 load 1 word from memory to arm registers
226 ; load2 load 2 words from memory to arm registers
227 ; load3 load 3 words from memory to arm registers
228 ; load4 load 4 words from memory to arm registers
229 ; store store 1 word to memory from arm registers
230 ; store2 store 2 words
231 ; store3 store 3 words
232 ; store4 store 4 (or more) words
233 ; Additions for Cirrus Maverick co-processor:
234 ; mav_farith Floating point arithmetic (4 cycle)
235 ; mav_dmult Double multiplies (7 cycle)
239 "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
241 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
242 (const_string "mult")
243 (const_string "alu")))
245 ; Load scheduling, set from the arm_ld_sched variable
246 ; initialized by arm_override_options()
247 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
249 ; condition codes: this one is used by final_prescan_insn to speed up
250 ; conditionalizing instructions. It saves having to scan the rtl to see if
251 ; it uses or alters the condition codes.
253 ; USE means that the condition codes are used by the insn in the process of
254 ; outputting code, this means (at present) that we can't use the insn in
257 ; SET means that the purpose of the insn is to set the condition codes in a
258 ; well defined manner.
260 ; CLOB means that the condition codes are altered in an undefined manner, if
261 ; they are altered at all
263 ; JUMP_CLOB is used when the condition cannot be represented by a single
264 ; instruction (UNEQ and LTGT). These cannot be predicated.
266 ; NOCOND means that the condition codes are neither altered nor affect the
267 ; output of this insn
269 (define_attr "conds" "use,set,clob,jump_clob,nocond"
270 (if_then_else (eq_attr "type" "call")
271 (const_string "clob")
272 (const_string "nocond")))
274 ; Predicable means that the insn can be conditionally executed based on
275 ; an automatically added predicate (additional patterns are generated by
276 ; gen...). We default to 'no' because no Thumb patterns match this rule
277 ; and not all ARM patterns do.
278 (define_attr "predicable" "no,yes" (const_string "no"))
280 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
281 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
282 ; suffer blockages enough to warrant modelling this (and it can adversely
283 ; affect the schedule).
284 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
286 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
287 ; to stall the processor. Used with model_wbuf above.
288 (define_attr "write_conflict" "no,yes"
289 (if_then_else (eq_attr "type"
290 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
292 (const_string "no")))
294 ; Classify the insns into those that take one cycle and those that take more
295 ; than one on the main cpu execution unit.
296 (define_attr "core_cycles" "single,multi"
297 (if_then_else (eq_attr "type"
298 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
299 (const_string "single")
300 (const_string "multi")))
302 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
303 ;; distant label. Only applicable to Thumb code.
304 (define_attr "far_jump" "yes,no" (const_string "no"))
307 ;; The number of machine instructions this pattern expands to.
308 ;; Used for Thumb-2 conditional execution.
309 (define_attr "ce_count" "" (const_int 1))
311 ;;---------------------------------------------------------------------------
314 ; A list of modes that are exactly 64 bits in size. We use this to expand
315 ; some splits that are the same for all modes when operating on ARM
317 (define_mode_iterator ANY64 [DI DF V8QI V4HI V2SI V2SF])
319 ;;---------------------------------------------------------------------------
322 (include "predicates.md")
323 (include "constraints.md")
325 ;;---------------------------------------------------------------------------
326 ;; Pipeline descriptions
328 ;; Processor type. This is created automatically from arm-cores.def.
329 (include "arm-tune.md")
331 ;; True if the generic scheduling description should be used.
333 (define_attr "generic_sched" "yes,no"
335 (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa8")
337 (const_string "yes"))))
339 (define_attr "generic_vfp" "yes,no"
341 (and (eq_attr "fpu" "vfp")
342 (eq_attr "tune" "!arm1020e,arm1022e,cortexa8"))
344 (const_string "no"))))
346 (include "arm-generic.md")
347 (include "arm926ejs.md")
348 (include "arm1020e.md")
349 (include "arm1026ejs.md")
350 (include "arm1136jfs.md")
351 (include "cortex-a8.md")
354 ;;---------------------------------------------------------------------------
359 ;; Note: For DImode insns, there is normally no reason why operands should
360 ;; not be in the same register, what we don't want is for something being
361 ;; written to partially overlap something that is an input.
362 ;; Cirrus 64bit additions should not be split because we have a native
363 ;; 64bit addition instructions.
365 (define_expand "adddi3"
367 [(set (match_operand:DI 0 "s_register_operand" "")
368 (plus:DI (match_operand:DI 1 "s_register_operand" "")
369 (match_operand:DI 2 "s_register_operand" "")))
370 (clobber (reg:CC CC_REGNUM))])]
373 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
375 if (!cirrus_fp_register (operands[0], DImode))
376 operands[0] = force_reg (DImode, operands[0]);
377 if (!cirrus_fp_register (operands[1], DImode))
378 operands[1] = force_reg (DImode, operands[1]);
379 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
385 if (GET_CODE (operands[1]) != REG)
386 operands[1] = force_reg (SImode, operands[1]);
387 if (GET_CODE (operands[2]) != REG)
388 operands[2] = force_reg (SImode, operands[2]);
393 (define_insn "*thumb1_adddi3"
394 [(set (match_operand:DI 0 "register_operand" "=l")
395 (plus:DI (match_operand:DI 1 "register_operand" "%0")
396 (match_operand:DI 2 "register_operand" "l")))
397 (clobber (reg:CC CC_REGNUM))
400 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
401 [(set_attr "length" "4")]
404 (define_insn_and_split "*arm_adddi3"
405 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
406 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
407 (match_operand:DI 2 "s_register_operand" "r, 0")))
408 (clobber (reg:CC CC_REGNUM))]
409 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
411 "TARGET_32BIT && 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 (match_dup 4) (match_dup 5))))]
420 operands[3] = gen_highpart (SImode, operands[0]);
421 operands[0] = gen_lowpart (SImode, operands[0]);
422 operands[4] = gen_highpart (SImode, operands[1]);
423 operands[1] = gen_lowpart (SImode, operands[1]);
424 operands[5] = gen_highpart (SImode, operands[2]);
425 operands[2] = gen_lowpart (SImode, operands[2]);
427 [(set_attr "conds" "clob")
428 (set_attr "length" "8")]
431 (define_insn_and_split "*adddi_sesidi_di"
432 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
433 (plus:DI (sign_extend:DI
434 (match_operand:SI 2 "s_register_operand" "r,r"))
435 (match_operand:DI 1 "s_register_operand" "r,0")))
436 (clobber (reg:CC CC_REGNUM))]
437 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
439 "TARGET_32BIT && reload_completed"
440 [(parallel [(set (reg:CC_C CC_REGNUM)
441 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
443 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
444 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
445 (plus:SI (ashiftrt:SI (match_dup 2)
450 operands[3] = gen_highpart (SImode, operands[0]);
451 operands[0] = gen_lowpart (SImode, operands[0]);
452 operands[4] = gen_highpart (SImode, operands[1]);
453 operands[1] = gen_lowpart (SImode, operands[1]);
454 operands[2] = gen_lowpart (SImode, operands[2]);
456 [(set_attr "conds" "clob")
457 (set_attr "length" "8")]
460 (define_insn_and_split "*adddi_zesidi_di"
461 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
462 (plus:DI (zero_extend:DI
463 (match_operand:SI 2 "s_register_operand" "r,r"))
464 (match_operand:DI 1 "s_register_operand" "r,0")))
465 (clobber (reg:CC CC_REGNUM))]
466 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
468 "TARGET_32BIT && reload_completed"
469 [(parallel [(set (reg:CC_C CC_REGNUM)
470 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
472 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
473 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
474 (plus:SI (match_dup 4) (const_int 0))))]
477 operands[3] = gen_highpart (SImode, operands[0]);
478 operands[0] = gen_lowpart (SImode, operands[0]);
479 operands[4] = gen_highpart (SImode, operands[1]);
480 operands[1] = gen_lowpart (SImode, operands[1]);
481 operands[2] = gen_lowpart (SImode, operands[2]);
483 [(set_attr "conds" "clob")
484 (set_attr "length" "8")]
487 (define_expand "addsi3"
488 [(set (match_operand:SI 0 "s_register_operand" "")
489 (plus:SI (match_operand:SI 1 "s_register_operand" "")
490 (match_operand:SI 2 "reg_or_int_operand" "")))]
493 if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
495 arm_split_constant (PLUS, SImode, NULL_RTX,
496 INTVAL (operands[2]), operands[0], operands[1],
497 optimize && can_create_pseudo_p ());
503 ; If there is a scratch available, this will be faster than synthesizing the
506 [(match_scratch:SI 3 "r")
507 (set (match_operand:SI 0 "arm_general_register_operand" "")
508 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
509 (match_operand:SI 2 "const_int_operand" "")))]
511 !(const_ok_for_arm (INTVAL (operands[2]))
512 || const_ok_for_arm (-INTVAL (operands[2])))
513 && const_ok_for_arm (~INTVAL (operands[2]))"
514 [(set (match_dup 3) (match_dup 2))
515 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
519 (define_insn_and_split "*arm_addsi3"
520 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
521 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
522 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
529 GET_CODE (operands[2]) == CONST_INT
530 && !(const_ok_for_arm (INTVAL (operands[2]))
531 || const_ok_for_arm (-INTVAL (operands[2])))"
532 [(clobber (const_int 0))]
534 arm_split_constant (PLUS, SImode, curr_insn,
535 INTVAL (operands[2]), operands[0],
539 [(set_attr "length" "4,4,16")
540 (set_attr "predicable" "yes")]
543 ;; Register group 'k' is a single register group containing only the stack
544 ;; register. Trying to reload it will always fail catastrophically,
545 ;; so never allow those alternatives to match if reloading is needed.
547 (define_insn "*thumb1_addsi3"
548 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
549 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
550 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
553 static const char * const asms[] =
555 \"add\\t%0, %0, %2\",
556 \"sub\\t%0, %0, #%n2\",
557 \"add\\t%0, %1, %2\",
558 \"add\\t%0, %0, %2\",
559 \"add\\t%0, %0, %2\",
560 \"add\\t%0, %1, %2\",
563 if ((which_alternative == 2 || which_alternative == 6)
564 && GET_CODE (operands[2]) == CONST_INT
565 && INTVAL (operands[2]) < 0)
566 return \"sub\\t%0, %1, #%n2\";
567 return asms[which_alternative];
569 [(set_attr "length" "2")]
572 ;; Reloading and elimination of the frame pointer can
573 ;; sometimes cause this optimization to be missed.
575 [(set (match_operand:SI 0 "arm_general_register_operand" "")
576 (match_operand:SI 1 "const_int_operand" ""))
578 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
580 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
581 && (INTVAL (operands[1]) & 3) == 0"
582 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
586 ;; ??? Make Thumb-2 variants which prefer low regs
587 (define_insn "*addsi3_compare0"
588 [(set (reg:CC_NOOV CC_REGNUM)
590 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
591 (match_operand:SI 2 "arm_add_operand" "rI,L"))
593 (set (match_operand:SI 0 "s_register_operand" "=r,r")
594 (plus:SI (match_dup 1) (match_dup 2)))]
598 sub%.\\t%0, %1, #%n2"
599 [(set_attr "conds" "set")]
602 (define_insn "*addsi3_compare0_scratch"
603 [(set (reg:CC_NOOV CC_REGNUM)
605 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
606 (match_operand:SI 1 "arm_add_operand" "rI,L"))
612 [(set_attr "conds" "set")]
615 (define_insn "*compare_negsi_si"
616 [(set (reg:CC_Z CC_REGNUM)
618 (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
619 (match_operand:SI 1 "s_register_operand" "r")))]
622 [(set_attr "conds" "set")]
625 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
626 ;; addend is a constant.
627 (define_insn "*cmpsi2_addneg"
628 [(set (reg:CC CC_REGNUM)
630 (match_operand:SI 1 "s_register_operand" "r,r")
631 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
632 (set (match_operand:SI 0 "s_register_operand" "=r,r")
633 (plus:SI (match_dup 1)
634 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
635 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
638 add%.\\t%0, %1, #%n2"
639 [(set_attr "conds" "set")]
642 ;; Convert the sequence
644 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
648 ;; bcs dest ((unsigned)rn >= 1)
649 ;; similarly for the beq variant using bcc.
650 ;; This is a common looping idiom (while (n--))
652 [(set (match_operand:SI 0 "arm_general_register_operand" "")
653 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
655 (set (match_operand 2 "cc_register" "")
656 (compare (match_dup 0) (const_int -1)))
658 (if_then_else (match_operator 3 "equality_operator"
659 [(match_dup 2) (const_int 0)])
660 (match_operand 4 "" "")
661 (match_operand 5 "" "")))]
662 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
666 (match_dup 1) (const_int 1)))
667 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
669 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
672 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
673 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
676 operands[2], const0_rtx);"
679 ;; The next four insns work because they compare the result with one of
680 ;; the operands, and we know that the use of the condition code is
681 ;; either GEU or LTU, so we can use the carry flag from the addition
682 ;; instead of doing the compare a second time.
683 (define_insn "*addsi3_compare_op1"
684 [(set (reg:CC_C CC_REGNUM)
686 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
687 (match_operand:SI 2 "arm_add_operand" "rI,L"))
689 (set (match_operand:SI 0 "s_register_operand" "=r,r")
690 (plus:SI (match_dup 1) (match_dup 2)))]
694 sub%.\\t%0, %1, #%n2"
695 [(set_attr "conds" "set")]
698 (define_insn "*addsi3_compare_op2"
699 [(set (reg:CC_C CC_REGNUM)
701 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
702 (match_operand:SI 2 "arm_add_operand" "rI,L"))
704 (set (match_operand:SI 0 "s_register_operand" "=r,r")
705 (plus:SI (match_dup 1) (match_dup 2)))]
709 sub%.\\t%0, %1, #%n2"
710 [(set_attr "conds" "set")]
713 (define_insn "*compare_addsi2_op0"
714 [(set (reg:CC_C CC_REGNUM)
716 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
717 (match_operand:SI 1 "arm_add_operand" "rI,L"))
723 [(set_attr "conds" "set")]
726 (define_insn "*compare_addsi2_op1"
727 [(set (reg:CC_C CC_REGNUM)
729 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
730 (match_operand:SI 1 "arm_add_operand" "rI,L"))
736 [(set_attr "conds" "set")]
739 (define_insn "*addsi3_carryin"
740 [(set (match_operand:SI 0 "s_register_operand" "=r")
741 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
742 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
743 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
746 [(set_attr "conds" "use")]
749 (define_insn "*addsi3_carryin_shift"
750 [(set (match_operand:SI 0 "s_register_operand" "=r")
751 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
753 (match_operator:SI 2 "shift_operator"
754 [(match_operand:SI 3 "s_register_operand" "r")
755 (match_operand:SI 4 "reg_or_int_operand" "rM")])
756 (match_operand:SI 1 "s_register_operand" "r"))))]
758 "adc%?\\t%0, %1, %3%S2"
759 [(set_attr "conds" "use")
760 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
761 (const_string "alu_shift")
762 (const_string "alu_shift_reg")))]
765 (define_insn "*addsi3_carryin_alt1"
766 [(set (match_operand:SI 0 "s_register_operand" "=r")
767 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
768 (match_operand:SI 2 "arm_rhs_operand" "rI"))
769 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
772 [(set_attr "conds" "use")]
775 (define_insn "*addsi3_carryin_alt2"
776 [(set (match_operand:SI 0 "s_register_operand" "=r")
777 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
778 (match_operand:SI 1 "s_register_operand" "r"))
779 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
782 [(set_attr "conds" "use")]
785 (define_insn "*addsi3_carryin_alt3"
786 [(set (match_operand:SI 0 "s_register_operand" "=r")
787 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
788 (match_operand:SI 2 "arm_rhs_operand" "rI"))
789 (match_operand:SI 1 "s_register_operand" "r")))]
792 [(set_attr "conds" "use")]
795 (define_expand "incscc"
796 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
797 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
798 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
799 (match_operand:SI 1 "s_register_operand" "0,?r")))]
804 (define_insn "*arm_incscc"
805 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
806 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
807 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
808 (match_operand:SI 1 "s_register_operand" "0,?r")))]
812 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
813 [(set_attr "conds" "use")
814 (set_attr "length" "4,8")]
817 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
819 [(set (match_operand:SI 0 "s_register_operand" "")
820 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
821 (match_operand:SI 2 "s_register_operand" ""))
823 (clobber (match_operand:SI 3 "s_register_operand" ""))]
825 [(set (match_dup 3) (match_dup 1))
826 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
828 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
831 (define_expand "addsf3"
832 [(set (match_operand:SF 0 "s_register_operand" "")
833 (plus:SF (match_operand:SF 1 "s_register_operand" "")
834 (match_operand:SF 2 "arm_float_add_operand" "")))]
835 "TARGET_32BIT && TARGET_HARD_FLOAT"
838 && !cirrus_fp_register (operands[2], SFmode))
839 operands[2] = force_reg (SFmode, operands[2]);
842 (define_expand "adddf3"
843 [(set (match_operand:DF 0 "s_register_operand" "")
844 (plus:DF (match_operand:DF 1 "s_register_operand" "")
845 (match_operand:DF 2 "arm_float_add_operand" "")))]
846 "TARGET_32BIT && TARGET_HARD_FLOAT"
849 && !cirrus_fp_register (operands[2], DFmode))
850 operands[2] = force_reg (DFmode, operands[2]);
853 (define_expand "subdi3"
855 [(set (match_operand:DI 0 "s_register_operand" "")
856 (minus:DI (match_operand:DI 1 "s_register_operand" "")
857 (match_operand:DI 2 "s_register_operand" "")))
858 (clobber (reg:CC CC_REGNUM))])]
861 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
863 && cirrus_fp_register (operands[0], DImode)
864 && cirrus_fp_register (operands[1], DImode))
866 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
872 if (GET_CODE (operands[1]) != REG)
873 operands[1] = force_reg (SImode, operands[1]);
874 if (GET_CODE (operands[2]) != REG)
875 operands[2] = force_reg (SImode, operands[2]);
880 (define_insn "*arm_subdi3"
881 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
882 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
883 (match_operand:DI 2 "s_register_operand" "r,0,0")))
884 (clobber (reg:CC CC_REGNUM))]
886 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
887 [(set_attr "conds" "clob")
888 (set_attr "length" "8")]
891 (define_insn "*thumb_subdi3"
892 [(set (match_operand:DI 0 "register_operand" "=l")
893 (minus:DI (match_operand:DI 1 "register_operand" "0")
894 (match_operand:DI 2 "register_operand" "l")))
895 (clobber (reg:CC CC_REGNUM))]
897 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
898 [(set_attr "length" "4")]
901 (define_insn "*subdi_di_zesidi"
902 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
903 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
905 (match_operand:SI 2 "s_register_operand" "r,r"))))
906 (clobber (reg:CC CC_REGNUM))]
908 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
909 [(set_attr "conds" "clob")
910 (set_attr "length" "8")]
913 (define_insn "*subdi_di_sesidi"
914 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
915 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
917 (match_operand:SI 2 "s_register_operand" "r,r"))))
918 (clobber (reg:CC CC_REGNUM))]
920 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
921 [(set_attr "conds" "clob")
922 (set_attr "length" "8")]
925 (define_insn "*subdi_zesidi_di"
926 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
927 (minus:DI (zero_extend:DI
928 (match_operand:SI 2 "s_register_operand" "r,r"))
929 (match_operand:DI 1 "s_register_operand" "?r,0")))
930 (clobber (reg:CC CC_REGNUM))]
932 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
933 [(set_attr "conds" "clob")
934 (set_attr "length" "8")]
937 (define_insn "*subdi_sesidi_di"
938 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
939 (minus:DI (sign_extend:DI
940 (match_operand:SI 2 "s_register_operand" "r,r"))
941 (match_operand:DI 1 "s_register_operand" "?r,0")))
942 (clobber (reg:CC CC_REGNUM))]
944 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
945 [(set_attr "conds" "clob")
946 (set_attr "length" "8")]
949 (define_insn "*subdi_zesidi_zesidi"
950 [(set (match_operand:DI 0 "s_register_operand" "=r")
951 (minus:DI (zero_extend:DI
952 (match_operand:SI 1 "s_register_operand" "r"))
954 (match_operand:SI 2 "s_register_operand" "r"))))
955 (clobber (reg:CC CC_REGNUM))]
957 "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
958 [(set_attr "conds" "clob")
959 (set_attr "length" "8")]
962 (define_expand "subsi3"
963 [(set (match_operand:SI 0 "s_register_operand" "")
964 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
965 (match_operand:SI 2 "s_register_operand" "")))]
968 if (GET_CODE (operands[1]) == CONST_INT)
972 arm_split_constant (MINUS, SImode, NULL_RTX,
973 INTVAL (operands[1]), operands[0],
974 operands[2], optimize && can_create_pseudo_p ());
977 else /* TARGET_THUMB1 */
978 operands[1] = force_reg (SImode, operands[1]);
983 (define_insn "*thumb1_subsi3_insn"
984 [(set (match_operand:SI 0 "register_operand" "=l")
985 (minus:SI (match_operand:SI 1 "register_operand" "l")
986 (match_operand:SI 2 "register_operand" "l")))]
989 [(set_attr "length" "2")]
992 ; ??? Check Thumb-2 split length
993 (define_insn_and_split "*arm_subsi3_insn"
994 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
995 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
996 (match_operand:SI 2 "s_register_operand" "r,r")))]
1002 && GET_CODE (operands[1]) == CONST_INT
1003 && !const_ok_for_arm (INTVAL (operands[1]))"
1004 [(clobber (const_int 0))]
1006 arm_split_constant (MINUS, SImode, curr_insn,
1007 INTVAL (operands[1]), operands[0], operands[2], 0);
1010 [(set_attr "length" "4,16")
1011 (set_attr "predicable" "yes")]
1015 [(match_scratch:SI 3 "r")
1016 (set (match_operand:SI 0 "arm_general_register_operand" "")
1017 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1018 (match_operand:SI 2 "arm_general_register_operand" "")))]
1020 && !const_ok_for_arm (INTVAL (operands[1]))
1021 && const_ok_for_arm (~INTVAL (operands[1]))"
1022 [(set (match_dup 3) (match_dup 1))
1023 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1027 (define_insn "*subsi3_compare0"
1028 [(set (reg:CC_NOOV CC_REGNUM)
1030 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1031 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1033 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1034 (minus:SI (match_dup 1) (match_dup 2)))]
1039 [(set_attr "conds" "set")]
1042 (define_expand "decscc"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1044 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1045 (match_operator:SI 2 "arm_comparison_operator"
1046 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1051 (define_insn "*arm_decscc"
1052 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1053 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1054 (match_operator:SI 2 "arm_comparison_operator"
1055 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1059 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1060 [(set_attr "conds" "use")
1061 (set_attr "length" "*,8")]
1064 (define_expand "subsf3"
1065 [(set (match_operand:SF 0 "s_register_operand" "")
1066 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1067 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1068 "TARGET_32BIT && TARGET_HARD_FLOAT"
1070 if (TARGET_MAVERICK)
1072 if (!cirrus_fp_register (operands[1], SFmode))
1073 operands[1] = force_reg (SFmode, operands[1]);
1074 if (!cirrus_fp_register (operands[2], SFmode))
1075 operands[2] = force_reg (SFmode, operands[2]);
1079 (define_expand "subdf3"
1080 [(set (match_operand:DF 0 "s_register_operand" "")
1081 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1082 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1083 "TARGET_32BIT && TARGET_HARD_FLOAT"
1085 if (TARGET_MAVERICK)
1087 if (!cirrus_fp_register (operands[1], DFmode))
1088 operands[1] = force_reg (DFmode, operands[1]);
1089 if (!cirrus_fp_register (operands[2], DFmode))
1090 operands[2] = force_reg (DFmode, operands[2]);
1095 ;; Multiplication insns
1097 (define_expand "mulsi3"
1098 [(set (match_operand:SI 0 "s_register_operand" "")
1099 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1100 (match_operand:SI 1 "s_register_operand" "")))]
1105 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1106 (define_insn "*arm_mulsi3"
1107 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1108 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1109 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1110 "TARGET_32BIT && !arm_arch6"
1111 "mul%?\\t%0, %2, %1"
1112 [(set_attr "insn" "mul")
1113 (set_attr "predicable" "yes")]
1116 (define_insn "*arm_mulsi3_v6"
1117 [(set (match_operand:SI 0 "s_register_operand" "=r")
1118 (mult:SI (match_operand:SI 1 "s_register_operand" "r")
1119 (match_operand:SI 2 "s_register_operand" "r")))]
1120 "TARGET_32BIT && arm_arch6"
1121 "mul%?\\t%0, %1, %2"
1122 [(set_attr "insn" "mul")
1123 (set_attr "predicable" "yes")]
1126 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1127 ; 1 and 2; are the same, because reload will make operand 0 match
1128 ; operand 1 without realizing that this conflicts with operand 2. We fix
1129 ; this by adding another alternative to match this case, and then `reload'
1130 ; it ourselves. This alternative must come first.
1131 (define_insn "*thumb_mulsi3"
1132 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1133 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1134 (match_operand:SI 2 "register_operand" "l,l,l")))]
1135 "TARGET_THUMB1 && !arm_arch6"
1137 if (which_alternative < 2)
1138 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1140 return \"mul\\t%0, %2\";
1142 [(set_attr "length" "4,4,2")
1143 (set_attr "insn" "mul")]
1146 (define_insn "*thumb_mulsi3_v6"
1147 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1148 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1149 (match_operand:SI 2 "register_operand" "l,0,0")))]
1150 "TARGET_THUMB1 && arm_arch6"
1155 [(set_attr "length" "2")
1156 (set_attr "insn" "mul")]
1159 (define_insn "*mulsi3_compare0"
1160 [(set (reg:CC_NOOV CC_REGNUM)
1161 (compare:CC_NOOV (mult:SI
1162 (match_operand:SI 2 "s_register_operand" "r,r")
1163 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1165 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1166 (mult:SI (match_dup 2) (match_dup 1)))]
1167 "TARGET_ARM && !arm_arch6"
1168 "mul%.\\t%0, %2, %1"
1169 [(set_attr "conds" "set")
1170 (set_attr "insn" "muls")]
1173 (define_insn "*mulsi3_compare0_v6"
1174 [(set (reg:CC_NOOV CC_REGNUM)
1175 (compare:CC_NOOV (mult:SI
1176 (match_operand:SI 2 "s_register_operand" "r")
1177 (match_operand:SI 1 "s_register_operand" "r"))
1179 (set (match_operand:SI 0 "s_register_operand" "=r")
1180 (mult:SI (match_dup 2) (match_dup 1)))]
1181 "TARGET_ARM && arm_arch6 && optimize_size"
1182 "mul%.\\t%0, %2, %1"
1183 [(set_attr "conds" "set")
1184 (set_attr "insn" "muls")]
1187 (define_insn "*mulsi_compare0_scratch"
1188 [(set (reg:CC_NOOV CC_REGNUM)
1189 (compare:CC_NOOV (mult:SI
1190 (match_operand:SI 2 "s_register_operand" "r,r")
1191 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1193 (clobber (match_scratch:SI 0 "=&r,&r"))]
1194 "TARGET_ARM && !arm_arch6"
1195 "mul%.\\t%0, %2, %1"
1196 [(set_attr "conds" "set")
1197 (set_attr "insn" "muls")]
1200 (define_insn "*mulsi_compare0_scratch_v6"
1201 [(set (reg:CC_NOOV CC_REGNUM)
1202 (compare:CC_NOOV (mult:SI
1203 (match_operand:SI 2 "s_register_operand" "r")
1204 (match_operand:SI 1 "s_register_operand" "r"))
1206 (clobber (match_scratch:SI 0 "=r"))]
1207 "TARGET_ARM && arm_arch6 && optimize_size"
1208 "mul%.\\t%0, %2, %1"
1209 [(set_attr "conds" "set")
1210 (set_attr "insn" "muls")]
1213 ;; Unnamed templates to match MLA instruction.
1215 (define_insn "*mulsi3addsi"
1216 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1218 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1219 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1220 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1221 "TARGET_32BIT && !arm_arch6"
1222 "mla%?\\t%0, %2, %1, %3"
1223 [(set_attr "insn" "mla")
1224 (set_attr "predicable" "yes")]
1227 (define_insn "*mulsi3addsi_v6"
1228 [(set (match_operand:SI 0 "s_register_operand" "=r")
1230 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1231 (match_operand:SI 1 "s_register_operand" "r"))
1232 (match_operand:SI 3 "s_register_operand" "r")))]
1233 "TARGET_32BIT && arm_arch6"
1234 "mla%?\\t%0, %2, %1, %3"
1235 [(set_attr "insn" "mla")
1236 (set_attr "predicable" "yes")]
1239 (define_insn "*mulsi3addsi_compare0"
1240 [(set (reg:CC_NOOV CC_REGNUM)
1243 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1244 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1245 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1247 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1248 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1250 "TARGET_ARM && arm_arch6"
1251 "mla%.\\t%0, %2, %1, %3"
1252 [(set_attr "conds" "set")
1253 (set_attr "insn" "mlas")]
1256 (define_insn "*mulsi3addsi_compare0_v6"
1257 [(set (reg:CC_NOOV CC_REGNUM)
1260 (match_operand:SI 2 "s_register_operand" "r")
1261 (match_operand:SI 1 "s_register_operand" "r"))
1262 (match_operand:SI 3 "s_register_operand" "r"))
1264 (set (match_operand:SI 0 "s_register_operand" "=r")
1265 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1267 "TARGET_ARM && arm_arch6 && optimize_size"
1268 "mla%.\\t%0, %2, %1, %3"
1269 [(set_attr "conds" "set")
1270 (set_attr "insn" "mlas")]
1273 (define_insn "*mulsi3addsi_compare0_scratch"
1274 [(set (reg:CC_NOOV CC_REGNUM)
1277 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1278 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1279 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1281 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1282 "TARGET_ARM && !arm_arch6"
1283 "mla%.\\t%0, %2, %1, %3"
1284 [(set_attr "conds" "set")
1285 (set_attr "insn" "mlas")]
1288 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1289 [(set (reg:CC_NOOV CC_REGNUM)
1292 (match_operand:SI 2 "s_register_operand" "r")
1293 (match_operand:SI 1 "s_register_operand" "r"))
1294 (match_operand:SI 3 "s_register_operand" "r"))
1296 (clobber (match_scratch:SI 0 "=r"))]
1297 "TARGET_ARM && arm_arch6 && optimize_size"
1298 "mla%.\\t%0, %2, %1, %3"
1299 [(set_attr "conds" "set")
1300 (set_attr "insn" "mlas")]
1303 (define_insn "*mulsi3subsi"
1304 [(set (match_operand:SI 0 "s_register_operand" "=r")
1306 (match_operand:SI 3 "s_register_operand" "r")
1307 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1308 (match_operand:SI 1 "s_register_operand" "r"))))]
1309 "TARGET_32BIT && arm_arch_thumb2"
1310 "mls%?\\t%0, %2, %1, %3"
1311 [(set_attr "insn" "mla")
1312 (set_attr "predicable" "yes")]
1315 ;; Unnamed template to match long long multiply-accumulate (smlal)
1317 (define_insn "*mulsidi3adddi"
1318 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1321 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1322 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1323 (match_operand:DI 1 "s_register_operand" "0")))]
1324 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1325 "smlal%?\\t%Q0, %R0, %3, %2"
1326 [(set_attr "insn" "smlal")
1327 (set_attr "predicable" "yes")]
1330 (define_insn "*mulsidi3adddi_v6"
1331 [(set (match_operand:DI 0 "s_register_operand" "=r")
1334 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1335 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1336 (match_operand:DI 1 "s_register_operand" "0")))]
1337 "TARGET_32BIT && arm_arch6"
1338 "smlal%?\\t%Q0, %R0, %3, %2"
1339 [(set_attr "insn" "smlal")
1340 (set_attr "predicable" "yes")]
1343 ;; 32x32->64 widening multiply.
1344 ;; As with mulsi3, the only difference between the v3-5 and v6+
1345 ;; versions of these patterns is the requirement that the output not
1346 ;; overlap the inputs, but that still means we have to have a named
1347 ;; expander and two different starred insns.
1349 (define_expand "mulsidi3"
1350 [(set (match_operand:DI 0 "s_register_operand" "")
1352 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1353 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1354 "TARGET_32BIT && arm_arch3m"
1358 (define_insn "*mulsidi3_nov6"
1359 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1361 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1362 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1363 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1364 "smull%?\\t%Q0, %R0, %1, %2"
1365 [(set_attr "insn" "smull")
1366 (set_attr "predicable" "yes")]
1369 (define_insn "*mulsidi3_v6"
1370 [(set (match_operand:DI 0 "s_register_operand" "=r")
1372 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1373 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1374 "TARGET_32BIT && arm_arch6"
1375 "smull%?\\t%Q0, %R0, %1, %2"
1376 [(set_attr "insn" "smull")
1377 (set_attr "predicable" "yes")]
1380 (define_expand "umulsidi3"
1381 [(set (match_operand:DI 0 "s_register_operand" "")
1383 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1384 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1385 "TARGET_32BIT && arm_arch3m"
1389 (define_insn "*umulsidi3_nov6"
1390 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1392 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1393 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1394 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1395 "umull%?\\t%Q0, %R0, %1, %2"
1396 [(set_attr "insn" "umull")
1397 (set_attr "predicable" "yes")]
1400 (define_insn "*umulsidi3_v6"
1401 [(set (match_operand:DI 0 "s_register_operand" "=r")
1403 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1404 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1405 "TARGET_32BIT && arm_arch6"
1406 "umull%?\\t%Q0, %R0, %1, %2"
1407 [(set_attr "insn" "umull")
1408 (set_attr "predicable" "yes")]
1411 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1413 (define_insn "*umulsidi3adddi"
1414 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1417 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1418 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1419 (match_operand:DI 1 "s_register_operand" "0")))]
1420 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1421 "umlal%?\\t%Q0, %R0, %3, %2"
1422 [(set_attr "insn" "umlal")
1423 (set_attr "predicable" "yes")]
1426 (define_insn "*umulsidi3adddi_v6"
1427 [(set (match_operand:DI 0 "s_register_operand" "=r")
1430 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1431 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1432 (match_operand:DI 1 "s_register_operand" "0")))]
1433 "TARGET_32BIT && arm_arch6"
1434 "umlal%?\\t%Q0, %R0, %3, %2"
1435 [(set_attr "insn" "umlal")
1436 (set_attr "predicable" "yes")]
1439 (define_expand "smulsi3_highpart"
1441 [(set (match_operand:SI 0 "s_register_operand" "")
1445 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1446 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1448 (clobber (match_scratch:SI 3 ""))])]
1449 "TARGET_32BIT && arm_arch3m"
1453 (define_insn "*smulsi3_highpart_nov6"
1454 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1458 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1459 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1461 (clobber (match_scratch:SI 3 "=&r,&r"))]
1462 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1463 "smull%?\\t%3, %0, %2, %1"
1464 [(set_attr "insn" "smull")
1465 (set_attr "predicable" "yes")]
1468 (define_insn "*smulsi3_highpart_v6"
1469 [(set (match_operand:SI 0 "s_register_operand" "=r")
1473 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1474 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1476 (clobber (match_scratch:SI 3 "=r"))]
1477 "TARGET_32BIT && arm_arch6"
1478 "smull%?\\t%3, %0, %2, %1"
1479 [(set_attr "insn" "smull")
1480 (set_attr "predicable" "yes")]
1483 (define_expand "umulsi3_highpart"
1485 [(set (match_operand:SI 0 "s_register_operand" "")
1489 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1490 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1492 (clobber (match_scratch:SI 3 ""))])]
1493 "TARGET_32BIT && arm_arch3m"
1497 (define_insn "*umulsi3_highpart_nov6"
1498 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1502 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1503 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1505 (clobber (match_scratch:SI 3 "=&r,&r"))]
1506 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1507 "umull%?\\t%3, %0, %2, %1"
1508 [(set_attr "insn" "umull")
1509 (set_attr "predicable" "yes")]
1512 (define_insn "*umulsi3_highpart_v6"
1513 [(set (match_operand:SI 0 "s_register_operand" "=r")
1517 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1518 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1520 (clobber (match_scratch:SI 3 "=r"))]
1521 "TARGET_32BIT && arm_arch6"
1522 "umull%?\\t%3, %0, %2, %1"
1523 [(set_attr "insn" "umull")
1524 (set_attr "predicable" "yes")]
1527 (define_insn "mulhisi3"
1528 [(set (match_operand:SI 0 "s_register_operand" "=r")
1529 (mult:SI (sign_extend:SI
1530 (match_operand:HI 1 "s_register_operand" "%r"))
1532 (match_operand:HI 2 "s_register_operand" "r"))))]
1533 "TARGET_DSP_MULTIPLY"
1534 "smulbb%?\\t%0, %1, %2"
1535 [(set_attr "insn" "smulxy")
1536 (set_attr "predicable" "yes")]
1539 (define_insn "*mulhisi3tb"
1540 [(set (match_operand:SI 0 "s_register_operand" "=r")
1541 (mult:SI (ashiftrt:SI
1542 (match_operand:SI 1 "s_register_operand" "r")
1545 (match_operand:HI 2 "s_register_operand" "r"))))]
1546 "TARGET_DSP_MULTIPLY"
1547 "smultb%?\\t%0, %1, %2"
1548 [(set_attr "insn" "smulxy")
1549 (set_attr "predicable" "yes")]
1552 (define_insn "*mulhisi3bt"
1553 [(set (match_operand:SI 0 "s_register_operand" "=r")
1554 (mult:SI (sign_extend:SI
1555 (match_operand:HI 1 "s_register_operand" "r"))
1557 (match_operand:SI 2 "s_register_operand" "r")
1559 "TARGET_DSP_MULTIPLY"
1560 "smulbt%?\\t%0, %1, %2"
1561 [(set_attr "insn" "smulxy")
1562 (set_attr "predicable" "yes")]
1565 (define_insn "*mulhisi3tt"
1566 [(set (match_operand:SI 0 "s_register_operand" "=r")
1567 (mult:SI (ashiftrt:SI
1568 (match_operand:SI 1 "s_register_operand" "r")
1571 (match_operand:SI 2 "s_register_operand" "r")
1573 "TARGET_DSP_MULTIPLY"
1574 "smultt%?\\t%0, %1, %2"
1575 [(set_attr "insn" "smulxy")
1576 (set_attr "predicable" "yes")]
1579 (define_insn "*mulhisi3addsi"
1580 [(set (match_operand:SI 0 "s_register_operand" "=r")
1581 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1582 (mult:SI (sign_extend:SI
1583 (match_operand:HI 2 "s_register_operand" "%r"))
1585 (match_operand:HI 3 "s_register_operand" "r")))))]
1586 "TARGET_DSP_MULTIPLY"
1587 "smlabb%?\\t%0, %2, %3, %1"
1588 [(set_attr "insn" "smlaxy")
1589 (set_attr "predicable" "yes")]
1592 (define_insn "*mulhidi3adddi"
1593 [(set (match_operand:DI 0 "s_register_operand" "=r")
1595 (match_operand:DI 1 "s_register_operand" "0")
1596 (mult:DI (sign_extend:DI
1597 (match_operand:HI 2 "s_register_operand" "%r"))
1599 (match_operand:HI 3 "s_register_operand" "r")))))]
1600 "TARGET_DSP_MULTIPLY"
1601 "smlalbb%?\\t%Q0, %R0, %2, %3"
1602 [(set_attr "insn" "smlalxy")
1603 (set_attr "predicable" "yes")])
1605 (define_expand "mulsf3"
1606 [(set (match_operand:SF 0 "s_register_operand" "")
1607 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1608 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1609 "TARGET_32BIT && TARGET_HARD_FLOAT"
1612 && !cirrus_fp_register (operands[2], SFmode))
1613 operands[2] = force_reg (SFmode, operands[2]);
1616 (define_expand "muldf3"
1617 [(set (match_operand:DF 0 "s_register_operand" "")
1618 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1619 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1620 "TARGET_32BIT && TARGET_HARD_FLOAT"
1623 && !cirrus_fp_register (operands[2], DFmode))
1624 operands[2] = force_reg (DFmode, operands[2]);
1629 (define_expand "divsf3"
1630 [(set (match_operand:SF 0 "s_register_operand" "")
1631 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1632 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1633 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1636 (define_expand "divdf3"
1637 [(set (match_operand:DF 0 "s_register_operand" "")
1638 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1639 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1640 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1645 (define_expand "modsf3"
1646 [(set (match_operand:SF 0 "s_register_operand" "")
1647 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1648 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1649 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1652 (define_expand "moddf3"
1653 [(set (match_operand:DF 0 "s_register_operand" "")
1654 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1655 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1656 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1659 ;; Boolean and,ior,xor insns
1661 ;; Split up double word logical operations
1663 ;; Split up simple DImode logical operations. Simply perform the logical
1664 ;; operation on the upper and lower halves of the registers.
1666 [(set (match_operand:DI 0 "s_register_operand" "")
1667 (match_operator:DI 6 "logical_binary_operator"
1668 [(match_operand:DI 1 "s_register_operand" "")
1669 (match_operand:DI 2 "s_register_operand" "")]))]
1670 "TARGET_32BIT && reload_completed
1671 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1672 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1673 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1676 operands[3] = gen_highpart (SImode, operands[0]);
1677 operands[0] = gen_lowpart (SImode, operands[0]);
1678 operands[4] = gen_highpart (SImode, operands[1]);
1679 operands[1] = gen_lowpart (SImode, operands[1]);
1680 operands[5] = gen_highpart (SImode, operands[2]);
1681 operands[2] = gen_lowpart (SImode, operands[2]);
1686 [(set (match_operand:DI 0 "s_register_operand" "")
1687 (match_operator:DI 6 "logical_binary_operator"
1688 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1689 (match_operand:DI 1 "s_register_operand" "")]))]
1690 "TARGET_32BIT && reload_completed"
1691 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1692 (set (match_dup 3) (match_op_dup:SI 6
1693 [(ashiftrt:SI (match_dup 2) (const_int 31))
1697 operands[3] = gen_highpart (SImode, operands[0]);
1698 operands[0] = gen_lowpart (SImode, operands[0]);
1699 operands[4] = gen_highpart (SImode, operands[1]);
1700 operands[1] = gen_lowpart (SImode, operands[1]);
1701 operands[5] = gen_highpart (SImode, operands[2]);
1702 operands[2] = gen_lowpart (SImode, operands[2]);
1706 ;; The zero extend of operand 2 means we can just copy the high part of
1707 ;; operand1 into operand0.
1709 [(set (match_operand:DI 0 "s_register_operand" "")
1711 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1712 (match_operand:DI 1 "s_register_operand" "")))]
1713 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1714 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1715 (set (match_dup 3) (match_dup 4))]
1718 operands[4] = gen_highpart (SImode, operands[1]);
1719 operands[3] = gen_highpart (SImode, operands[0]);
1720 operands[0] = gen_lowpart (SImode, operands[0]);
1721 operands[1] = gen_lowpart (SImode, operands[1]);
1725 ;; The zero extend of operand 2 means we can just copy the high part of
1726 ;; operand1 into operand0.
1728 [(set (match_operand:DI 0 "s_register_operand" "")
1730 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1731 (match_operand:DI 1 "s_register_operand" "")))]
1732 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1733 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1734 (set (match_dup 3) (match_dup 4))]
1737 operands[4] = gen_highpart (SImode, operands[1]);
1738 operands[3] = gen_highpart (SImode, operands[0]);
1739 operands[0] = gen_lowpart (SImode, operands[0]);
1740 operands[1] = gen_lowpart (SImode, operands[1]);
1744 (define_insn "anddi3"
1745 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1746 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1747 (match_operand:DI 2 "s_register_operand" "r,r")))]
1748 "TARGET_32BIT && ! TARGET_IWMMXT"
1750 [(set_attr "length" "8")]
1753 (define_insn_and_split "*anddi_zesidi_di"
1754 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1755 (and:DI (zero_extend:DI
1756 (match_operand:SI 2 "s_register_operand" "r,r"))
1757 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1760 "TARGET_32BIT && reload_completed"
1761 ; The zero extend of operand 2 clears the high word of the output
1763 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1764 (set (match_dup 3) (const_int 0))]
1767 operands[3] = gen_highpart (SImode, operands[0]);
1768 operands[0] = gen_lowpart (SImode, operands[0]);
1769 operands[1] = gen_lowpart (SImode, operands[1]);
1771 [(set_attr "length" "8")]
1774 (define_insn "*anddi_sesdi_di"
1775 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1776 (and:DI (sign_extend:DI
1777 (match_operand:SI 2 "s_register_operand" "r,r"))
1778 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1781 [(set_attr "length" "8")]
1784 (define_expand "andsi3"
1785 [(set (match_operand:SI 0 "s_register_operand" "")
1786 (and:SI (match_operand:SI 1 "s_register_operand" "")
1787 (match_operand:SI 2 "reg_or_int_operand" "")))]
1792 if (GET_CODE (operands[2]) == CONST_INT)
1794 arm_split_constant (AND, SImode, NULL_RTX,
1795 INTVAL (operands[2]), operands[0],
1796 operands[1], optimize && can_create_pseudo_p ());
1801 else /* TARGET_THUMB1 */
1803 if (GET_CODE (operands[2]) != CONST_INT)
1804 operands[2] = force_reg (SImode, operands[2]);
1809 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1811 operands[2] = force_reg (SImode,
1812 GEN_INT (~INTVAL (operands[2])));
1814 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1819 for (i = 9; i <= 31; i++)
1821 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1823 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1827 else if ((((HOST_WIDE_INT) 1) << i) - 1
1828 == ~INTVAL (operands[2]))
1830 rtx shift = GEN_INT (i);
1831 rtx reg = gen_reg_rtx (SImode);
1833 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1834 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1840 operands[2] = force_reg (SImode, operands[2]);
1846 ; ??? Check split length for Thumb-2
1847 (define_insn_and_split "*arm_andsi3_insn"
1848 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1849 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1850 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1854 bic%?\\t%0, %1, #%B2
1857 && GET_CODE (operands[2]) == CONST_INT
1858 && !(const_ok_for_arm (INTVAL (operands[2]))
1859 || const_ok_for_arm (~INTVAL (operands[2])))"
1860 [(clobber (const_int 0))]
1862 arm_split_constant (AND, SImode, curr_insn,
1863 INTVAL (operands[2]), operands[0], operands[1], 0);
1866 [(set_attr "length" "4,4,16")
1867 (set_attr "predicable" "yes")]
1870 (define_insn "*thumb1_andsi3_insn"
1871 [(set (match_operand:SI 0 "register_operand" "=l")
1872 (and:SI (match_operand:SI 1 "register_operand" "%0")
1873 (match_operand:SI 2 "register_operand" "l")))]
1876 [(set_attr "length" "2")]
1879 (define_insn "*andsi3_compare0"
1880 [(set (reg:CC_NOOV CC_REGNUM)
1882 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1883 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1885 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1886 (and:SI (match_dup 1) (match_dup 2)))]
1890 bic%.\\t%0, %1, #%B2"
1891 [(set_attr "conds" "set")]
1894 (define_insn "*andsi3_compare0_scratch"
1895 [(set (reg:CC_NOOV CC_REGNUM)
1897 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1898 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1900 (clobber (match_scratch:SI 2 "=X,r"))]
1904 bic%.\\t%2, %0, #%B1"
1905 [(set_attr "conds" "set")]
1908 (define_insn "*zeroextractsi_compare0_scratch"
1909 [(set (reg:CC_NOOV CC_REGNUM)
1910 (compare:CC_NOOV (zero_extract:SI
1911 (match_operand:SI 0 "s_register_operand" "r")
1912 (match_operand 1 "const_int_operand" "n")
1913 (match_operand 2 "const_int_operand" "n"))
1916 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1917 && INTVAL (operands[1]) > 0
1918 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1919 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1921 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1922 << INTVAL (operands[2]));
1923 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1926 [(set_attr "conds" "set")]
1929 (define_insn_and_split "*ne_zeroextractsi"
1930 [(set (match_operand:SI 0 "s_register_operand" "=r")
1931 (ne:SI (zero_extract:SI
1932 (match_operand:SI 1 "s_register_operand" "r")
1933 (match_operand:SI 2 "const_int_operand" "n")
1934 (match_operand:SI 3 "const_int_operand" "n"))
1936 (clobber (reg:CC CC_REGNUM))]
1938 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1939 && INTVAL (operands[2]) > 0
1940 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1941 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1944 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1945 && INTVAL (operands[2]) > 0
1946 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1947 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1948 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1949 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1951 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1953 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1954 (match_dup 0) (const_int 1)))]
1956 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1957 << INTVAL (operands[3]));
1959 [(set_attr "conds" "clob")
1960 (set (attr "length")
1961 (if_then_else (eq_attr "is_thumb" "yes")
1966 (define_insn_and_split "*ne_zeroextractsi_shifted"
1967 [(set (match_operand:SI 0 "s_register_operand" "=r")
1968 (ne:SI (zero_extract:SI
1969 (match_operand:SI 1 "s_register_operand" "r")
1970 (match_operand:SI 2 "const_int_operand" "n")
1973 (clobber (reg:CC CC_REGNUM))]
1977 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1978 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1980 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1982 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1983 (match_dup 0) (const_int 1)))]
1985 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1987 [(set_attr "conds" "clob")
1988 (set_attr "length" "8")]
1991 (define_insn_and_split "*ite_ne_zeroextractsi"
1992 [(set (match_operand:SI 0 "s_register_operand" "=r")
1993 (if_then_else:SI (ne (zero_extract:SI
1994 (match_operand:SI 1 "s_register_operand" "r")
1995 (match_operand:SI 2 "const_int_operand" "n")
1996 (match_operand:SI 3 "const_int_operand" "n"))
1998 (match_operand:SI 4 "arm_not_operand" "rIK")
2000 (clobber (reg:CC CC_REGNUM))]
2002 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2003 && INTVAL (operands[2]) > 0
2004 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2005 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2006 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2009 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2010 && INTVAL (operands[2]) > 0
2011 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2012 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2013 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2014 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2015 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2017 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2019 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2020 (match_dup 0) (match_dup 4)))]
2022 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2023 << INTVAL (operands[3]));
2025 [(set_attr "conds" "clob")
2026 (set_attr "length" "8")]
2029 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2030 [(set (match_operand:SI 0 "s_register_operand" "=r")
2031 (if_then_else:SI (ne (zero_extract:SI
2032 (match_operand:SI 1 "s_register_operand" "r")
2033 (match_operand:SI 2 "const_int_operand" "n")
2036 (match_operand:SI 3 "arm_not_operand" "rIK")
2038 (clobber (reg:CC CC_REGNUM))]
2039 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2041 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2042 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2043 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2045 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2047 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2048 (match_dup 0) (match_dup 3)))]
2050 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2052 [(set_attr "conds" "clob")
2053 (set_attr "length" "8")]
2057 [(set (match_operand:SI 0 "s_register_operand" "")
2058 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2059 (match_operand:SI 2 "const_int_operand" "")
2060 (match_operand:SI 3 "const_int_operand" "")))
2061 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2063 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2064 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2066 HOST_WIDE_INT temp = INTVAL (operands[2]);
2068 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2069 operands[3] = GEN_INT (32 - temp);
2073 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2075 [(set (match_operand:SI 0 "s_register_operand" "")
2076 (match_operator:SI 1 "shiftable_operator"
2077 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2078 (match_operand:SI 3 "const_int_operand" "")
2079 (match_operand:SI 4 "const_int_operand" ""))
2080 (match_operand:SI 5 "s_register_operand" "")]))
2081 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2083 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2086 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2089 HOST_WIDE_INT temp = INTVAL (operands[3]);
2091 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2092 operands[4] = GEN_INT (32 - temp);
2097 [(set (match_operand:SI 0 "s_register_operand" "")
2098 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2099 (match_operand:SI 2 "const_int_operand" "")
2100 (match_operand:SI 3 "const_int_operand" "")))]
2102 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2103 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2105 HOST_WIDE_INT temp = INTVAL (operands[2]);
2107 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2108 operands[3] = GEN_INT (32 - temp);
2113 [(set (match_operand:SI 0 "s_register_operand" "")
2114 (match_operator:SI 1 "shiftable_operator"
2115 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2116 (match_operand:SI 3 "const_int_operand" "")
2117 (match_operand:SI 4 "const_int_operand" ""))
2118 (match_operand:SI 5 "s_register_operand" "")]))
2119 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2121 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2124 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2127 HOST_WIDE_INT temp = INTVAL (operands[3]);
2129 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2130 operands[4] = GEN_INT (32 - temp);
2134 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2135 ;;; represented by the bitfield, then this will produce incorrect results.
2136 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2137 ;;; which have a real bit-field insert instruction, the truncation happens
2138 ;;; in the bit-field insert instruction itself. Since arm does not have a
2139 ;;; bit-field insert instruction, we would have to emit code here to truncate
2140 ;;; the value before we insert. This loses some of the advantage of having
2141 ;;; this insv pattern, so this pattern needs to be reevalutated.
2143 ; ??? Use Thumb-2 bitfield insert/extract instructions
2144 (define_expand "insv"
2145 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
2146 (match_operand:SI 1 "general_operand" "")
2147 (match_operand:SI 2 "general_operand" ""))
2148 (match_operand:SI 3 "reg_or_int_operand" ""))]
2152 int start_bit = INTVAL (operands[2]);
2153 int width = INTVAL (operands[1]);
2154 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2155 rtx target, subtarget;
2157 target = operands[0];
2158 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2159 subreg as the final target. */
2160 if (GET_CODE (target) == SUBREG)
2162 subtarget = gen_reg_rtx (SImode);
2163 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2164 < GET_MODE_SIZE (SImode))
2165 target = SUBREG_REG (target);
2170 if (GET_CODE (operands[3]) == CONST_INT)
2172 /* Since we are inserting a known constant, we may be able to
2173 reduce the number of bits that we have to clear so that
2174 the mask becomes simple. */
2175 /* ??? This code does not check to see if the new mask is actually
2176 simpler. It may not be. */
2177 rtx op1 = gen_reg_rtx (SImode);
2178 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2179 start of this pattern. */
2180 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2181 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2183 emit_insn (gen_andsi3 (op1, operands[0],
2184 gen_int_mode (~mask2, SImode)));
2185 emit_insn (gen_iorsi3 (subtarget, op1,
2186 gen_int_mode (op3_value << start_bit, SImode)));
2188 else if (start_bit == 0
2189 && !(const_ok_for_arm (mask)
2190 || const_ok_for_arm (~mask)))
2192 /* A Trick, since we are setting the bottom bits in the word,
2193 we can shift operand[3] up, operand[0] down, OR them together
2194 and rotate the result back again. This takes 3 insns, and
2195 the third might be mergeable into another op. */
2196 /* The shift up copes with the possibility that operand[3] is
2197 wider than the bitfield. */
2198 rtx op0 = gen_reg_rtx (SImode);
2199 rtx op1 = gen_reg_rtx (SImode);
2201 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2202 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2203 emit_insn (gen_iorsi3 (op1, op1, op0));
2204 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2206 else if ((width + start_bit == 32)
2207 && !(const_ok_for_arm (mask)
2208 || const_ok_for_arm (~mask)))
2210 /* Similar trick, but slightly less efficient. */
2212 rtx op0 = gen_reg_rtx (SImode);
2213 rtx op1 = gen_reg_rtx (SImode);
2215 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2216 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2217 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2218 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2222 rtx op0 = gen_int_mode (mask, SImode);
2223 rtx op1 = gen_reg_rtx (SImode);
2224 rtx op2 = gen_reg_rtx (SImode);
2226 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2228 rtx tmp = gen_reg_rtx (SImode);
2230 emit_insn (gen_movsi (tmp, op0));
2234 /* Mask out any bits in operand[3] that are not needed. */
2235 emit_insn (gen_andsi3 (op1, operands[3], op0));
2237 if (GET_CODE (op0) == CONST_INT
2238 && (const_ok_for_arm (mask << start_bit)
2239 || const_ok_for_arm (~(mask << start_bit))))
2241 op0 = gen_int_mode (~(mask << start_bit), SImode);
2242 emit_insn (gen_andsi3 (op2, operands[0], op0));
2246 if (GET_CODE (op0) == CONST_INT)
2248 rtx tmp = gen_reg_rtx (SImode);
2250 emit_insn (gen_movsi (tmp, op0));
2255 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2257 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2261 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2263 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2266 if (subtarget != target)
2268 /* If TARGET is still a SUBREG, then it must be wider than a word,
2269 so we must be careful only to set the subword we were asked to. */
2270 if (GET_CODE (target) == SUBREG)
2271 emit_move_insn (target, subtarget);
2273 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2280 ; constants for op 2 will never be given to these patterns.
2281 (define_insn_and_split "*anddi_notdi_di"
2282 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2283 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
2284 (match_operand:DI 2 "s_register_operand" "0,r")))]
2287 "TARGET_32BIT && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2288 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2289 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2292 operands[3] = gen_highpart (SImode, operands[0]);
2293 operands[0] = gen_lowpart (SImode, operands[0]);
2294 operands[4] = gen_highpart (SImode, operands[1]);
2295 operands[1] = gen_lowpart (SImode, operands[1]);
2296 operands[5] = gen_highpart (SImode, operands[2]);
2297 operands[2] = gen_lowpart (SImode, operands[2]);
2299 [(set_attr "length" "8")
2300 (set_attr "predicable" "yes")]
2303 (define_insn_and_split "*anddi_notzesidi_di"
2304 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2305 (and:DI (not:DI (zero_extend:DI
2306 (match_operand:SI 2 "s_register_operand" "r,r")))
2307 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2310 bic%?\\t%Q0, %Q1, %2
2312 ; (not (zero_extend ...)) allows us to just copy the high word from
2313 ; operand1 to operand0.
2316 && operands[0] != operands[1]"
2317 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2318 (set (match_dup 3) (match_dup 4))]
2321 operands[3] = gen_highpart (SImode, operands[0]);
2322 operands[0] = gen_lowpart (SImode, operands[0]);
2323 operands[4] = gen_highpart (SImode, operands[1]);
2324 operands[1] = gen_lowpart (SImode, operands[1]);
2326 [(set_attr "length" "4,8")
2327 (set_attr "predicable" "yes")]
2330 (define_insn_and_split "*anddi_notsesidi_di"
2331 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2332 (and:DI (not:DI (sign_extend:DI
2333 (match_operand:SI 2 "s_register_operand" "r,r")))
2334 (match_operand:DI 1 "s_register_operand" "0,r")))]
2337 "TARGET_32BIT && reload_completed"
2338 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2339 (set (match_dup 3) (and:SI (not:SI
2340 (ashiftrt:SI (match_dup 2) (const_int 31)))
2344 operands[3] = gen_highpart (SImode, operands[0]);
2345 operands[0] = gen_lowpart (SImode, operands[0]);
2346 operands[4] = gen_highpart (SImode, operands[1]);
2347 operands[1] = gen_lowpart (SImode, operands[1]);
2349 [(set_attr "length" "8")
2350 (set_attr "predicable" "yes")]
2353 (define_insn "andsi_notsi_si"
2354 [(set (match_operand:SI 0 "s_register_operand" "=r")
2355 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2356 (match_operand:SI 1 "s_register_operand" "r")))]
2358 "bic%?\\t%0, %1, %2"
2359 [(set_attr "predicable" "yes")]
2362 (define_insn "bicsi3"
2363 [(set (match_operand:SI 0 "register_operand" "=l")
2364 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2365 (match_operand:SI 2 "register_operand" "0")))]
2368 [(set_attr "length" "2")]
2371 (define_insn "andsi_not_shiftsi_si"
2372 [(set (match_operand:SI 0 "s_register_operand" "=r")
2373 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2374 [(match_operand:SI 2 "s_register_operand" "r")
2375 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2376 (match_operand:SI 1 "s_register_operand" "r")))]
2378 "bic%?\\t%0, %1, %2%S4"
2379 [(set_attr "predicable" "yes")
2380 (set_attr "shift" "2")
2381 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2382 (const_string "alu_shift")
2383 (const_string "alu_shift_reg")))]
2386 (define_insn "*andsi_notsi_si_compare0"
2387 [(set (reg:CC_NOOV CC_REGNUM)
2389 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2390 (match_operand:SI 1 "s_register_operand" "r"))
2392 (set (match_operand:SI 0 "s_register_operand" "=r")
2393 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2395 "bic%.\\t%0, %1, %2"
2396 [(set_attr "conds" "set")]
2399 (define_insn "*andsi_notsi_si_compare0_scratch"
2400 [(set (reg:CC_NOOV CC_REGNUM)
2402 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2403 (match_operand:SI 1 "s_register_operand" "r"))
2405 (clobber (match_scratch:SI 0 "=r"))]
2407 "bic%.\\t%0, %1, %2"
2408 [(set_attr "conds" "set")]
2411 (define_insn "iordi3"
2412 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2413 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2414 (match_operand:DI 2 "s_register_operand" "r,r")))]
2415 "TARGET_32BIT && ! TARGET_IWMMXT"
2417 [(set_attr "length" "8")
2418 (set_attr "predicable" "yes")]
2421 (define_insn "*iordi_zesidi_di"
2422 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2423 (ior:DI (zero_extend:DI
2424 (match_operand:SI 2 "s_register_operand" "r,r"))
2425 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2428 orr%?\\t%Q0, %Q1, %2
2430 [(set_attr "length" "4,8")
2431 (set_attr "predicable" "yes")]
2434 (define_insn "*iordi_sesidi_di"
2435 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2436 (ior:DI (sign_extend:DI
2437 (match_operand:SI 2 "s_register_operand" "r,r"))
2438 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2441 [(set_attr "length" "8")
2442 (set_attr "predicable" "yes")]
2445 (define_expand "iorsi3"
2446 [(set (match_operand:SI 0 "s_register_operand" "")
2447 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2448 (match_operand:SI 2 "reg_or_int_operand" "")))]
2451 if (GET_CODE (operands[2]) == CONST_INT)
2455 arm_split_constant (IOR, SImode, NULL_RTX,
2456 INTVAL (operands[2]), operands[0], operands[1],
2457 optimize && can_create_pseudo_p ());
2460 else /* TARGET_THUMB1 */
2461 operands [2] = force_reg (SImode, operands [2]);
2466 (define_insn_and_split "*arm_iorsi3"
2467 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2468 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2469 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2475 && GET_CODE (operands[2]) == CONST_INT
2476 && !const_ok_for_arm (INTVAL (operands[2]))"
2477 [(clobber (const_int 0))]
2479 arm_split_constant (IOR, SImode, curr_insn,
2480 INTVAL (operands[2]), operands[0], operands[1], 0);
2483 [(set_attr "length" "4,16")
2484 (set_attr "predicable" "yes")]
2487 (define_insn "*thumb1_iorsi3"
2488 [(set (match_operand:SI 0 "register_operand" "=l")
2489 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2490 (match_operand:SI 2 "register_operand" "l")))]
2493 [(set_attr "length" "2")]
2497 [(match_scratch:SI 3 "r")
2498 (set (match_operand:SI 0 "arm_general_register_operand" "")
2499 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2500 (match_operand:SI 2 "const_int_operand" "")))]
2502 && !const_ok_for_arm (INTVAL (operands[2]))
2503 && const_ok_for_arm (~INTVAL (operands[2]))"
2504 [(set (match_dup 3) (match_dup 2))
2505 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2509 (define_insn "*iorsi3_compare0"
2510 [(set (reg:CC_NOOV CC_REGNUM)
2511 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2512 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2514 (set (match_operand:SI 0 "s_register_operand" "=r")
2515 (ior:SI (match_dup 1) (match_dup 2)))]
2517 "orr%.\\t%0, %1, %2"
2518 [(set_attr "conds" "set")]
2521 (define_insn "*iorsi3_compare0_scratch"
2522 [(set (reg:CC_NOOV CC_REGNUM)
2523 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2524 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2526 (clobber (match_scratch:SI 0 "=r"))]
2528 "orr%.\\t%0, %1, %2"
2529 [(set_attr "conds" "set")]
2532 (define_insn "xordi3"
2533 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2534 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2535 (match_operand:DI 2 "s_register_operand" "r,r")))]
2536 "TARGET_32BIT && !TARGET_IWMMXT"
2538 [(set_attr "length" "8")
2539 (set_attr "predicable" "yes")]
2542 (define_insn "*xordi_zesidi_di"
2543 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2544 (xor:DI (zero_extend:DI
2545 (match_operand:SI 2 "s_register_operand" "r,r"))
2546 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2549 eor%?\\t%Q0, %Q1, %2
2551 [(set_attr "length" "4,8")
2552 (set_attr "predicable" "yes")]
2555 (define_insn "*xordi_sesidi_di"
2556 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2557 (xor:DI (sign_extend:DI
2558 (match_operand:SI 2 "s_register_operand" "r,r"))
2559 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2562 [(set_attr "length" "8")
2563 (set_attr "predicable" "yes")]
2566 (define_expand "xorsi3"
2567 [(set (match_operand:SI 0 "s_register_operand" "")
2568 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2569 (match_operand:SI 2 "arm_rhs_operand" "")))]
2572 if (GET_CODE (operands[2]) == CONST_INT)
2573 operands[2] = force_reg (SImode, operands[2]);
2577 (define_insn "*arm_xorsi3"
2578 [(set (match_operand:SI 0 "s_register_operand" "=r")
2579 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2580 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2582 "eor%?\\t%0, %1, %2"
2583 [(set_attr "predicable" "yes")]
2586 (define_insn "*thumb1_xorsi3"
2587 [(set (match_operand:SI 0 "register_operand" "=l")
2588 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2589 (match_operand:SI 2 "register_operand" "l")))]
2592 [(set_attr "length" "2")]
2595 (define_insn "*xorsi3_compare0"
2596 [(set (reg:CC_NOOV CC_REGNUM)
2597 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2598 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2600 (set (match_operand:SI 0 "s_register_operand" "=r")
2601 (xor:SI (match_dup 1) (match_dup 2)))]
2603 "eor%.\\t%0, %1, %2"
2604 [(set_attr "conds" "set")]
2607 (define_insn "*xorsi3_compare0_scratch"
2608 [(set (reg:CC_NOOV CC_REGNUM)
2609 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2610 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2614 [(set_attr "conds" "set")]
2617 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2618 ; (NOT D) we can sometimes merge the final NOT into one of the following
2622 [(set (match_operand:SI 0 "s_register_operand" "")
2623 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2624 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2625 (match_operand:SI 3 "arm_rhs_operand" "")))
2626 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2628 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2629 (not:SI (match_dup 3))))
2630 (set (match_dup 0) (not:SI (match_dup 4)))]
2634 (define_insn "*andsi_iorsi3_notsi"
2635 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2636 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2637 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2638 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2640 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2641 [(set_attr "length" "8")
2642 (set_attr "ce_count" "2")
2643 (set_attr "predicable" "yes")]
2646 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
2647 ; insns are available?
2649 [(set (match_operand:SI 0 "s_register_operand" "")
2650 (match_operator:SI 1 "logical_binary_operator"
2651 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2652 (match_operand:SI 3 "const_int_operand" "")
2653 (match_operand:SI 4 "const_int_operand" ""))
2654 (match_operator:SI 9 "logical_binary_operator"
2655 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2656 (match_operand:SI 6 "const_int_operand" ""))
2657 (match_operand:SI 7 "s_register_operand" "")])]))
2658 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2660 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2661 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2664 [(ashift:SI (match_dup 2) (match_dup 4))
2668 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2671 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2675 [(set (match_operand:SI 0 "s_register_operand" "")
2676 (match_operator:SI 1 "logical_binary_operator"
2677 [(match_operator:SI 9 "logical_binary_operator"
2678 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2679 (match_operand:SI 6 "const_int_operand" ""))
2680 (match_operand:SI 7 "s_register_operand" "")])
2681 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2682 (match_operand:SI 3 "const_int_operand" "")
2683 (match_operand:SI 4 "const_int_operand" ""))]))
2684 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2686 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2687 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2690 [(ashift:SI (match_dup 2) (match_dup 4))
2694 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2697 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2701 [(set (match_operand:SI 0 "s_register_operand" "")
2702 (match_operator:SI 1 "logical_binary_operator"
2703 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2704 (match_operand:SI 3 "const_int_operand" "")
2705 (match_operand:SI 4 "const_int_operand" ""))
2706 (match_operator:SI 9 "logical_binary_operator"
2707 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2708 (match_operand:SI 6 "const_int_operand" ""))
2709 (match_operand:SI 7 "s_register_operand" "")])]))
2710 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2712 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2713 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2716 [(ashift:SI (match_dup 2) (match_dup 4))
2720 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2723 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2727 [(set (match_operand:SI 0 "s_register_operand" "")
2728 (match_operator:SI 1 "logical_binary_operator"
2729 [(match_operator:SI 9 "logical_binary_operator"
2730 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2731 (match_operand:SI 6 "const_int_operand" ""))
2732 (match_operand:SI 7 "s_register_operand" "")])
2733 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2734 (match_operand:SI 3 "const_int_operand" "")
2735 (match_operand:SI 4 "const_int_operand" ""))]))
2736 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2738 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2739 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2742 [(ashift:SI (match_dup 2) (match_dup 4))
2746 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2749 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2753 ;; Minimum and maximum insns
2755 (define_expand "smaxsi3"
2757 (set (match_operand:SI 0 "s_register_operand" "")
2758 (smax:SI (match_operand:SI 1 "s_register_operand" "")
2759 (match_operand:SI 2 "arm_rhs_operand" "")))
2760 (clobber (reg:CC CC_REGNUM))])]
2763 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
2765 /* No need for a clobber of the condition code register here. */
2766 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2767 gen_rtx_SMAX (SImode, operands[1],
2773 (define_insn "*smax_0"
2774 [(set (match_operand:SI 0 "s_register_operand" "=r")
2775 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
2778 "bic%?\\t%0, %1, %1, asr #31"
2779 [(set_attr "predicable" "yes")]
2782 (define_insn "*smax_m1"
2783 [(set (match_operand:SI 0 "s_register_operand" "=r")
2784 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
2787 "orr%?\\t%0, %1, %1, asr #31"
2788 [(set_attr "predicable" "yes")]
2791 (define_insn "*arm_smax_insn"
2792 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2793 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
2794 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
2795 (clobber (reg:CC CC_REGNUM))]
2798 cmp\\t%1, %2\;movlt\\t%0, %2
2799 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2800 [(set_attr "conds" "clob")
2801 (set_attr "length" "8,12")]
2804 (define_expand "sminsi3"
2806 (set (match_operand:SI 0 "s_register_operand" "")
2807 (smin:SI (match_operand:SI 1 "s_register_operand" "")
2808 (match_operand:SI 2 "arm_rhs_operand" "")))
2809 (clobber (reg:CC CC_REGNUM))])]
2812 if (operands[2] == const0_rtx)
2814 /* No need for a clobber of the condition code register here. */
2815 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2816 gen_rtx_SMIN (SImode, operands[1],
2822 (define_insn "*smin_0"
2823 [(set (match_operand:SI 0 "s_register_operand" "=r")
2824 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
2827 "and%?\\t%0, %1, %1, asr #31"
2828 [(set_attr "predicable" "yes")]
2831 (define_insn "*arm_smin_insn"
2832 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2833 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
2834 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
2835 (clobber (reg:CC CC_REGNUM))]
2838 cmp\\t%1, %2\;movge\\t%0, %2
2839 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2840 [(set_attr "conds" "clob")
2841 (set_attr "length" "8,12")]
2844 (define_expand "umaxsi3"
2846 (set (match_operand:SI 0 "s_register_operand" "")
2847 (umax:SI (match_operand:SI 1 "s_register_operand" "")
2848 (match_operand:SI 2 "arm_rhs_operand" "")))
2849 (clobber (reg:CC CC_REGNUM))])]
2854 (define_insn "*arm_umaxsi3"
2855 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2856 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2857 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2858 (clobber (reg:CC CC_REGNUM))]
2861 cmp\\t%1, %2\;movcc\\t%0, %2
2862 cmp\\t%1, %2\;movcs\\t%0, %1
2863 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2864 [(set_attr "conds" "clob")
2865 (set_attr "length" "8,8,12")]
2868 (define_expand "uminsi3"
2870 (set (match_operand:SI 0 "s_register_operand" "")
2871 (umin:SI (match_operand:SI 1 "s_register_operand" "")
2872 (match_operand:SI 2 "arm_rhs_operand" "")))
2873 (clobber (reg:CC CC_REGNUM))])]
2878 (define_insn "*arm_uminsi3"
2879 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2880 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2881 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2882 (clobber (reg:CC CC_REGNUM))]
2885 cmp\\t%1, %2\;movcs\\t%0, %2
2886 cmp\\t%1, %2\;movcc\\t%0, %1
2887 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2888 [(set_attr "conds" "clob")
2889 (set_attr "length" "8,8,12")]
2892 (define_insn "*store_minmaxsi"
2893 [(set (match_operand:SI 0 "memory_operand" "=m")
2894 (match_operator:SI 3 "minmax_operator"
2895 [(match_operand:SI 1 "s_register_operand" "r")
2896 (match_operand:SI 2 "s_register_operand" "r")]))
2897 (clobber (reg:CC CC_REGNUM))]
2900 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2901 operands[1], operands[2]);
2902 output_asm_insn (\"cmp\\t%1, %2\", operands);
2904 output_asm_insn (\"ite\t%d3\", operands);
2905 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2906 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2909 [(set_attr "conds" "clob")
2910 (set (attr "length")
2911 (if_then_else (eq_attr "is_thumb" "yes")
2914 (set_attr "type" "store1")]
2917 ; Reject the frame pointer in operand[1], since reloading this after
2918 ; it has been eliminated can cause carnage.
2919 (define_insn "*minmax_arithsi"
2920 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2921 (match_operator:SI 4 "shiftable_operator"
2922 [(match_operator:SI 5 "minmax_operator"
2923 [(match_operand:SI 2 "s_register_operand" "r,r")
2924 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2925 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2926 (clobber (reg:CC CC_REGNUM))]
2927 "TARGET_32BIT && !arm_eliminable_register (operands[1])"
2930 enum rtx_code code = GET_CODE (operands[4]);
2933 if (which_alternative != 0 || operands[3] != const0_rtx
2934 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2939 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2940 operands[2], operands[3]);
2941 output_asm_insn (\"cmp\\t%2, %3\", operands);
2945 output_asm_insn (\"ite\\t%d5\", operands);
2947 output_asm_insn (\"it\\t%d5\", operands);
2949 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2951 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2954 [(set_attr "conds" "clob")
2955 (set (attr "length")
2956 (if_then_else (eq_attr "is_thumb" "yes")
2962 ;; Shift and rotation insns
2964 (define_expand "ashldi3"
2965 [(set (match_operand:DI 0 "s_register_operand" "")
2966 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2967 (match_operand:SI 2 "reg_or_int_operand" "")))]
2970 if (GET_CODE (operands[2]) == CONST_INT)
2972 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2974 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2977 /* Ideally we shouldn't fail here if we could know that operands[1]
2978 ends up already living in an iwmmxt register. Otherwise it's
2979 cheaper to have the alternate code being generated than moving
2980 values to iwmmxt regs and back. */
2983 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2988 (define_insn "arm_ashldi3_1bit"
2989 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2990 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2992 (clobber (reg:CC CC_REGNUM))]
2994 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2995 [(set_attr "conds" "clob")
2996 (set_attr "length" "8")]
2999 (define_expand "ashlsi3"
3000 [(set (match_operand:SI 0 "s_register_operand" "")
3001 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3002 (match_operand:SI 2 "arm_rhs_operand" "")))]
3005 if (GET_CODE (operands[2]) == CONST_INT
3006 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3008 emit_insn (gen_movsi (operands[0], const0_rtx));
3014 (define_insn "*thumb1_ashlsi3"
3015 [(set (match_operand:SI 0 "register_operand" "=l,l")
3016 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3017 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3020 [(set_attr "length" "2")]
3023 (define_expand "ashrdi3"
3024 [(set (match_operand:DI 0 "s_register_operand" "")
3025 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3026 (match_operand:SI 2 "reg_or_int_operand" "")))]
3029 if (GET_CODE (operands[2]) == CONST_INT)
3031 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3033 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3036 /* Ideally we shouldn't fail here if we could know that operands[1]
3037 ends up already living in an iwmmxt register. Otherwise it's
3038 cheaper to have the alternate code being generated than moving
3039 values to iwmmxt regs and back. */
3042 else if (!TARGET_REALLY_IWMMXT)
3047 (define_insn "arm_ashrdi3_1bit"
3048 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
3049 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
3051 (clobber (reg:CC CC_REGNUM))]
3053 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3054 [(set_attr "conds" "clob")
3055 (set_attr "length" "8")]
3058 (define_expand "ashrsi3"
3059 [(set (match_operand:SI 0 "s_register_operand" "")
3060 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3061 (match_operand:SI 2 "arm_rhs_operand" "")))]
3064 if (GET_CODE (operands[2]) == CONST_INT
3065 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3066 operands[2] = GEN_INT (31);
3070 (define_insn "*thumb1_ashrsi3"
3071 [(set (match_operand:SI 0 "register_operand" "=l,l")
3072 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3073 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3076 [(set_attr "length" "2")]
3079 (define_expand "lshrdi3"
3080 [(set (match_operand:DI 0 "s_register_operand" "")
3081 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3082 (match_operand:SI 2 "reg_or_int_operand" "")))]
3085 if (GET_CODE (operands[2]) == CONST_INT)
3087 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3089 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3092 /* Ideally we shouldn't fail here if we could know that operands[1]
3093 ends up already living in an iwmmxt register. Otherwise it's
3094 cheaper to have the alternate code being generated than moving
3095 values to iwmmxt regs and back. */
3098 else if (!TARGET_REALLY_IWMMXT)
3103 (define_insn "arm_lshrdi3_1bit"
3104 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
3105 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
3107 (clobber (reg:CC CC_REGNUM))]
3109 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3110 [(set_attr "conds" "clob")
3111 (set_attr "length" "8")]
3114 (define_expand "lshrsi3"
3115 [(set (match_operand:SI 0 "s_register_operand" "")
3116 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3117 (match_operand:SI 2 "arm_rhs_operand" "")))]
3120 if (GET_CODE (operands[2]) == CONST_INT
3121 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3123 emit_insn (gen_movsi (operands[0], const0_rtx));
3129 (define_insn "*thumb1_lshrsi3"
3130 [(set (match_operand:SI 0 "register_operand" "=l,l")
3131 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3132 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3135 [(set_attr "length" "2")]
3138 (define_expand "rotlsi3"
3139 [(set (match_operand:SI 0 "s_register_operand" "")
3140 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3141 (match_operand:SI 2 "reg_or_int_operand" "")))]
3144 if (GET_CODE (operands[2]) == CONST_INT)
3145 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3148 rtx reg = gen_reg_rtx (SImode);
3149 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3155 (define_expand "rotrsi3"
3156 [(set (match_operand:SI 0 "s_register_operand" "")
3157 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3158 (match_operand:SI 2 "arm_rhs_operand" "")))]
3163 if (GET_CODE (operands[2]) == CONST_INT
3164 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3165 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3167 else /* TARGET_THUMB1 */
3169 if (GET_CODE (operands [2]) == CONST_INT)
3170 operands [2] = force_reg (SImode, operands[2]);
3175 (define_insn "*thumb1_rotrsi3"
3176 [(set (match_operand:SI 0 "register_operand" "=l")
3177 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
3178 (match_operand:SI 2 "register_operand" "l")))]
3181 [(set_attr "length" "2")]
3184 (define_insn "*arm_shiftsi3"
3185 [(set (match_operand:SI 0 "s_register_operand" "=r")
3186 (match_operator:SI 3 "shift_operator"
3187 [(match_operand:SI 1 "s_register_operand" "r")
3188 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
3190 "* return arm_output_shift(operands, 0);"
3191 [(set_attr "predicable" "yes")
3192 (set_attr "shift" "1")
3193 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3194 (const_string "alu_shift")
3195 (const_string "alu_shift_reg")))]
3198 (define_insn "*shiftsi3_compare0"
3199 [(set (reg:CC_NOOV CC_REGNUM)
3200 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3201 [(match_operand:SI 1 "s_register_operand" "r")
3202 (match_operand:SI 2 "arm_rhs_operand" "rM")])
3204 (set (match_operand:SI 0 "s_register_operand" "=r")
3205 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3207 "* return arm_output_shift(operands, 1);"
3208 [(set_attr "conds" "set")
3209 (set_attr "shift" "1")
3210 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3211 (const_string "alu_shift")
3212 (const_string "alu_shift_reg")))]
3215 (define_insn "*shiftsi3_compare0_scratch"
3216 [(set (reg:CC_NOOV CC_REGNUM)
3217 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3218 [(match_operand:SI 1 "s_register_operand" "r")
3219 (match_operand:SI 2 "arm_rhs_operand" "rM")])
3221 (clobber (match_scratch:SI 0 "=r"))]
3223 "* return arm_output_shift(operands, 1);"
3224 [(set_attr "conds" "set")
3225 (set_attr "shift" "1")]
3228 (define_insn "*arm_notsi_shiftsi"
3229 [(set (match_operand:SI 0 "s_register_operand" "=r")
3230 (not:SI (match_operator:SI 3 "shift_operator"
3231 [(match_operand:SI 1 "s_register_operand" "r")
3232 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
3235 [(set_attr "predicable" "yes")
3236 (set_attr "shift" "1")
3237 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3238 (const_string "alu_shift")
3239 (const_string "alu_shift_reg")))]
3242 (define_insn "*arm_notsi_shiftsi_compare0"
3243 [(set (reg:CC_NOOV CC_REGNUM)
3244 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
3245 [(match_operand:SI 1 "s_register_operand" "r")
3246 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3248 (set (match_operand:SI 0 "s_register_operand" "=r")
3249 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3252 [(set_attr "conds" "set")
3253 (set_attr "shift" "1")
3254 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3255 (const_string "alu_shift")
3256 (const_string "alu_shift_reg")))]
3259 (define_insn "*arm_not_shiftsi_compare0_scratch"
3260 [(set (reg:CC_NOOV CC_REGNUM)
3261 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
3262 [(match_operand:SI 1 "s_register_operand" "r")
3263 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3265 (clobber (match_scratch:SI 0 "=r"))]
3268 [(set_attr "conds" "set")
3269 (set_attr "shift" "1")
3270 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3271 (const_string "alu_shift")
3272 (const_string "alu_shift_reg")))]
3275 ;; We don't really have extzv, but defining this using shifts helps
3276 ;; to reduce register pressure later on.
3278 (define_expand "extzv"
3280 (ashift:SI (match_operand:SI 1 "register_operand" "")
3281 (match_operand:SI 2 "const_int_operand" "")))
3282 (set (match_operand:SI 0 "register_operand" "")
3283 (lshiftrt:SI (match_dup 4)
3284 (match_operand:SI 3 "const_int_operand" "")))]
3288 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3289 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3291 operands[3] = GEN_INT (rshift);
3295 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
3299 operands[2] = GEN_INT (lshift);
3300 operands[4] = gen_reg_rtx (SImode);
3305 ;; Unary arithmetic insns
3307 (define_expand "negdi2"
3309 [(set (match_operand:DI 0 "s_register_operand" "")
3310 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
3311 (clobber (reg:CC CC_REGNUM))])]
3316 if (GET_CODE (operands[1]) != REG)
3317 operands[1] = force_reg (SImode, operands[1]);
3322 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
3323 ;; The second alternative is to allow the common case of a *full* overlap.
3324 (define_insn "*arm_negdi2"
3325 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
3326 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
3327 (clobber (reg:CC CC_REGNUM))]
3329 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
3330 [(set_attr "conds" "clob")
3331 (set_attr "length" "8")]
3334 (define_insn "*thumb1_negdi2"
3335 [(set (match_operand:DI 0 "register_operand" "=&l")
3336 (neg:DI (match_operand:DI 1 "register_operand" "l")))
3337 (clobber (reg:CC CC_REGNUM))]
3339 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
3340 [(set_attr "length" "6")]
3343 (define_expand "negsi2"
3344 [(set (match_operand:SI 0 "s_register_operand" "")
3345 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
3350 (define_insn "*arm_negsi2"
3351 [(set (match_operand:SI 0 "s_register_operand" "=r")
3352 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
3354 "rsb%?\\t%0, %1, #0"
3355 [(set_attr "predicable" "yes")]
3358 (define_insn "*thumb1_negsi2"
3359 [(set (match_operand:SI 0 "register_operand" "=l")
3360 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
3363 [(set_attr "length" "2")]
3366 (define_expand "negsf2"
3367 [(set (match_operand:SF 0 "s_register_operand" "")
3368 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
3369 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3373 (define_expand "negdf2"
3374 [(set (match_operand:DF 0 "s_register_operand" "")
3375 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
3376 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3379 ;; abssi2 doesn't really clobber the condition codes if a different register
3380 ;; is being set. To keep things simple, assume during rtl manipulations that
3381 ;; it does, but tell the final scan operator the truth. Similarly for
3384 (define_expand "abssi2"
3386 [(set (match_operand:SI 0 "s_register_operand" "")
3387 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
3388 (clobber (match_dup 2))])]
3392 operands[2] = gen_rtx_SCRATCH (SImode);
3394 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
3397 (define_insn "*arm_abssi2"
3398 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3399 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
3400 (clobber (reg:CC CC_REGNUM))]
3403 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
3404 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
3405 [(set_attr "conds" "clob,*")
3406 (set_attr "shift" "1")
3407 ;; predicable can't be set based on the variant, so left as no
3408 (set_attr "length" "8")]
3411 (define_insn_and_split "*thumb1_abssi2"
3412 [(set (match_operand:SI 0 "s_register_operand" "=l")
3413 (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
3414 (clobber (match_scratch:SI 2 "=&l"))]
3417 "TARGET_THUMB1 && reload_completed"
3418 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
3419 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
3420 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
3422 [(set_attr "length" "6")]
3425 (define_insn "*arm_neg_abssi2"
3426 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3427 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
3428 (clobber (reg:CC CC_REGNUM))]
3431 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
3432 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
3433 [(set_attr "conds" "clob,*")
3434 (set_attr "shift" "1")
3435 ;; predicable can't be set based on the variant, so left as no
3436 (set_attr "length" "8")]
3439 (define_insn_and_split "*thumb1_neg_abssi2"
3440 [(set (match_operand:SI 0 "s_register_operand" "=l")
3441 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
3442 (clobber (match_scratch:SI 2 "=&l"))]
3445 "TARGET_THUMB1 && reload_completed"
3446 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
3447 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
3448 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
3450 [(set_attr "length" "6")]
3453 (define_expand "abssf2"
3454 [(set (match_operand:SF 0 "s_register_operand" "")
3455 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
3456 "TARGET_32BIT && TARGET_HARD_FLOAT"
3459 (define_expand "absdf2"
3460 [(set (match_operand:DF 0 "s_register_operand" "")
3461 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
3462 "TARGET_32BIT && TARGET_HARD_FLOAT"
3465 (define_expand "sqrtsf2"
3466 [(set (match_operand:SF 0 "s_register_operand" "")
3467 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
3468 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3471 (define_expand "sqrtdf2"
3472 [(set (match_operand:DF 0 "s_register_operand" "")
3473 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
3474 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3477 (define_insn_and_split "one_cmpldi2"
3478 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3479 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
3482 "TARGET_32BIT && reload_completed"
3483 [(set (match_dup 0) (not:SI (match_dup 1)))
3484 (set (match_dup 2) (not:SI (match_dup 3)))]
3487 operands[2] = gen_highpart (SImode, operands[0]);
3488 operands[0] = gen_lowpart (SImode, operands[0]);
3489 operands[3] = gen_highpart (SImode, operands[1]);
3490 operands[1] = gen_lowpart (SImode, operands[1]);
3492 [(set_attr "length" "8")
3493 (set_attr "predicable" "yes")]
3496 (define_expand "one_cmplsi2"
3497 [(set (match_operand:SI 0 "s_register_operand" "")
3498 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
3503 (define_insn "*arm_one_cmplsi2"
3504 [(set (match_operand:SI 0 "s_register_operand" "=r")
3505 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
3508 [(set_attr "predicable" "yes")]
3511 (define_insn "*thumb1_one_cmplsi2"
3512 [(set (match_operand:SI 0 "register_operand" "=l")
3513 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3516 [(set_attr "length" "2")]
3519 (define_insn "*notsi_compare0"
3520 [(set (reg:CC_NOOV CC_REGNUM)
3521 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3523 (set (match_operand:SI 0 "s_register_operand" "=r")
3524 (not:SI (match_dup 1)))]
3527 [(set_attr "conds" "set")]
3530 (define_insn "*notsi_compare0_scratch"
3531 [(set (reg:CC_NOOV CC_REGNUM)
3532 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3534 (clobber (match_scratch:SI 0 "=r"))]
3537 [(set_attr "conds" "set")]
3540 ;; Fixed <--> Floating conversion insns
3542 (define_expand "floatsisf2"
3543 [(set (match_operand:SF 0 "s_register_operand" "")
3544 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3545 "TARGET_32BIT && TARGET_HARD_FLOAT"
3547 if (TARGET_MAVERICK)
3549 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3554 (define_expand "floatsidf2"
3555 [(set (match_operand:DF 0 "s_register_operand" "")
3556 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3557 "TARGET_32BIT && TARGET_HARD_FLOAT"
3559 if (TARGET_MAVERICK)
3561 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3566 (define_expand "fix_truncsfsi2"
3567 [(set (match_operand:SI 0 "s_register_operand" "")
3568 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3569 "TARGET_32BIT && TARGET_HARD_FLOAT"
3571 if (TARGET_MAVERICK)
3573 if (!cirrus_fp_register (operands[0], SImode))
3574 operands[0] = force_reg (SImode, operands[0]);
3575 if (!cirrus_fp_register (operands[1], SFmode))
3576 operands[1] = force_reg (SFmode, operands[0]);
3577 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3582 (define_expand "fix_truncdfsi2"
3583 [(set (match_operand:SI 0 "s_register_operand" "")
3584 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3585 "TARGET_32BIT && TARGET_HARD_FLOAT"
3587 if (TARGET_MAVERICK)
3589 if (!cirrus_fp_register (operands[1], DFmode))
3590 operands[1] = force_reg (DFmode, operands[0]);
3591 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3598 (define_expand "truncdfsf2"
3599 [(set (match_operand:SF 0 "s_register_operand" "")
3601 (match_operand:DF 1 "s_register_operand" "")))]
3602 "TARGET_32BIT && TARGET_HARD_FLOAT"
3606 ;; Zero and sign extension instructions.
3608 (define_expand "zero_extendsidi2"
3609 [(set (match_operand:DI 0 "s_register_operand" "")
3610 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
3615 (define_insn "*arm_zero_extendsidi2"
3616 [(set (match_operand:DI 0 "s_register_operand" "=r")
3617 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3620 if (REGNO (operands[1])
3621 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3622 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3623 return \"mov%?\\t%R0, #0\";
3625 [(set_attr "length" "8")
3626 (set_attr "predicable" "yes")]
3629 (define_expand "zero_extendqidi2"
3630 [(set (match_operand:DI 0 "s_register_operand" "")
3631 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3636 (define_insn "*arm_zero_extendqidi2"
3637 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3638 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3641 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3642 ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0"
3643 [(set_attr "length" "8")
3644 (set_attr "predicable" "yes")
3645 (set_attr "type" "*,load_byte")
3646 (set_attr "pool_range" "*,4092")
3647 (set_attr "neg_pool_range" "*,4084")]
3650 (define_expand "extendsidi2"
3651 [(set (match_operand:DI 0 "s_register_operand" "")
3652 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
3657 (define_insn "*arm_extendsidi2"
3658 [(set (match_operand:DI 0 "s_register_operand" "=r")
3659 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3662 if (REGNO (operands[1])
3663 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3664 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3665 return \"mov%?\\t%R0, %Q0, asr #31\";
3667 [(set_attr "length" "8")
3668 (set_attr "shift" "1")
3669 (set_attr "predicable" "yes")]
3672 (define_expand "zero_extendhisi2"
3674 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3676 (set (match_operand:SI 0 "s_register_operand" "")
3677 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3681 if ((TARGET_THUMB1 || arm_arch4) && GET_CODE (operands[1]) == MEM)
3683 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3684 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3688 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3690 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3694 if (!s_register_operand (operands[1], HImode))
3695 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3699 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3700 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3704 operands[1] = gen_lowpart (SImode, operands[1]);
3705 operands[2] = gen_reg_rtx (SImode);
3709 (define_insn "*thumb1_zero_extendhisi2"
3710 [(set (match_operand:SI 0 "register_operand" "=l")
3711 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3712 "TARGET_THUMB1 && !arm_arch6"
3714 rtx mem = XEXP (operands[1], 0);
3716 if (GET_CODE (mem) == CONST)
3717 mem = XEXP (mem, 0);
3719 if (GET_CODE (mem) == LABEL_REF)
3720 return \"ldr\\t%0, %1\";
3722 if (GET_CODE (mem) == PLUS)
3724 rtx a = XEXP (mem, 0);
3725 rtx b = XEXP (mem, 1);
3727 /* This can happen due to bugs in reload. */
3728 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3731 ops[0] = operands[0];
3734 output_asm_insn (\"mov %0, %1\", ops);
3736 XEXP (mem, 0) = operands[0];
3739 else if ( GET_CODE (a) == LABEL_REF
3740 && GET_CODE (b) == CONST_INT)
3741 return \"ldr\\t%0, %1\";
3744 return \"ldrh\\t%0, %1\";
3746 [(set_attr "length" "4")
3747 (set_attr "type" "load_byte")
3748 (set_attr "pool_range" "60")]
3751 (define_insn "*thumb1_zero_extendhisi2_v6"
3752 [(set (match_operand:SI 0 "register_operand" "=l,l")
3753 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3754 "TARGET_THUMB1 && arm_arch6"
3758 if (which_alternative == 0)
3759 return \"uxth\\t%0, %1\";
3761 mem = XEXP (operands[1], 0);
3763 if (GET_CODE (mem) == CONST)
3764 mem = XEXP (mem, 0);
3766 if (GET_CODE (mem) == LABEL_REF)
3767 return \"ldr\\t%0, %1\";
3769 if (GET_CODE (mem) == PLUS)
3771 rtx a = XEXP (mem, 0);
3772 rtx b = XEXP (mem, 1);
3774 /* This can happen due to bugs in reload. */
3775 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3778 ops[0] = operands[0];
3781 output_asm_insn (\"mov %0, %1\", ops);
3783 XEXP (mem, 0) = operands[0];
3786 else if ( GET_CODE (a) == LABEL_REF
3787 && GET_CODE (b) == CONST_INT)
3788 return \"ldr\\t%0, %1\";
3791 return \"ldrh\\t%0, %1\";
3793 [(set_attr "length" "2,4")
3794 (set_attr "type" "alu_shift,load_byte")
3795 (set_attr "pool_range" "*,60")]
3798 (define_insn "*arm_zero_extendhisi2"
3799 [(set (match_operand:SI 0 "s_register_operand" "=r")
3800 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3801 "TARGET_ARM && arm_arch4 && !arm_arch6"
3803 [(set_attr "type" "load_byte")
3804 (set_attr "predicable" "yes")
3805 (set_attr "pool_range" "256")
3806 (set_attr "neg_pool_range" "244")]
3809 (define_insn "*arm_zero_extendhisi2_v6"
3810 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3811 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3812 "TARGET_ARM && arm_arch6"
3816 [(set_attr "type" "alu_shift,load_byte")
3817 (set_attr "predicable" "yes")
3818 (set_attr "pool_range" "*,256")
3819 (set_attr "neg_pool_range" "*,244")]
3822 (define_insn "*arm_zero_extendhisi2addsi"
3823 [(set (match_operand:SI 0 "s_register_operand" "=r")
3824 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3825 (match_operand:SI 2 "s_register_operand" "r")))]
3827 "uxtah%?\\t%0, %2, %1"
3828 [(set_attr "type" "alu_shift")
3829 (set_attr "predicable" "yes")]
3832 (define_expand "zero_extendqisi2"
3833 [(set (match_operand:SI 0 "s_register_operand" "")
3834 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3837 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3841 emit_insn (gen_andsi3 (operands[0],
3842 gen_lowpart (SImode, operands[1]),
3845 else /* TARGET_THUMB */
3847 rtx temp = gen_reg_rtx (SImode);
3850 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3851 operands[1] = gen_lowpart (SImode, operands[1]);
3854 ops[1] = operands[1];
3855 ops[2] = GEN_INT (24);
3857 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3858 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3860 ops[0] = operands[0];
3862 ops[2] = GEN_INT (24);
3864 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3865 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3872 (define_insn "*thumb1_zero_extendqisi2"
3873 [(set (match_operand:SI 0 "register_operand" "=l")
3874 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3875 "TARGET_THUMB1 && !arm_arch6"
3877 [(set_attr "length" "2")
3878 (set_attr "type" "load_byte")
3879 (set_attr "pool_range" "32")]
3882 (define_insn "*thumb1_zero_extendqisi2_v6"
3883 [(set (match_operand:SI 0 "register_operand" "=l,l")
3884 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3885 "TARGET_THUMB1 && arm_arch6"
3889 [(set_attr "length" "2,2")
3890 (set_attr "type" "alu_shift,load_byte")
3891 (set_attr "pool_range" "*,32")]
3894 (define_insn "*arm_zero_extendqisi2"
3895 [(set (match_operand:SI 0 "s_register_operand" "=r")
3896 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3897 "TARGET_ARM && !arm_arch6"
3898 "ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
3899 [(set_attr "type" "load_byte")
3900 (set_attr "predicable" "yes")
3901 (set_attr "pool_range" "4096")
3902 (set_attr "neg_pool_range" "4084")]
3905 (define_insn "*arm_zero_extendqisi2_v6"
3906 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3907 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3908 "TARGET_ARM && arm_arch6"
3911 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
3912 [(set_attr "type" "alu_shift,load_byte")
3913 (set_attr "predicable" "yes")
3914 (set_attr "pool_range" "*,4096")
3915 (set_attr "neg_pool_range" "*,4084")]
3918 (define_insn "*arm_zero_extendqisi2addsi"
3919 [(set (match_operand:SI 0 "s_register_operand" "=r")
3920 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3921 (match_operand:SI 2 "s_register_operand" "r")))]
3923 "uxtab%?\\t%0, %2, %1"
3924 [(set_attr "predicable" "yes")
3925 (set_attr "insn" "xtab")
3926 (set_attr "type" "alu_shift")]
3930 [(set (match_operand:SI 0 "s_register_operand" "")
3931 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3932 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3933 "TARGET_32BIT && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3934 [(set (match_dup 2) (match_dup 1))
3935 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3940 [(set (match_operand:SI 0 "s_register_operand" "")
3941 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
3942 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3943 "TARGET_32BIT && (GET_CODE (operands[1]) != MEM) && BYTES_BIG_ENDIAN"
3944 [(set (match_dup 2) (match_dup 1))
3945 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3949 (define_insn "*compareqi_eq0"
3950 [(set (reg:CC_Z CC_REGNUM)
3951 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3955 [(set_attr "conds" "set")]
3958 (define_expand "extendhisi2"
3960 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3962 (set (match_operand:SI 0 "s_register_operand" "")
3963 (ashiftrt:SI (match_dup 2)
3968 if (GET_CODE (operands[1]) == MEM)
3972 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
3977 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3978 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3983 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3985 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3989 if (!s_register_operand (operands[1], HImode))
3990 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3995 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
3997 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3998 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4003 operands[1] = gen_lowpart (SImode, operands[1]);
4004 operands[2] = gen_reg_rtx (SImode);
4008 (define_insn "thumb1_extendhisi2"
4009 [(set (match_operand:SI 0 "register_operand" "=l")
4010 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
4011 (clobber (match_scratch:SI 2 "=&l"))]
4012 "TARGET_THUMB1 && !arm_arch6"
4016 rtx mem = XEXP (operands[1], 0);
4018 /* This code used to try to use 'V', and fix the address only if it was
4019 offsettable, but this fails for e.g. REG+48 because 48 is outside the
4020 range of QImode offsets, and offsettable_address_p does a QImode
4023 if (GET_CODE (mem) == CONST)
4024 mem = XEXP (mem, 0);
4026 if (GET_CODE (mem) == LABEL_REF)
4027 return \"ldr\\t%0, %1\";
4029 if (GET_CODE (mem) == PLUS)
4031 rtx a = XEXP (mem, 0);
4032 rtx b = XEXP (mem, 1);
4034 if (GET_CODE (a) == LABEL_REF
4035 && GET_CODE (b) == CONST_INT)
4036 return \"ldr\\t%0, %1\";
4038 if (GET_CODE (b) == REG)
4039 return \"ldrsh\\t%0, %1\";
4047 ops[2] = const0_rtx;
4050 gcc_assert (GET_CODE (ops[1]) == REG);
4052 ops[0] = operands[0];
4053 ops[3] = operands[2];
4054 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
4057 [(set_attr "length" "4")
4058 (set_attr "type" "load_byte")
4059 (set_attr "pool_range" "1020")]
4062 ;; We used to have an early-clobber on the scratch register here.
4063 ;; However, there's a bug somewhere in reload which means that this
4064 ;; can be partially ignored during spill allocation if the memory
4065 ;; address also needs reloading; this causes us to die later on when
4066 ;; we try to verify the operands. Fortunately, we don't really need
4067 ;; the early-clobber: we can always use operand 0 if operand 2
4068 ;; overlaps the address.
4069 (define_insn "*thumb1_extendhisi2_insn_v6"
4070 [(set (match_operand:SI 0 "register_operand" "=l,l")
4071 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
4072 (clobber (match_scratch:SI 2 "=X,l"))]
4073 "TARGET_THUMB1 && arm_arch6"
4079 if (which_alternative == 0)
4080 return \"sxth\\t%0, %1\";
4082 mem = XEXP (operands[1], 0);
4084 /* This code used to try to use 'V', and fix the address only if it was
4085 offsettable, but this fails for e.g. REG+48 because 48 is outside the
4086 range of QImode offsets, and offsettable_address_p does a QImode
4089 if (GET_CODE (mem) == CONST)
4090 mem = XEXP (mem, 0);
4092 if (GET_CODE (mem) == LABEL_REF)
4093 return \"ldr\\t%0, %1\";
4095 if (GET_CODE (mem) == PLUS)
4097 rtx a = XEXP (mem, 0);
4098 rtx b = XEXP (mem, 1);
4100 if (GET_CODE (a) == LABEL_REF
4101 && GET_CODE (b) == CONST_INT)
4102 return \"ldr\\t%0, %1\";
4104 if (GET_CODE (b) == REG)
4105 return \"ldrsh\\t%0, %1\";
4113 ops[2] = const0_rtx;
4116 gcc_assert (GET_CODE (ops[1]) == REG);
4118 ops[0] = operands[0];
4119 if (reg_mentioned_p (operands[2], ops[1]))
4122 ops[3] = operands[2];
4123 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
4126 [(set_attr "length" "2,4")
4127 (set_attr "type" "alu_shift,load_byte")
4128 (set_attr "pool_range" "*,1020")]
4131 ;; This pattern will only be used when ldsh is not available
4132 (define_expand "extendhisi2_mem"
4133 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4135 (zero_extend:SI (match_dup 7)))
4136 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
4137 (set (match_operand:SI 0 "" "")
4138 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
4143 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4145 mem1 = change_address (operands[1], QImode, addr);
4146 mem2 = change_address (operands[1], QImode, plus_constant (addr, 1));
4147 operands[0] = gen_lowpart (SImode, operands[0]);
4149 operands[2] = gen_reg_rtx (SImode);
4150 operands[3] = gen_reg_rtx (SImode);
4151 operands[6] = gen_reg_rtx (SImode);
4154 if (BYTES_BIG_ENDIAN)
4156 operands[4] = operands[2];
4157 operands[5] = operands[3];
4161 operands[4] = operands[3];
4162 operands[5] = operands[2];
4167 (define_insn "*arm_extendhisi2"
4168 [(set (match_operand:SI 0 "s_register_operand" "=r")
4169 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4170 "TARGET_ARM && arm_arch4 && !arm_arch6"
4171 "ldr%(sh%)\\t%0, %1"
4172 [(set_attr "type" "load_byte")
4173 (set_attr "predicable" "yes")
4174 (set_attr "pool_range" "256")
4175 (set_attr "neg_pool_range" "244")]
4178 ;; ??? Check Thumb-2 pool range
4179 (define_insn "*arm_extendhisi2_v6"
4180 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4181 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4182 "TARGET_32BIT && arm_arch6"
4186 [(set_attr "type" "alu_shift,load_byte")
4187 (set_attr "predicable" "yes")
4188 (set_attr "pool_range" "*,256")
4189 (set_attr "neg_pool_range" "*,244")]
4192 (define_insn "*arm_extendhisi2addsi"
4193 [(set (match_operand:SI 0 "s_register_operand" "=r")
4194 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4195 (match_operand:SI 2 "s_register_operand" "r")))]
4197 "sxtah%?\\t%0, %2, %1"
4200 (define_expand "extendqihi2"
4202 (ashift:SI (match_operand:QI 1 "general_operand" "")
4204 (set (match_operand:HI 0 "s_register_operand" "")
4205 (ashiftrt:SI (match_dup 2)
4210 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
4212 emit_insn (gen_rtx_SET (VOIDmode,
4214 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
4217 if (!s_register_operand (operands[1], QImode))
4218 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4219 operands[0] = gen_lowpart (SImode, operands[0]);
4220 operands[1] = gen_lowpart (SImode, operands[1]);
4221 operands[2] = gen_reg_rtx (SImode);
4225 (define_insn "*arm_extendqihi_insn"
4226 [(set (match_operand:HI 0 "s_register_operand" "=r")
4227 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
4228 "TARGET_ARM && arm_arch4"
4229 "ldr%(sb%)\\t%0, %1"
4230 [(set_attr "type" "load_byte")
4231 (set_attr "predicable" "yes")
4232 (set_attr "pool_range" "256")
4233 (set_attr "neg_pool_range" "244")]
4236 (define_expand "extendqisi2"
4238 (ashift:SI (match_operand:QI 1 "general_operand" "")
4240 (set (match_operand:SI 0 "s_register_operand" "")
4241 (ashiftrt:SI (match_dup 2)
4246 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
4248 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4249 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4253 if (!s_register_operand (operands[1], QImode))
4254 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4258 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4259 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4263 operands[1] = gen_lowpart (SImode, operands[1]);
4264 operands[2] = gen_reg_rtx (SImode);
4268 (define_insn "*arm_extendqisi"
4269 [(set (match_operand:SI 0 "s_register_operand" "=r")
4270 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
4271 "TARGET_ARM && arm_arch4 && !arm_arch6"
4272 "ldr%(sb%)\\t%0, %1"
4273 [(set_attr "type" "load_byte")
4274 (set_attr "predicable" "yes")
4275 (set_attr "pool_range" "256")
4276 (set_attr "neg_pool_range" "244")]
4279 (define_insn "*arm_extendqisi_v6"
4280 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4281 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
4282 "TARGET_ARM && arm_arch6"
4286 [(set_attr "type" "alu_shift,load_byte")
4287 (set_attr "predicable" "yes")
4288 (set_attr "pool_range" "*,256")
4289 (set_attr "neg_pool_range" "*,244")]
4292 (define_insn "*arm_extendqisi2addsi"
4293 [(set (match_operand:SI 0 "s_register_operand" "=r")
4294 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
4295 (match_operand:SI 2 "s_register_operand" "r")))]
4297 "sxtab%?\\t%0, %2, %1"
4298 [(set_attr "type" "alu_shift")
4299 (set_attr "insn" "xtab")
4300 (set_attr "predicable" "yes")]
4303 (define_insn "*thumb1_extendqisi2"
4304 [(set (match_operand:SI 0 "register_operand" "=l,l")
4305 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
4306 "TARGET_THUMB1 && !arm_arch6"
4310 rtx mem = XEXP (operands[1], 0);
4312 if (GET_CODE (mem) == CONST)
4313 mem = XEXP (mem, 0);
4315 if (GET_CODE (mem) == LABEL_REF)
4316 return \"ldr\\t%0, %1\";
4318 if (GET_CODE (mem) == PLUS
4319 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
4320 return \"ldr\\t%0, %1\";
4322 if (which_alternative == 0)
4323 return \"ldrsb\\t%0, %1\";
4325 ops[0] = operands[0];
4327 if (GET_CODE (mem) == PLUS)
4329 rtx a = XEXP (mem, 0);
4330 rtx b = XEXP (mem, 1);
4335 if (GET_CODE (a) == REG)
4337 if (GET_CODE (b) == REG)
4338 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
4339 else if (REGNO (a) == REGNO (ops[0]))
4341 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
4342 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
4343 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
4346 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4350 gcc_assert (GET_CODE (b) == REG);
4351 if (REGNO (b) == REGNO (ops[0]))
4353 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
4354 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
4355 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
4358 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4361 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
4363 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
4364 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
4365 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
4370 ops[2] = const0_rtx;
4372 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4376 [(set_attr "length" "2,6")
4377 (set_attr "type" "load_byte,load_byte")
4378 (set_attr "pool_range" "32,32")]
4381 (define_insn "*thumb1_extendqisi2_v6"
4382 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
4383 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
4384 "TARGET_THUMB1 && arm_arch6"
4390 if (which_alternative == 0)
4391 return \"sxtb\\t%0, %1\";
4393 mem = XEXP (operands[1], 0);
4395 if (GET_CODE (mem) == CONST)
4396 mem = XEXP (mem, 0);
4398 if (GET_CODE (mem) == LABEL_REF)
4399 return \"ldr\\t%0, %1\";
4401 if (GET_CODE (mem) == PLUS
4402 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
4403 return \"ldr\\t%0, %1\";
4405 if (which_alternative == 0)
4406 return \"ldrsb\\t%0, %1\";
4408 ops[0] = operands[0];
4410 if (GET_CODE (mem) == PLUS)
4412 rtx a = XEXP (mem, 0);
4413 rtx b = XEXP (mem, 1);
4418 if (GET_CODE (a) == REG)
4420 if (GET_CODE (b) == REG)
4421 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
4422 else if (REGNO (a) == REGNO (ops[0]))
4424 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
4425 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4428 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4432 gcc_assert (GET_CODE (b) == REG);
4433 if (REGNO (b) == REGNO (ops[0]))
4435 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
4436 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4439 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4442 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
4444 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
4445 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4450 ops[2] = const0_rtx;
4452 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4456 [(set_attr "length" "2,2,4")
4457 (set_attr "type" "alu_shift,load_byte,load_byte")
4458 (set_attr "pool_range" "*,32,32")]
4461 (define_expand "extendsfdf2"
4462 [(set (match_operand:DF 0 "s_register_operand" "")
4463 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
4464 "TARGET_32BIT && TARGET_HARD_FLOAT"
4468 ;; Move insns (including loads and stores)
4470 ;; XXX Just some ideas about movti.
4471 ;; I don't think these are a good idea on the arm, there just aren't enough
4473 ;;(define_expand "loadti"
4474 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4475 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4478 ;;(define_expand "storeti"
4479 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4480 ;; (match_operand:TI 1 "s_register_operand" ""))]
4483 ;;(define_expand "movti"
4484 ;; [(set (match_operand:TI 0 "general_operand" "")
4485 ;; (match_operand:TI 1 "general_operand" ""))]
4491 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4492 ;; operands[1] = copy_to_reg (operands[1]);
4493 ;; if (GET_CODE (operands[0]) == MEM)
4494 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4495 ;; else if (GET_CODE (operands[1]) == MEM)
4496 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4500 ;; emit_insn (insn);
4504 ;; Recognize garbage generated above.
4507 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4508 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4512 ;; register mem = (which_alternative < 3);
4513 ;; register const char *template;
4515 ;; operands[mem] = XEXP (operands[mem], 0);
4516 ;; switch (which_alternative)
4518 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4519 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4520 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4521 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4522 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4523 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4525 ;; output_asm_insn (template, operands);
4529 (define_expand "movdi"
4530 [(set (match_operand:DI 0 "general_operand" "")
4531 (match_operand:DI 1 "general_operand" ""))]
4534 if (can_create_pseudo_p ())
4536 if (GET_CODE (operands[0]) != REG)
4537 operands[1] = force_reg (DImode, operands[1]);
4542 (define_insn "*arm_movdi"
4543 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
4544 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
4546 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4548 && ( register_operand (operands[0], DImode)
4549 || register_operand (operands[1], DImode))"
4551 switch (which_alternative)
4558 return output_move_double (operands);
4561 [(set_attr "length" "8,12,16,8,8")
4562 (set_attr "type" "*,*,*,load2,store2")
4563 (set_attr "pool_range" "*,*,*,1020,*")
4564 (set_attr "neg_pool_range" "*,*,*,1008,*")]
4568 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4569 (match_operand:ANY64 1 "const_double_operand" ""))]
4572 && (arm_const_double_inline_cost (operands[1])
4573 <= ((optimize_size || arm_ld_sched) ? 3 : 4))"
4576 arm_split_constant (SET, SImode, curr_insn,
4577 INTVAL (gen_lowpart (SImode, operands[1])),
4578 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
4579 arm_split_constant (SET, SImode, curr_insn,
4580 INTVAL (gen_highpart_mode (SImode,
4581 GET_MODE (operands[0]),
4583 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
4588 ; If optimizing for size, or if we have load delay slots, then
4589 ; we want to split the constant into two separate operations.
4590 ; In both cases this may split a trivial part into a single data op
4591 ; leaving a single complex constant to load. We can also get longer
4592 ; offsets in a LDR which means we get better chances of sharing the pool
4593 ; entries. Finally, we can normally do a better job of scheduling
4594 ; LDR instructions than we can with LDM.
4595 ; This pattern will only match if the one above did not.
4597 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4598 (match_operand:ANY64 1 "const_double_operand" ""))]
4599 "TARGET_ARM && reload_completed
4600 && arm_const_double_by_parts (operands[1])"
4601 [(set (match_dup 0) (match_dup 1))
4602 (set (match_dup 2) (match_dup 3))]
4604 operands[2] = gen_highpart (SImode, operands[0]);
4605 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
4607 operands[0] = gen_lowpart (SImode, operands[0]);
4608 operands[1] = gen_lowpart (SImode, operands[1]);
4613 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4614 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
4615 "TARGET_EITHER && reload_completed"
4616 [(set (match_dup 0) (match_dup 1))
4617 (set (match_dup 2) (match_dup 3))]
4619 operands[2] = gen_highpart (SImode, operands[0]);
4620 operands[3] = gen_highpart (SImode, operands[1]);
4621 operands[0] = gen_lowpart (SImode, operands[0]);
4622 operands[1] = gen_lowpart (SImode, operands[1]);
4624 /* Handle a partial overlap. */
4625 if (rtx_equal_p (operands[0], operands[3]))
4627 rtx tmp0 = operands[0];
4628 rtx tmp1 = operands[1];
4630 operands[0] = operands[2];
4631 operands[1] = operands[3];
4638 ;; We can't actually do base+index doubleword loads if the index and
4639 ;; destination overlap. Split here so that we at least have chance to
4642 [(set (match_operand:DI 0 "s_register_operand" "")
4643 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
4644 (match_operand:SI 2 "s_register_operand" ""))))]
4646 && reg_overlap_mentioned_p (operands[0], operands[1])
4647 && reg_overlap_mentioned_p (operands[0], operands[2])"
4649 (plus:SI (match_dup 1)
4652 (mem:DI (match_dup 4)))]
4654 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
4658 ;;; ??? This should have alternatives for constants.
4659 ;;; ??? This was originally identical to the movdf_insn pattern.
4660 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4661 ;;; thumb_reorg with a memory reference.
4662 (define_insn "*thumb1_movdi_insn"
4663 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4664 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4666 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4667 && ( register_operand (operands[0], DImode)
4668 || register_operand (operands[1], DImode))"
4671 switch (which_alternative)
4675 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4676 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4677 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4679 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4681 operands[1] = GEN_INT (- INTVAL (operands[1]));
4682 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4684 return \"ldmia\\t%1, {%0, %H0}\";
4686 return \"stmia\\t%0, {%1, %H1}\";
4688 return thumb_load_double_from_address (operands);
4690 operands[2] = gen_rtx_MEM (SImode,
4691 plus_constant (XEXP (operands[0], 0), 4));
4692 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4695 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4696 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4697 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4700 [(set_attr "length" "4,4,6,2,2,6,4,4")
4701 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4702 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4705 (define_expand "movsi"
4706 [(set (match_operand:SI 0 "general_operand" "")
4707 (match_operand:SI 1 "general_operand" ""))]
4711 rtx base, offset, tmp;
4715 /* Everything except mem = const or mem = mem can be done easily. */
4716 if (GET_CODE (operands[0]) == MEM)
4717 operands[1] = force_reg (SImode, operands[1]);
4718 if (arm_general_register_operand (operands[0], SImode)
4719 && GET_CODE (operands[1]) == CONST_INT
4720 && !(const_ok_for_arm (INTVAL (operands[1]))
4721 || const_ok_for_arm (~INTVAL (operands[1]))))
4723 arm_split_constant (SET, SImode, NULL_RTX,
4724 INTVAL (operands[1]), operands[0], NULL_RTX,
4725 optimize && can_create_pseudo_p ());
4729 else /* TARGET_THUMB1... */
4731 if (can_create_pseudo_p ())
4733 if (GET_CODE (operands[0]) != REG)
4734 operands[1] = force_reg (SImode, operands[1]);
4738 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
4740 split_const (operands[1], &base, &offset);
4741 if (GET_CODE (base) == SYMBOL_REF
4742 && !offset_within_block_p (base, INTVAL (offset)))
4744 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
4745 emit_move_insn (tmp, base);
4746 emit_insn (gen_addsi3 (operands[0], tmp, offset));
4751 /* Recognize the case where operand[1] is a reference to thread-local
4752 data and load its address to a register. */
4753 if (arm_tls_referenced_p (operands[1]))
4755 rtx tmp = operands[1];
4758 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4760 addend = XEXP (XEXP (tmp, 0), 1);
4761 tmp = XEXP (XEXP (tmp, 0), 0);
4764 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4765 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
4767 tmp = legitimize_tls_address (tmp,
4768 !can_create_pseudo_p () ? operands[0] : 0);
4771 tmp = gen_rtx_PLUS (SImode, tmp, addend);
4772 tmp = force_operand (tmp, operands[0]);
4777 && (CONSTANT_P (operands[1])
4778 || symbol_mentioned_p (operands[1])
4779 || label_mentioned_p (operands[1])))
4780 operands[1] = legitimize_pic_address (operands[1], SImode,
4781 (!can_create_pseudo_p ()
4788 (define_insn "*arm_movsi_insn"
4789 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r, m")
4790 (match_operand:SI 1 "general_operand" "rI,K,N,mi,r"))]
4791 "TARGET_ARM && ! TARGET_IWMMXT
4792 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4793 && ( register_operand (operands[0], SImode)
4794 || register_operand (operands[1], SImode))"
4801 [(set_attr "type" "*,*,*,load1,store1")
4802 (set_attr "predicable" "yes")
4803 (set_attr "pool_range" "*,*,*,4096,*")
4804 (set_attr "neg_pool_range" "*,*,*,4084,*")]
4808 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4809 (match_operand:SI 1 "const_int_operand" ""))]
4811 && (!(const_ok_for_arm (INTVAL (operands[1]))
4812 || const_ok_for_arm (~INTVAL (operands[1]))))"
4813 [(clobber (const_int 0))]
4815 arm_split_constant (SET, SImode, NULL_RTX,
4816 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4821 (define_insn "*thumb1_movsi_insn"
4822 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4823 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4825 && ( register_operand (operands[0], SImode)
4826 || register_operand (operands[1], SImode))"
4837 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4838 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4839 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4843 [(set (match_operand:SI 0 "register_operand" "")
4844 (match_operand:SI 1 "const_int_operand" ""))]
4845 "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
4846 [(set (match_dup 0) (match_dup 1))
4847 (set (match_dup 0) (neg:SI (match_dup 0)))]
4848 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4852 [(set (match_operand:SI 0 "register_operand" "")
4853 (match_operand:SI 1 "const_int_operand" ""))]
4854 "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
4855 [(set (match_dup 0) (match_dup 1))
4856 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4859 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4860 unsigned HOST_WIDE_INT mask = 0xff;
4863 for (i = 0; i < 25; i++)
4864 if ((val & (mask << i)) == val)
4867 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4871 operands[1] = GEN_INT (val >> i);
4872 operands[2] = GEN_INT (i);
4876 ;; When generating pic, we need to load the symbol offset into a register.
4877 ;; So that the optimizer does not confuse this with a normal symbol load
4878 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4879 ;; since that is the only type of relocation we can use.
4881 ;; The rather odd constraints on the following are to force reload to leave
4882 ;; the insn alone, and to force the minipool generation pass to then move
4883 ;; the GOT symbol to memory.
4885 (define_insn "pic_load_addr_arm"
4886 [(set (match_operand:SI 0 "s_register_operand" "=r")
4887 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4888 "TARGET_ARM && flag_pic"
4890 [(set_attr "type" "load1")
4891 (set (attr "pool_range") (const_int 4096))
4892 (set (attr "neg_pool_range") (const_int 4084))]
4895 (define_insn "pic_load_addr_thumb1"
4896 [(set (match_operand:SI 0 "s_register_operand" "=l")
4897 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4898 "TARGET_THUMB1 && flag_pic"
4900 [(set_attr "type" "load1")
4901 (set (attr "pool_range") (const_int 1024))]
4904 (define_insn "pic_add_dot_plus_four"
4905 [(set (match_operand:SI 0 "register_operand" "=r")
4906 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
4907 (const (plus:SI (pc) (const_int 4))))
4908 (match_operand 2 "" "")]
4912 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
4913 INTVAL (operands[2]));
4914 return \"add\\t%0, %|pc\";
4916 [(set_attr "length" "2")]
4919 (define_insn "pic_add_dot_plus_eight"
4920 [(set (match_operand:SI 0 "register_operand" "=r")
4921 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
4922 (const (plus:SI (pc) (const_int 8))))
4923 (match_operand 2 "" "")]
4927 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
4928 INTVAL (operands[2]));
4929 return \"add%?\\t%0, %|pc, %1\";
4931 [(set_attr "predicable" "yes")]
4934 (define_insn "tls_load_dot_plus_eight"
4935 [(set (match_operand:SI 0 "register_operand" "+r")
4936 (mem:SI (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
4937 (const (plus:SI (pc) (const_int 8))))
4938 (match_operand 2 "" "")]
4942 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
4943 INTVAL (operands[2]));
4944 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
4946 [(set_attr "predicable" "yes")]
4949 ;; PIC references to local variables can generate pic_add_dot_plus_eight
4950 ;; followed by a load. These sequences can be crunched down to
4951 ;; tls_load_dot_plus_eight by a peephole.
4954 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4955 (unspec:SI [(plus:SI (match_operand:SI 3 "register_operand" "")
4956 (const (plus:SI (pc) (const_int 8))))]
4958 (use (label_ref (match_operand 1 "" "")))])
4959 (set (match_operand:SI 2 "register_operand" "") (mem:SI (match_dup 0)))]
4960 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
4961 [(parallel [(set (match_dup 2)
4962 (mem:SI (unspec:SI [(plus:SI (match_dup 3)
4963 (const (plus:SI (pc) (const_int 8))))]
4965 (use (label_ref (match_dup 1)))])]
4969 (define_insn "pic_offset_arm"
4970 [(set (match_operand:SI 0 "register_operand" "=r")
4971 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
4972 (unspec:SI [(match_operand:SI 2 "" "X")]
4973 UNSPEC_PIC_OFFSET))))]
4974 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
4975 "ldr%?\\t%0, [%1,%2]"
4976 [(set_attr "type" "load1")]
4979 (define_expand "builtin_setjmp_receiver"
4980 [(label_ref (match_operand 0 "" ""))]
4984 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
4986 if (arm_pic_register != INVALID_REGNUM)
4987 arm_load_pic_register (1UL << 3);
4991 ;; If copying one reg to another we can set the condition codes according to
4992 ;; its value. Such a move is common after a return from subroutine and the
4993 ;; result is being tested against zero.
4995 (define_insn "*movsi_compare0"
4996 [(set (reg:CC CC_REGNUM)
4997 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4999 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5005 [(set_attr "conds" "set")]
5008 ;; Subroutine to store a half word from a register into memory.
5009 ;; Operand 0 is the source register (HImode)
5010 ;; Operand 1 is the destination address in a register (SImode)
5012 ;; In both this routine and the next, we must be careful not to spill
5013 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5014 ;; can generate unrecognizable rtl.
5016 (define_expand "storehi"
5017 [;; store the low byte
5018 (set (match_operand 1 "" "") (match_dup 3))
5019 ;; extract the high byte
5021 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5022 ;; store the high byte
5023 (set (match_dup 4) (match_dup 5))]
5027 rtx op1 = operands[1];
5028 rtx addr = XEXP (op1, 0);
5029 enum rtx_code code = GET_CODE (addr);
5031 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
5033 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5035 operands[4] = adjust_address (op1, QImode, 1);
5036 operands[1] = adjust_address (operands[1], QImode, 0);
5037 operands[3] = gen_lowpart (QImode, operands[0]);
5038 operands[0] = gen_lowpart (SImode, operands[0]);
5039 operands[2] = gen_reg_rtx (SImode);
5040 operands[5] = gen_lowpart (QImode, operands[2]);
5044 (define_expand "storehi_bigend"
5045 [(set (match_dup 4) (match_dup 3))
5047 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5048 (set (match_operand 1 "" "") (match_dup 5))]
5052 rtx op1 = operands[1];
5053 rtx addr = XEXP (op1, 0);
5054 enum rtx_code code = GET_CODE (addr);
5056 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
5058 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5060 operands[4] = adjust_address (op1, QImode, 1);
5061 operands[1] = adjust_address (operands[1], QImode, 0);
5062 operands[3] = gen_lowpart (QImode, operands[0]);
5063 operands[0] = gen_lowpart (SImode, operands[0]);
5064 operands[2] = gen_reg_rtx (SImode);
5065 operands[5] = gen_lowpart (QImode, operands[2]);
5069 ;; Subroutine to store a half word integer constant into memory.
5070 (define_expand "storeinthi"
5071 [(set (match_operand 0 "" "")
5072 (match_operand 1 "" ""))
5073 (set (match_dup 3) (match_dup 2))]
5077 HOST_WIDE_INT value = INTVAL (operands[1]);
5078 rtx addr = XEXP (operands[0], 0);
5079 rtx op0 = operands[0];
5080 enum rtx_code code = GET_CODE (addr);
5082 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
5084 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5086 operands[1] = gen_reg_rtx (SImode);
5087 if (BYTES_BIG_ENDIAN)
5089 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5090 if ((value & 255) == ((value >> 8) & 255))
5091 operands[2] = operands[1];
5094 operands[2] = gen_reg_rtx (SImode);
5095 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
5100 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
5101 if ((value & 255) == ((value >> 8) & 255))
5102 operands[2] = operands[1];
5105 operands[2] = gen_reg_rtx (SImode);
5106 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
5110 operands[3] = adjust_address (op0, QImode, 1);
5111 operands[0] = adjust_address (operands[0], QImode, 0);
5112 operands[2] = gen_lowpart (QImode, operands[2]);
5113 operands[1] = gen_lowpart (QImode, operands[1]);
5117 (define_expand "storehi_single_op"
5118 [(set (match_operand:HI 0 "memory_operand" "")
5119 (match_operand:HI 1 "general_operand" ""))]
5120 "TARGET_32BIT && arm_arch4"
5122 if (!s_register_operand (operands[1], HImode))
5123 operands[1] = copy_to_mode_reg (HImode, operands[1]);
5127 (define_expand "movhi"
5128 [(set (match_operand:HI 0 "general_operand" "")
5129 (match_operand:HI 1 "general_operand" ""))]
5134 if (can_create_pseudo_p ())
5136 if (GET_CODE (operands[0]) == MEM)
5140 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
5143 if (GET_CODE (operands[1]) == CONST_INT)
5144 emit_insn (gen_storeinthi (operands[0], operands[1]));
5147 if (GET_CODE (operands[1]) == MEM)
5148 operands[1] = force_reg (HImode, operands[1]);
5149 if (BYTES_BIG_ENDIAN)
5150 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
5152 emit_insn (gen_storehi (operands[1], operands[0]));
5156 /* Sign extend a constant, and keep it in an SImode reg. */
5157 else if (GET_CODE (operands[1]) == CONST_INT)
5159 rtx reg = gen_reg_rtx (SImode);
5160 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5162 /* If the constant is already valid, leave it alone. */
5163 if (!const_ok_for_arm (val))
5165 /* If setting all the top bits will make the constant
5166 loadable in a single instruction, then set them.
5167 Otherwise, sign extend the number. */
5169 if (const_ok_for_arm (~(val | ~0xffff)))
5171 else if (val & 0x8000)
5175 emit_insn (gen_movsi (reg, GEN_INT (val)));
5176 operands[1] = gen_lowpart (HImode, reg);
5178 else if (arm_arch4 && optimize && can_create_pseudo_p ()
5179 && GET_CODE (operands[1]) == MEM)
5181 rtx reg = gen_reg_rtx (SImode);
5183 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5184 operands[1] = gen_lowpart (HImode, reg);
5186 else if (!arm_arch4)
5188 if (GET_CODE (operands[1]) == MEM)
5191 rtx offset = const0_rtx;
5192 rtx reg = gen_reg_rtx (SImode);
5194 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
5195 || (GET_CODE (base) == PLUS
5196 && (GET_CODE (offset = XEXP (base, 1))
5198 && ((INTVAL(offset) & 1) != 1)
5199 && GET_CODE (base = XEXP (base, 0)) == REG))
5200 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
5204 new = widen_memory_access (operands[1], SImode,
5205 ((INTVAL (offset) & ~3)
5206 - INTVAL (offset)));
5207 emit_insn (gen_movsi (reg, new));
5208 if (((INTVAL (offset) & 2) != 0)
5209 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
5211 rtx reg2 = gen_reg_rtx (SImode);
5213 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
5218 emit_insn (gen_movhi_bytes (reg, operands[1]));
5220 operands[1] = gen_lowpart (HImode, reg);
5224 /* Handle loading a large integer during reload. */
5225 else if (GET_CODE (operands[1]) == CONST_INT
5226 && !const_ok_for_arm (INTVAL (operands[1]))
5227 && !const_ok_for_arm (~INTVAL (operands[1])))
5229 /* Writing a constant to memory needs a scratch, which should
5230 be handled with SECONDARY_RELOADs. */
5231 gcc_assert (GET_CODE (operands[0]) == REG);
5233 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5234 emit_insn (gen_movsi (operands[0], operands[1]));
5238 else if (TARGET_THUMB2)
5240 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
5241 if (can_create_pseudo_p ())
5243 if (GET_CODE (operands[0]) != REG)
5244 operands[1] = force_reg (HImode, operands[1]);
5245 /* Zero extend a constant, and keep it in an SImode reg. */
5246 else if (GET_CODE (operands[1]) == CONST_INT)
5248 rtx reg = gen_reg_rtx (SImode);
5249 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5251 emit_insn (gen_movsi (reg, GEN_INT (val)));
5252 operands[1] = gen_lowpart (HImode, reg);
5256 else /* TARGET_THUMB1 */
5258 if (can_create_pseudo_p ())
5260 if (GET_CODE (operands[1]) == CONST_INT)
5262 rtx reg = gen_reg_rtx (SImode);
5264 emit_insn (gen_movsi (reg, operands[1]));
5265 operands[1] = gen_lowpart (HImode, reg);
5268 /* ??? We shouldn't really get invalid addresses here, but this can
5269 happen if we are passed a SP (never OK for HImode/QImode) or
5270 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
5271 HImode/QImode) relative address. */
5272 /* ??? This should perhaps be fixed elsewhere, for instance, in
5273 fixup_stack_1, by checking for other kinds of invalid addresses,
5274 e.g. a bare reference to a virtual register. This may confuse the
5275 alpha though, which must handle this case differently. */
5276 if (GET_CODE (operands[0]) == MEM
5277 && !memory_address_p (GET_MODE (operands[0]),
5278 XEXP (operands[0], 0)))
5280 = replace_equiv_address (operands[0],
5281 copy_to_reg (XEXP (operands[0], 0)));
5283 if (GET_CODE (operands[1]) == MEM
5284 && !memory_address_p (GET_MODE (operands[1]),
5285 XEXP (operands[1], 0)))
5287 = replace_equiv_address (operands[1],
5288 copy_to_reg (XEXP (operands[1], 0)));
5290 if (GET_CODE (operands[1]) == MEM && optimize > 0)
5292 rtx reg = gen_reg_rtx (SImode);
5294 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5295 operands[1] = gen_lowpart (HImode, reg);
5298 if (GET_CODE (operands[0]) == MEM)
5299 operands[1] = force_reg (HImode, operands[1]);
5301 else if (GET_CODE (operands[1]) == CONST_INT
5302 && !satisfies_constraint_I (operands[1]))
5304 /* Handle loading a large integer during reload. */
5306 /* Writing a constant to memory needs a scratch, which should
5307 be handled with SECONDARY_RELOADs. */
5308 gcc_assert (GET_CODE (operands[0]) == REG);
5310 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5311 emit_insn (gen_movsi (operands[0], operands[1]));
5318 (define_insn "*thumb1_movhi_insn"
5319 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5320 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
5322 && ( register_operand (operands[0], HImode)
5323 || register_operand (operands[1], HImode))"
5325 switch (which_alternative)
5327 case 0: return \"add %0, %1, #0\";
5328 case 2: return \"strh %1, %0\";
5329 case 3: return \"mov %0, %1\";
5330 case 4: return \"mov %0, %1\";
5331 case 5: return \"mov %0, %1\";
5332 default: gcc_unreachable ();
5334 /* The stack pointer can end up being taken as an index register.
5335 Catch this case here and deal with it. */
5336 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
5337 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
5338 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
5341 ops[0] = operands[0];
5342 ops[1] = XEXP (XEXP (operands[1], 0), 0);
5344 output_asm_insn (\"mov %0, %1\", ops);
5346 XEXP (XEXP (operands[1], 0), 0) = operands[0];
5349 return \"ldrh %0, %1\";
5351 [(set_attr "length" "2,4,2,2,2,2")
5352 (set_attr "type" "*,load1,store1,*,*,*")]
5356 (define_expand "movhi_bytes"
5357 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5359 (zero_extend:SI (match_dup 6)))
5360 (set (match_operand:SI 0 "" "")
5361 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
5366 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5368 mem1 = change_address (operands[1], QImode, addr);
5369 mem2 = change_address (operands[1], QImode, plus_constant (addr, 1));
5370 operands[0] = gen_lowpart (SImode, operands[0]);
5372 operands[2] = gen_reg_rtx (SImode);
5373 operands[3] = gen_reg_rtx (SImode);
5376 if (BYTES_BIG_ENDIAN)
5378 operands[4] = operands[2];
5379 operands[5] = operands[3];
5383 operands[4] = operands[3];
5384 operands[5] = operands[2];
5389 (define_expand "movhi_bigend"
5391 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
5394 (ashiftrt:SI (match_dup 2) (const_int 16)))
5395 (set (match_operand:HI 0 "s_register_operand" "")
5399 operands[2] = gen_reg_rtx (SImode);
5400 operands[3] = gen_reg_rtx (SImode);
5401 operands[4] = gen_lowpart (HImode, operands[3]);
5405 ;; Pattern to recognize insn generated default case above
5406 (define_insn "*movhi_insn_arch4"
5407 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
5408 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
5411 && (GET_CODE (operands[1]) != CONST_INT
5412 || const_ok_for_arm (INTVAL (operands[1]))
5413 || const_ok_for_arm (~INTVAL (operands[1])))"
5415 mov%?\\t%0, %1\\t%@ movhi
5416 mvn%?\\t%0, #%B1\\t%@ movhi
5417 str%(h%)\\t%1, %0\\t%@ movhi
5418 ldr%(h%)\\t%0, %1\\t%@ movhi"
5419 [(set_attr "type" "*,*,store1,load1")
5420 (set_attr "predicable" "yes")
5421 (set_attr "pool_range" "*,*,*,256")
5422 (set_attr "neg_pool_range" "*,*,*,244")]
5425 (define_insn "*movhi_bytes"
5426 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
5427 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
5430 mov%?\\t%0, %1\\t%@ movhi
5431 mvn%?\\t%0, #%B1\\t%@ movhi"
5432 [(set_attr "predicable" "yes")]
5435 (define_expand "thumb_movhi_clobber"
5436 [(set (match_operand:HI 0 "memory_operand" "")
5437 (match_operand:HI 1 "register_operand" ""))
5438 (clobber (match_operand:DI 2 "register_operand" ""))]
5441 if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
5442 && REGNO (operands[1]) <= LAST_LO_REGNUM)
5444 emit_insn (gen_movhi (operands[0], operands[1]));
5447 /* XXX Fixme, need to handle other cases here as well. */
5452 ;; We use a DImode scratch because we may occasionally need an additional
5453 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
5454 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
5455 (define_expand "reload_outhi"
5456 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
5457 (match_operand:HI 1 "s_register_operand" "r")
5458 (match_operand:DI 2 "s_register_operand" "=&l")])]
5461 arm_reload_out_hi (operands);
5463 thumb_reload_out_hi (operands);
5468 (define_expand "reload_inhi"
5469 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
5470 (match_operand:HI 1 "arm_reload_memory_operand" "o")
5471 (match_operand:DI 2 "s_register_operand" "=&r")])]
5475 arm_reload_in_hi (operands);
5477 thumb_reload_out_hi (operands);
5481 (define_expand "movqi"
5482 [(set (match_operand:QI 0 "general_operand" "")
5483 (match_operand:QI 1 "general_operand" ""))]
5486 /* Everything except mem = const or mem = mem can be done easily */
5488 if (can_create_pseudo_p ())
5490 if (GET_CODE (operands[1]) == CONST_INT)
5492 rtx reg = gen_reg_rtx (SImode);
5494 emit_insn (gen_movsi (reg, operands[1]));
5495 operands[1] = gen_lowpart (QImode, reg);
5500 /* ??? We shouldn't really get invalid addresses here, but this can
5501 happen if we are passed a SP (never OK for HImode/QImode) or
5502 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
5503 HImode/QImode) relative address. */
5504 /* ??? This should perhaps be fixed elsewhere, for instance, in
5505 fixup_stack_1, by checking for other kinds of invalid addresses,
5506 e.g. a bare reference to a virtual register. This may confuse the
5507 alpha though, which must handle this case differently. */
5508 if (GET_CODE (operands[0]) == MEM
5509 && !memory_address_p (GET_MODE (operands[0]),
5510 XEXP (operands[0], 0)))
5512 = replace_equiv_address (operands[0],
5513 copy_to_reg (XEXP (operands[0], 0)));
5514 if (GET_CODE (operands[1]) == MEM
5515 && !memory_address_p (GET_MODE (operands[1]),
5516 XEXP (operands[1], 0)))
5518 = replace_equiv_address (operands[1],
5519 copy_to_reg (XEXP (operands[1], 0)));
5522 if (GET_CODE (operands[1]) == MEM && optimize > 0)
5524 rtx reg = gen_reg_rtx (SImode);
5526 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
5527 operands[1] = gen_lowpart (QImode, reg);
5530 if (GET_CODE (operands[0]) == MEM)
5531 operands[1] = force_reg (QImode, operands[1]);
5533 else if (TARGET_THUMB
5534 && GET_CODE (operands[1]) == CONST_INT
5535 && !satisfies_constraint_I (operands[1]))
5537 /* Handle loading a large integer during reload. */
5539 /* Writing a constant to memory needs a scratch, which should
5540 be handled with SECONDARY_RELOADs. */
5541 gcc_assert (GET_CODE (operands[0]) == REG);
5543 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5544 emit_insn (gen_movsi (operands[0], operands[1]));
5551 (define_insn "*arm_movqi_insn"
5552 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5553 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
5555 && ( register_operand (operands[0], QImode)
5556 || register_operand (operands[1], QImode))"
5562 [(set_attr "type" "*,*,load1,store1")
5563 (set_attr "predicable" "yes")]
5566 (define_insn "*thumb1_movqi_insn"
5567 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5568 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5570 && ( register_operand (operands[0], QImode)
5571 || register_operand (operands[1], QImode))"
5579 [(set_attr "length" "2")
5580 (set_attr "type" "*,load1,store1,*,*,*")
5581 (set_attr "pool_range" "*,32,*,*,*,*")]
5584 (define_expand "movsf"
5585 [(set (match_operand:SF 0 "general_operand" "")
5586 (match_operand:SF 1 "general_operand" ""))]
5591 if (GET_CODE (operands[0]) == MEM)
5592 operands[1] = force_reg (SFmode, operands[1]);
5594 else /* TARGET_THUMB1 */
5596 if (can_create_pseudo_p ())
5598 if (GET_CODE (operands[0]) != REG)
5599 operands[1] = force_reg (SFmode, operands[1]);
5605 ;; Transform a floating-point move of a constant into a core register into
5606 ;; an SImode operation.
5608 [(set (match_operand:SF 0 "arm_general_register_operand" "")
5609 (match_operand:SF 1 "immediate_operand" ""))]
5612 && GET_CODE (operands[1]) == CONST_DOUBLE"
5613 [(set (match_dup 2) (match_dup 3))]
5615 operands[2] = gen_lowpart (SImode, operands[0]);
5616 operands[3] = gen_lowpart (SImode, operands[1]);
5617 if (operands[2] == 0 || operands[3] == 0)
5622 (define_insn "*arm_movsf_soft_insn"
5623 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5624 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5626 && TARGET_SOFT_FLOAT
5627 && (GET_CODE (operands[0]) != MEM
5628 || register_operand (operands[1], SFmode))"
5631 ldr%?\\t%0, %1\\t%@ float
5632 str%?\\t%1, %0\\t%@ float"
5633 [(set_attr "length" "4,4,4")
5634 (set_attr "predicable" "yes")
5635 (set_attr "type" "*,load1,store1")
5636 (set_attr "pool_range" "*,4096,*")
5637 (set_attr "neg_pool_range" "*,4084,*")]
5640 ;;; ??? This should have alternatives for constants.
5641 (define_insn "*thumb1_movsf_insn"
5642 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5643 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5645 && ( register_operand (operands[0], SFmode)
5646 || register_operand (operands[1], SFmode))"
5655 [(set_attr "length" "2")
5656 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5657 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5660 (define_expand "movdf"
5661 [(set (match_operand:DF 0 "general_operand" "")
5662 (match_operand:DF 1 "general_operand" ""))]
5667 if (GET_CODE (operands[0]) == MEM)
5668 operands[1] = force_reg (DFmode, operands[1]);
5670 else /* TARGET_THUMB */
5672 if (can_create_pseudo_p ())
5674 if (GET_CODE (operands[0]) != REG)
5675 operands[1] = force_reg (DFmode, operands[1]);
5681 ;; Reloading a df mode value stored in integer regs to memory can require a
5683 (define_expand "reload_outdf"
5684 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5685 (match_operand:DF 1 "s_register_operand" "r")
5686 (match_operand:SI 2 "s_register_operand" "=&r")]
5690 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5693 operands[2] = XEXP (operands[0], 0);
5694 else if (code == POST_INC || code == PRE_DEC)
5696 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5697 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5698 emit_insn (gen_movdi (operands[0], operands[1]));
5701 else if (code == PRE_INC)
5703 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5705 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5708 else if (code == POST_DEC)
5709 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5711 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5712 XEXP (XEXP (operands[0], 0), 1)));
5714 emit_insn (gen_rtx_SET (VOIDmode,
5715 replace_equiv_address (operands[0], operands[2]),
5718 if (code == POST_DEC)
5719 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5725 (define_insn "*movdf_soft_insn"
5726 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
5727 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
5728 "TARGET_ARM && TARGET_SOFT_FLOAT
5729 && ( register_operand (operands[0], DFmode)
5730 || register_operand (operands[1], DFmode))"
5732 switch (which_alternative)
5739 return output_move_double (operands);
5742 [(set_attr "length" "8,12,16,8,8")
5743 (set_attr "type" "*,*,*,load2,store2")
5744 (set_attr "pool_range" "1020")
5745 (set_attr "neg_pool_range" "1008")]
5748 ;;; ??? This should have alternatives for constants.
5749 ;;; ??? This was originally identical to the movdi_insn pattern.
5750 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5751 ;;; thumb_reorg with a memory reference.
5752 (define_insn "*thumb_movdf_insn"
5753 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5754 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5756 && ( register_operand (operands[0], DFmode)
5757 || register_operand (operands[1], DFmode))"
5759 switch (which_alternative)
5763 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5764 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5765 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5767 return \"ldmia\\t%1, {%0, %H0}\";
5769 return \"stmia\\t%0, {%1, %H1}\";
5771 return thumb_load_double_from_address (operands);
5773 operands[2] = gen_rtx_MEM (SImode,
5774 plus_constant (XEXP (operands[0], 0), 4));
5775 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5778 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5779 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5780 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5783 [(set_attr "length" "4,2,2,6,4,4")
5784 (set_attr "type" "*,load2,store2,load2,store2,*")
5785 (set_attr "pool_range" "*,*,*,1020,*,*")]
5788 (define_expand "movxf"
5789 [(set (match_operand:XF 0 "general_operand" "")
5790 (match_operand:XF 1 "general_operand" ""))]
5791 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
5793 if (GET_CODE (operands[0]) == MEM)
5794 operands[1] = force_reg (XFmode, operands[1]);
5800 ;; load- and store-multiple insns
5801 ;; The arm can load/store any set of registers, provided that they are in
5802 ;; ascending order; but that is beyond GCC so stick with what it knows.
5804 (define_expand "load_multiple"
5805 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5806 (match_operand:SI 1 "" ""))
5807 (use (match_operand:SI 2 "" ""))])]
5810 HOST_WIDE_INT offset = 0;
5812 /* Support only fixed point registers. */
5813 if (GET_CODE (operands[2]) != CONST_INT
5814 || INTVAL (operands[2]) > 14
5815 || INTVAL (operands[2]) < 2
5816 || GET_CODE (operands[1]) != MEM
5817 || GET_CODE (operands[0]) != REG
5818 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5819 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5823 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5824 force_reg (SImode, XEXP (operands[1], 0)),
5825 TRUE, FALSE, operands[1], &offset);
5828 ;; Load multiple with write-back
5830 (define_insn "*ldmsi_postinc4"
5831 [(match_parallel 0 "load_multiple_operation"
5832 [(set (match_operand:SI 1 "s_register_operand" "=r")
5833 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5835 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5836 (mem:SI (match_dup 2)))
5837 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5838 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5839 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5840 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5841 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5842 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5843 "TARGET_32BIT && XVECLEN (operands[0], 0) == 5"
5844 "ldm%(ia%)\\t%1!, {%3, %4, %5, %6}"
5845 [(set_attr "type" "load4")
5846 (set_attr "predicable" "yes")]
5849 (define_insn "*ldmsi_postinc4_thumb1"
5850 [(match_parallel 0 "load_multiple_operation"
5851 [(set (match_operand:SI 1 "s_register_operand" "=l")
5852 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5854 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5855 (mem:SI (match_dup 2)))
5856 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5857 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5858 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5859 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5860 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5861 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5862 "TARGET_THUMB1 && XVECLEN (operands[0], 0) == 5"
5863 "ldmia\\t%1!, {%3, %4, %5, %6}"
5864 [(set_attr "type" "load4")]
5867 (define_insn "*ldmsi_postinc3"
5868 [(match_parallel 0 "load_multiple_operation"
5869 [(set (match_operand:SI 1 "s_register_operand" "=r")
5870 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5872 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5873 (mem:SI (match_dup 2)))
5874 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5875 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5876 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5877 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5878 "TARGET_32BIT && XVECLEN (operands[0], 0) == 4"
5879 "ldm%(ia%)\\t%1!, {%3, %4, %5}"
5880 [(set_attr "type" "load3")
5881 (set_attr "predicable" "yes")]
5884 (define_insn "*ldmsi_postinc2"
5885 [(match_parallel 0 "load_multiple_operation"
5886 [(set (match_operand:SI 1 "s_register_operand" "=r")
5887 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5889 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5890 (mem:SI (match_dup 2)))
5891 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5892 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5893 "TARGET_32BIT && XVECLEN (operands[0], 0) == 3"
5894 "ldm%(ia%)\\t%1!, {%3, %4}"
5895 [(set_attr "type" "load2")
5896 (set_attr "predicable" "yes")]
5899 ;; Ordinary load multiple
5901 (define_insn "*ldmsi4"
5902 [(match_parallel 0 "load_multiple_operation"
5903 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5904 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5905 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5906 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5907 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5908 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5909 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5910 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5911 "TARGET_32BIT && XVECLEN (operands[0], 0) == 4"
5912 "ldm%(ia%)\\t%1, {%2, %3, %4, %5}"
5913 [(set_attr "type" "load4")
5914 (set_attr "predicable" "yes")]
5917 (define_insn "*ldmsi3"
5918 [(match_parallel 0 "load_multiple_operation"
5919 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5920 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5921 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5922 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5923 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5924 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5925 "TARGET_32BIT && XVECLEN (operands[0], 0) == 3"
5926 "ldm%(ia%)\\t%1, {%2, %3, %4}"
5927 [(set_attr "type" "load3")
5928 (set_attr "predicable" "yes")]
5931 (define_insn "*ldmsi2"
5932 [(match_parallel 0 "load_multiple_operation"
5933 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5934 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5935 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5936 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5937 "TARGET_32BIT && XVECLEN (operands[0], 0) == 2"
5938 "ldm%(ia%)\\t%1, {%2, %3}"
5939 [(set_attr "type" "load2")
5940 (set_attr "predicable" "yes")]
5943 (define_expand "store_multiple"
5944 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5945 (match_operand:SI 1 "" ""))
5946 (use (match_operand:SI 2 "" ""))])]
5949 HOST_WIDE_INT offset = 0;
5951 /* Support only fixed point registers. */
5952 if (GET_CODE (operands[2]) != CONST_INT
5953 || INTVAL (operands[2]) > 14
5954 || INTVAL (operands[2]) < 2
5955 || GET_CODE (operands[1]) != REG
5956 || GET_CODE (operands[0]) != MEM
5957 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5958 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5962 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5963 force_reg (SImode, XEXP (operands[0], 0)),
5964 TRUE, FALSE, operands[0], &offset);
5967 ;; Store multiple with write-back
5969 (define_insn "*stmsi_postinc4"
5970 [(match_parallel 0 "store_multiple_operation"
5971 [(set (match_operand:SI 1 "s_register_operand" "=r")
5972 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5974 (set (mem:SI (match_dup 2))
5975 (match_operand:SI 3 "arm_hard_register_operand" ""))
5976 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5977 (match_operand:SI 4 "arm_hard_register_operand" ""))
5978 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5979 (match_operand:SI 5 "arm_hard_register_operand" ""))
5980 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5981 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5982 "TARGET_32BIT && XVECLEN (operands[0], 0) == 5"
5983 "stm%(ia%)\\t%1!, {%3, %4, %5, %6}"
5984 [(set_attr "predicable" "yes")
5985 (set_attr "type" "store4")]
5988 (define_insn "*stmsi_postinc4_thumb1"
5989 [(match_parallel 0 "store_multiple_operation"
5990 [(set (match_operand:SI 1 "s_register_operand" "=l")
5991 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5993 (set (mem:SI (match_dup 2))
5994 (match_operand:SI 3 "arm_hard_register_operand" ""))
5995 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5996 (match_operand:SI 4 "arm_hard_register_operand" ""))
5997 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5998 (match_operand:SI 5 "arm_hard_register_operand" ""))
5999 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
6000 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
6001 "TARGET_THUMB1 && XVECLEN (operands[0], 0) == 5"
6002 "stmia\\t%1!, {%3, %4, %5, %6}"
6003 [(set_attr "type" "store4")]
6006 (define_insn "*stmsi_postinc3"
6007 [(match_parallel 0 "store_multiple_operation"
6008 [(set (match_operand:SI 1 "s_register_operand" "=r")
6009 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
6011 (set (mem:SI (match_dup 2))
6012 (match_operand:SI 3 "arm_hard_register_operand" ""))
6013 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
6014 (match_operand:SI 4 "arm_hard_register_operand" ""))
6015 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
6016 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
6017 "TARGET_32BIT && XVECLEN (operands[0], 0) == 4"
6018 "stm%(ia%)\\t%1!, {%3, %4, %5}"
6019 [(set_attr "predicable" "yes")
6020 (set_attr "type" "store3")]
6023 (define_insn "*stmsi_postinc2"
6024 [(match_parallel 0 "store_multiple_operation"
6025 [(set (match_operand:SI 1 "s_register_operand" "=r")
6026 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
6028 (set (mem:SI (match_dup 2))
6029 (match_operand:SI 3 "arm_hard_register_operand" ""))
6030 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
6031 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
6032 "TARGET_32BIT && XVECLEN (operands[0], 0) == 3"
6033 "stm%(ia%)\\t%1!, {%3, %4}"
6034 [(set_attr "predicable" "yes")
6035 (set_attr "type" "store2")]
6038 ;; Ordinary store multiple
6040 (define_insn "*stmsi4"
6041 [(match_parallel 0 "store_multiple_operation"
6042 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
6043 (match_operand:SI 2 "arm_hard_register_operand" ""))
6044 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
6045 (match_operand:SI 3 "arm_hard_register_operand" ""))
6046 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
6047 (match_operand:SI 4 "arm_hard_register_operand" ""))
6048 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
6049 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
6050 "TARGET_32BIT && XVECLEN (operands[0], 0) == 4"
6051 "stm%(ia%)\\t%1, {%2, %3, %4, %5}"
6052 [(set_attr "predicable" "yes")
6053 (set_attr "type" "store4")]
6056 (define_insn "*stmsi3"
6057 [(match_parallel 0 "store_multiple_operation"
6058 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
6059 (match_operand:SI 2 "arm_hard_register_operand" ""))
6060 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
6061 (match_operand:SI 3 "arm_hard_register_operand" ""))
6062 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
6063 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
6064 "TARGET_32BIT && XVECLEN (operands[0], 0) == 3"
6065 "stm%(ia%)\\t%1, {%2, %3, %4}"
6066 [(set_attr "predicable" "yes")
6067 (set_attr "type" "store3")]
6070 (define_insn "*stmsi2"
6071 [(match_parallel 0 "store_multiple_operation"
6072 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
6073 (match_operand:SI 2 "arm_hard_register_operand" ""))
6074 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
6075 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
6076 "TARGET_32BIT && XVECLEN (operands[0], 0) == 2"
6077 "stm%(ia%)\\t%1, {%2, %3}"
6078 [(set_attr "predicable" "yes")
6079 (set_attr "type" "store2")]
6082 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6083 ;; We could let this apply for blocks of less than this, but it clobbers so
6084 ;; many registers that there is then probably a better way.
6086 (define_expand "movmemqi"
6087 [(match_operand:BLK 0 "general_operand" "")
6088 (match_operand:BLK 1 "general_operand" "")
6089 (match_operand:SI 2 "const_int_operand" "")
6090 (match_operand:SI 3 "const_int_operand" "")]
6095 if (arm_gen_movmemqi (operands))
6099 else /* TARGET_THUMB1 */
6101 if ( INTVAL (operands[3]) != 4
6102 || INTVAL (operands[2]) > 48)
6105 thumb_expand_movmemqi (operands);
6111 ;; Thumb block-move insns
6113 (define_insn "movmem12b"
6114 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
6115 (mem:SI (match_operand:SI 3 "register_operand" "1")))
6116 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
6117 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
6118 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
6119 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
6120 (set (match_operand:SI 0 "register_operand" "=l")
6121 (plus:SI (match_dup 2) (const_int 12)))
6122 (set (match_operand:SI 1 "register_operand" "=l")
6123 (plus:SI (match_dup 3) (const_int 12)))
6124 (clobber (match_scratch:SI 4 "=&l"))
6125 (clobber (match_scratch:SI 5 "=&l"))
6126 (clobber (match_scratch:SI 6 "=&l"))]
6128 "* return thumb_output_move_mem_multiple (3, operands);"
6129 [(set_attr "length" "4")
6130 ; This isn't entirely accurate... It loads as well, but in terms of
6131 ; scheduling the following insn it is better to consider it as a store
6132 (set_attr "type" "store3")]
6135 (define_insn "movmem8b"
6136 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
6137 (mem:SI (match_operand:SI 3 "register_operand" "1")))
6138 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
6139 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
6140 (set (match_operand:SI 0 "register_operand" "=l")
6141 (plus:SI (match_dup 2) (const_int 8)))
6142 (set (match_operand:SI 1 "register_operand" "=l")
6143 (plus:SI (match_dup 3) (const_int 8)))
6144 (clobber (match_scratch:SI 4 "=&l"))
6145 (clobber (match_scratch:SI 5 "=&l"))]
6147 "* return thumb_output_move_mem_multiple (2, operands);"
6148 [(set_attr "length" "4")
6149 ; This isn't entirely accurate... It loads as well, but in terms of
6150 ; scheduling the following insn it is better to consider it as a store
6151 (set_attr "type" "store2")]
6156 ;; Compare & branch insns
6157 ;; The range calculations are based as follows:
6158 ;; For forward branches, the address calculation returns the address of
6159 ;; the next instruction. This is 2 beyond the branch instruction.
6160 ;; For backward branches, the address calculation returns the address of
6161 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6162 ;; instruction for the shortest sequence, and 4 before the branch instruction
6163 ;; if we have to jump around an unconditional branch.
6164 ;; To the basic branch range the PC offset must be added (this is +4).
6165 ;; So for forward branches we have
6166 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6167 ;; And for backward branches we have
6168 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6170 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6171 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6173 (define_expand "cbranchsi4"
6174 [(set (pc) (if_then_else
6175 (match_operator 0 "arm_comparison_operator"
6176 [(match_operand:SI 1 "s_register_operand" "")
6177 (match_operand:SI 2 "nonmemory_operand" "")])
6178 (label_ref (match_operand 3 "" ""))
6182 if (thumb1_cmpneg_operand (operands[2], SImode))
6184 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6185 operands[3], operands[0]));
6188 if (!thumb1_cmp_operand (operands[2], SImode))
6189 operands[2] = force_reg (SImode, operands[2]);
6192 (define_insn "*cbranchsi4_insn"
6193 [(set (pc) (if_then_else
6194 (match_operator 0 "arm_comparison_operator"
6195 [(match_operand:SI 1 "s_register_operand" "l,*h")
6196 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
6197 (label_ref (match_operand 3 "" ""))
6201 output_asm_insn (\"cmp\\t%1, %2\", operands);
6203 switch (get_attr_length (insn))
6205 case 4: return \"b%d0\\t%l3\";
6206 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6207 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6210 [(set (attr "far_jump")
6212 (eq_attr "length" "8")
6213 (const_string "yes")
6214 (const_string "no")))
6215 (set (attr "length")
6217 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6218 (le (minus (match_dup 3) (pc)) (const_int 256)))
6221 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6222 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6227 (define_insn "cbranchsi4_scratch"
6228 [(set (pc) (if_then_else
6229 (match_operator 4 "arm_comparison_operator"
6230 [(match_operand:SI 1 "s_register_operand" "l,0")
6231 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
6232 (label_ref (match_operand 3 "" ""))
6234 (clobber (match_scratch:SI 0 "=l,l"))]
6237 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
6239 switch (get_attr_length (insn))
6241 case 4: return \"b%d4\\t%l3\";
6242 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6243 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6246 [(set (attr "far_jump")
6248 (eq_attr "length" "8")
6249 (const_string "yes")
6250 (const_string "no")))
6251 (set (attr "length")
6253 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6254 (le (minus (match_dup 3) (pc)) (const_int 256)))
6257 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6258 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6262 (define_insn "*movsi_cbranchsi4"
6265 (match_operator 3 "arm_comparison_operator"
6266 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
6268 (label_ref (match_operand 2 "" ""))
6270 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
6274 if (which_alternative == 0)
6275 output_asm_insn (\"cmp\t%0, #0\", operands);
6276 else if (which_alternative == 1)
6277 output_asm_insn (\"sub\t%0, %1, #0\", operands);
6280 output_asm_insn (\"cmp\t%1, #0\", operands);
6281 if (which_alternative == 2)
6282 output_asm_insn (\"mov\t%0, %1\", operands);
6284 output_asm_insn (\"str\t%1, %0\", operands);
6286 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
6288 case 4: return \"b%d3\\t%l2\";
6289 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
6290 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
6293 [(set (attr "far_jump")
6295 (ior (and (gt (symbol_ref ("which_alternative"))
6297 (eq_attr "length" "8"))
6298 (eq_attr "length" "10"))
6299 (const_string "yes")
6300 (const_string "no")))
6301 (set (attr "length")
6303 (le (symbol_ref ("which_alternative"))
6306 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
6307 (le (minus (match_dup 2) (pc)) (const_int 256)))
6310 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
6311 (le (minus (match_dup 2) (pc)) (const_int 2048)))
6315 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
6316 (le (minus (match_dup 2) (pc)) (const_int 256)))
6319 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
6320 (le (minus (match_dup 2) (pc)) (const_int 2048)))
6325 (define_insn "*negated_cbranchsi4"
6328 (match_operator 0 "equality_operator"
6329 [(match_operand:SI 1 "s_register_operand" "l")
6330 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
6331 (label_ref (match_operand 3 "" ""))
6335 output_asm_insn (\"cmn\\t%1, %2\", operands);
6336 switch (get_attr_length (insn))
6338 case 4: return \"b%d0\\t%l3\";
6339 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6340 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6343 [(set (attr "far_jump")
6345 (eq_attr "length" "8")
6346 (const_string "yes")
6347 (const_string "no")))
6348 (set (attr "length")
6350 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6351 (le (minus (match_dup 3) (pc)) (const_int 256)))
6354 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6355 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6360 (define_insn "*tbit_cbranch"
6363 (match_operator 0 "equality_operator"
6364 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
6366 (match_operand:SI 2 "const_int_operand" "i"))
6368 (label_ref (match_operand 3 "" ""))
6370 (clobber (match_scratch:SI 4 "=l"))]
6375 op[0] = operands[4];
6376 op[1] = operands[1];
6377 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
6379 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
6380 switch (get_attr_length (insn))
6382 case 4: return \"b%d0\\t%l3\";
6383 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6384 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6387 [(set (attr "far_jump")
6389 (eq_attr "length" "8")
6390 (const_string "yes")
6391 (const_string "no")))
6392 (set (attr "length")
6394 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6395 (le (minus (match_dup 3) (pc)) (const_int 256)))
6398 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6399 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6404 (define_insn "*tlobits_cbranch"
6407 (match_operator 0 "equality_operator"
6408 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
6409 (match_operand:SI 2 "const_int_operand" "i")
6412 (label_ref (match_operand 3 "" ""))
6414 (clobber (match_scratch:SI 4 "=l"))]
6419 op[0] = operands[4];
6420 op[1] = operands[1];
6421 op[2] = GEN_INT (32 - INTVAL (operands[2]));
6423 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
6424 switch (get_attr_length (insn))
6426 case 4: return \"b%d0\\t%l3\";
6427 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6428 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6431 [(set (attr "far_jump")
6433 (eq_attr "length" "8")
6434 (const_string "yes")
6435 (const_string "no")))
6436 (set (attr "length")
6438 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6439 (le (minus (match_dup 3) (pc)) (const_int 256)))
6442 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6443 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6448 (define_insn "*tstsi3_cbranch"
6451 (match_operator 3 "equality_operator"
6452 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
6453 (match_operand:SI 1 "s_register_operand" "l"))
6455 (label_ref (match_operand 2 "" ""))
6460 output_asm_insn (\"tst\\t%0, %1\", operands);
6461 switch (get_attr_length (insn))
6463 case 4: return \"b%d3\\t%l2\";
6464 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
6465 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
6468 [(set (attr "far_jump")
6470 (eq_attr "length" "8")
6471 (const_string "yes")
6472 (const_string "no")))
6473 (set (attr "length")
6475 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
6476 (le (minus (match_dup 2) (pc)) (const_int 256)))
6479 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
6480 (le (minus (match_dup 2) (pc)) (const_int 2048)))
6485 (define_insn "*andsi3_cbranch"
6488 (match_operator 5 "equality_operator"
6489 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6490 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6492 (label_ref (match_operand 4 "" ""))
6494 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6495 (and:SI (match_dup 2) (match_dup 3)))
6496 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6500 if (which_alternative == 0)
6501 output_asm_insn (\"and\\t%0, %3\", operands);
6502 else if (which_alternative == 1)
6504 output_asm_insn (\"and\\t%1, %3\", operands);
6505 output_asm_insn (\"mov\\t%0, %1\", operands);
6509 output_asm_insn (\"and\\t%1, %3\", operands);
6510 output_asm_insn (\"str\\t%1, %0\", operands);
6513 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6515 case 4: return \"b%d5\\t%l4\";
6516 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6517 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6520 [(set (attr "far_jump")
6522 (ior (and (eq (symbol_ref ("which_alternative"))
6524 (eq_attr "length" "8"))
6525 (eq_attr "length" "10"))
6526 (const_string "yes")
6527 (const_string "no")))
6528 (set (attr "length")
6530 (eq (symbol_ref ("which_alternative"))
6533 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6534 (le (minus (match_dup 4) (pc)) (const_int 256)))
6537 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6538 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6542 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6543 (le (minus (match_dup 4) (pc)) (const_int 256)))
6546 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6547 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6552 (define_insn "*orrsi3_cbranch_scratch"
6555 (match_operator 4 "equality_operator"
6556 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
6557 (match_operand:SI 2 "s_register_operand" "l"))
6559 (label_ref (match_operand 3 "" ""))
6561 (clobber (match_scratch:SI 0 "=l"))]
6565 output_asm_insn (\"orr\\t%0, %2\", operands);
6566 switch (get_attr_length (insn))
6568 case 4: return \"b%d4\\t%l3\";
6569 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6570 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6573 [(set (attr "far_jump")
6575 (eq_attr "length" "8")
6576 (const_string "yes")
6577 (const_string "no")))
6578 (set (attr "length")
6580 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6581 (le (minus (match_dup 3) (pc)) (const_int 256)))
6584 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6585 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6590 (define_insn "*orrsi3_cbranch"
6593 (match_operator 5 "equality_operator"
6594 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6595 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6597 (label_ref (match_operand 4 "" ""))
6599 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6600 (ior:SI (match_dup 2) (match_dup 3)))
6601 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6605 if (which_alternative == 0)
6606 output_asm_insn (\"orr\\t%0, %3\", operands);
6607 else if (which_alternative == 1)
6609 output_asm_insn (\"orr\\t%1, %3\", operands);
6610 output_asm_insn (\"mov\\t%0, %1\", operands);
6614 output_asm_insn (\"orr\\t%1, %3\", operands);
6615 output_asm_insn (\"str\\t%1, %0\", operands);
6618 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6620 case 4: return \"b%d5\\t%l4\";
6621 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6622 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6625 [(set (attr "far_jump")
6627 (ior (and (eq (symbol_ref ("which_alternative"))
6629 (eq_attr "length" "8"))
6630 (eq_attr "length" "10"))
6631 (const_string "yes")
6632 (const_string "no")))
6633 (set (attr "length")
6635 (eq (symbol_ref ("which_alternative"))
6638 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6639 (le (minus (match_dup 4) (pc)) (const_int 256)))
6642 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6643 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6647 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6648 (le (minus (match_dup 4) (pc)) (const_int 256)))
6651 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6652 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6657 (define_insn "*xorsi3_cbranch_scratch"
6660 (match_operator 4 "equality_operator"
6661 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6662 (match_operand:SI 2 "s_register_operand" "l"))
6664 (label_ref (match_operand 3 "" ""))
6666 (clobber (match_scratch:SI 0 "=l"))]
6670 output_asm_insn (\"eor\\t%0, %2\", operands);
6671 switch (get_attr_length (insn))
6673 case 4: return \"b%d4\\t%l3\";
6674 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6675 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6678 [(set (attr "far_jump")
6680 (eq_attr "length" "8")
6681 (const_string "yes")
6682 (const_string "no")))
6683 (set (attr "length")
6685 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6686 (le (minus (match_dup 3) (pc)) (const_int 256)))
6689 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6690 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6695 (define_insn "*xorsi3_cbranch"
6698 (match_operator 5 "equality_operator"
6699 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6700 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6702 (label_ref (match_operand 4 "" ""))
6704 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6705 (xor:SI (match_dup 2) (match_dup 3)))
6706 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6710 if (which_alternative == 0)
6711 output_asm_insn (\"eor\\t%0, %3\", operands);
6712 else if (which_alternative == 1)
6714 output_asm_insn (\"eor\\t%1, %3\", operands);
6715 output_asm_insn (\"mov\\t%0, %1\", operands);
6719 output_asm_insn (\"eor\\t%1, %3\", operands);
6720 output_asm_insn (\"str\\t%1, %0\", operands);
6723 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6725 case 4: return \"b%d5\\t%l4\";
6726 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6727 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6730 [(set (attr "far_jump")
6732 (ior (and (eq (symbol_ref ("which_alternative"))
6734 (eq_attr "length" "8"))
6735 (eq_attr "length" "10"))
6736 (const_string "yes")
6737 (const_string "no")))
6738 (set (attr "length")
6740 (eq (symbol_ref ("which_alternative"))
6743 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6744 (le (minus (match_dup 4) (pc)) (const_int 256)))
6747 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6748 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6752 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6753 (le (minus (match_dup 4) (pc)) (const_int 256)))
6756 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6757 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6762 (define_insn "*bicsi3_cbranch_scratch"
6765 (match_operator 4 "equality_operator"
6766 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6767 (match_operand:SI 1 "s_register_operand" "0"))
6769 (label_ref (match_operand 3 "" ""))
6771 (clobber (match_scratch:SI 0 "=l"))]
6775 output_asm_insn (\"bic\\t%0, %2\", operands);
6776 switch (get_attr_length (insn))
6778 case 4: return \"b%d4\\t%l3\";
6779 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6780 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6783 [(set (attr "far_jump")
6785 (eq_attr "length" "8")
6786 (const_string "yes")
6787 (const_string "no")))
6788 (set (attr "length")
6790 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6791 (le (minus (match_dup 3) (pc)) (const_int 256)))
6794 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6795 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6800 (define_insn "*bicsi3_cbranch"
6803 (match_operator 5 "equality_operator"
6804 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
6805 (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
6807 (label_ref (match_operand 4 "" ""))
6809 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
6810 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6811 (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
6815 if (which_alternative == 0)
6816 output_asm_insn (\"bic\\t%0, %3\", operands);
6817 else if (which_alternative <= 2)
6819 output_asm_insn (\"bic\\t%1, %3\", operands);
6820 /* It's ok if OP0 is a lo-reg, even though the mov will set the
6821 conditions again, since we're only testing for equality. */
6822 output_asm_insn (\"mov\\t%0, %1\", operands);
6826 output_asm_insn (\"bic\\t%1, %3\", operands);
6827 output_asm_insn (\"str\\t%1, %0\", operands);
6830 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6832 case 4: return \"b%d5\\t%l4\";
6833 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6834 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6837 [(set (attr "far_jump")
6839 (ior (and (eq (symbol_ref ("which_alternative"))
6841 (eq_attr "length" "8"))
6842 (eq_attr "length" "10"))
6843 (const_string "yes")
6844 (const_string "no")))
6845 (set (attr "length")
6847 (eq (symbol_ref ("which_alternative"))
6850 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6851 (le (minus (match_dup 4) (pc)) (const_int 256)))
6854 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6855 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6859 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6860 (le (minus (match_dup 4) (pc)) (const_int 256)))
6863 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6864 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6869 (define_insn "*cbranchne_decr1"
6871 (if_then_else (match_operator 3 "equality_operator"
6872 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6874 (label_ref (match_operand 4 "" ""))
6876 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6877 (plus:SI (match_dup 2) (const_int -1)))
6878 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6883 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6885 VOIDmode, operands[2], const1_rtx);
6886 cond[1] = operands[4];
6888 if (which_alternative == 0)
6889 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6890 else if (which_alternative == 1)
6892 /* We must provide an alternative for a hi reg because reload
6893 cannot handle output reloads on a jump instruction, but we
6894 can't subtract into that. Fortunately a mov from lo to hi
6895 does not clobber the condition codes. */
6896 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6897 output_asm_insn (\"mov\\t%0, %1\", operands);
6901 /* Similarly, but the target is memory. */
6902 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6903 output_asm_insn (\"str\\t%1, %0\", operands);
6906 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6909 output_asm_insn (\"b%d0\\t%l1\", cond);
6912 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6913 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6915 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6916 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6920 [(set (attr "far_jump")
6922 (ior (and (eq (symbol_ref ("which_alternative"))
6924 (eq_attr "length" "8"))
6925 (eq_attr "length" "10"))
6926 (const_string "yes")
6927 (const_string "no")))
6928 (set_attr_alternative "length"
6932 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6933 (le (minus (match_dup 4) (pc)) (const_int 256)))
6936 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6937 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6942 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6943 (le (minus (match_dup 4) (pc)) (const_int 256)))
6946 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6947 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6952 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6953 (le (minus (match_dup 4) (pc)) (const_int 256)))
6956 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6957 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6962 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6963 (le (minus (match_dup 4) (pc)) (const_int 256)))
6966 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6967 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6972 (define_insn "*addsi3_cbranch"
6975 (match_operator 4 "comparison_operator"
6977 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6978 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6980 (label_ref (match_operand 5 "" ""))
6983 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6984 (plus:SI (match_dup 2) (match_dup 3)))
6985 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6987 && (GET_CODE (operands[4]) == EQ
6988 || GET_CODE (operands[4]) == NE
6989 || GET_CODE (operands[4]) == GE
6990 || GET_CODE (operands[4]) == LT)"
6996 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6997 cond[1] = operands[2];
6998 cond[2] = operands[3];
7000 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
7001 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
7003 output_asm_insn (\"add\\t%0, %1, %2\", cond);
7005 if (which_alternative >= 3
7006 && which_alternative < 4)
7007 output_asm_insn (\"mov\\t%0, %1\", operands);
7008 else if (which_alternative >= 4)
7009 output_asm_insn (\"str\\t%1, %0\", operands);
7011 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
7014 return \"b%d4\\t%l5\";
7016 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
7018 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
7022 [(set (attr "far_jump")
7024 (ior (and (lt (symbol_ref ("which_alternative"))
7026 (eq_attr "length" "8"))
7027 (eq_attr "length" "10"))
7028 (const_string "yes")
7029 (const_string "no")))
7030 (set (attr "length")
7032 (lt (symbol_ref ("which_alternative"))
7035 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
7036 (le (minus (match_dup 5) (pc)) (const_int 256)))
7039 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
7040 (le (minus (match_dup 5) (pc)) (const_int 2048)))
7044 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
7045 (le (minus (match_dup 5) (pc)) (const_int 256)))
7048 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
7049 (le (minus (match_dup 5) (pc)) (const_int 2048)))
7054 (define_insn "*addsi3_cbranch_scratch"
7057 (match_operator 3 "comparison_operator"
7059 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
7060 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
7062 (label_ref (match_operand 4 "" ""))
7064 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
7066 && (GET_CODE (operands[3]) == EQ
7067 || GET_CODE (operands[3]) == NE
7068 || GET_CODE (operands[3]) == GE
7069 || GET_CODE (operands[3]) == LT)"
7072 switch (which_alternative)
7075 output_asm_insn (\"cmp\t%1, #%n2\", operands);
7078 output_asm_insn (\"cmn\t%1, %2\", operands);
7081 if (INTVAL (operands[2]) < 0)
7082 output_asm_insn (\"sub\t%0, %1, %2\", operands);
7084 output_asm_insn (\"add\t%0, %1, %2\", operands);
7087 if (INTVAL (operands[2]) < 0)
7088 output_asm_insn (\"sub\t%0, %0, %2\", operands);
7090 output_asm_insn (\"add\t%0, %0, %2\", operands);
7094 switch (get_attr_length (insn))
7097 return \"b%d3\\t%l4\";
7099 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
7101 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
7105 [(set (attr "far_jump")
7107 (eq_attr "length" "8")
7108 (const_string "yes")
7109 (const_string "no")))
7110 (set (attr "length")
7112 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
7113 (le (minus (match_dup 4) (pc)) (const_int 256)))
7116 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
7117 (le (minus (match_dup 4) (pc)) (const_int 2048)))
7122 (define_insn "*subsi3_cbranch"
7125 (match_operator 4 "comparison_operator"
7127 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
7128 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
7130 (label_ref (match_operand 5 "" ""))
7132 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
7133 (minus:SI (match_dup 2) (match_dup 3)))
7134 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
7136 && (GET_CODE (operands[4]) == EQ
7137 || GET_CODE (operands[4]) == NE
7138 || GET_CODE (operands[4]) == GE
7139 || GET_CODE (operands[4]) == LT)"
7142 if (which_alternative == 0)
7143 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
7144 else if (which_alternative == 1)
7146 /* We must provide an alternative for a hi reg because reload
7147 cannot handle output reloads on a jump instruction, but we
7148 can't subtract into that. Fortunately a mov from lo to hi
7149 does not clobber the condition codes. */
7150 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
7151 output_asm_insn (\"mov\\t%0, %1\", operands);
7155 /* Similarly, but the target is memory. */
7156 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
7157 output_asm_insn (\"str\\t%1, %0\", operands);
7160 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
7163 return \"b%d4\\t%l5\";
7165 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
7167 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
7171 [(set (attr "far_jump")
7173 (ior (and (eq (symbol_ref ("which_alternative"))
7175 (eq_attr "length" "8"))
7176 (eq_attr "length" "10"))
7177 (const_string "yes")
7178 (const_string "no")))
7179 (set (attr "length")
7181 (eq (symbol_ref ("which_alternative"))
7184 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
7185 (le (minus (match_dup 5) (pc)) (const_int 256)))
7188 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
7189 (le (minus (match_dup 5) (pc)) (const_int 2048)))
7193 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
7194 (le (minus (match_dup 5) (pc)) (const_int 256)))
7197 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
7198 (le (minus (match_dup 5) (pc)) (const_int 2048)))
7203 (define_insn "*subsi3_cbranch_scratch"
7206 (match_operator 0 "arm_comparison_operator"
7207 [(minus:SI (match_operand:SI 1 "register_operand" "l")
7208 (match_operand:SI 2 "nonmemory_operand" "l"))
7210 (label_ref (match_operand 3 "" ""))
7213 && (GET_CODE (operands[0]) == EQ
7214 || GET_CODE (operands[0]) == NE
7215 || GET_CODE (operands[0]) == GE
7216 || GET_CODE (operands[0]) == LT)"
7218 output_asm_insn (\"cmp\\t%1, %2\", operands);
7219 switch (get_attr_length (insn))
7221 case 4: return \"b%d0\\t%l3\";
7222 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7223 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7226 [(set (attr "far_jump")
7228 (eq_attr "length" "8")
7229 (const_string "yes")
7230 (const_string "no")))
7231 (set (attr "length")
7233 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7234 (le (minus (match_dup 3) (pc)) (const_int 256)))
7237 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7238 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7243 ;; Comparison and test insns
7245 (define_expand "cmpsi"
7246 [(match_operand:SI 0 "s_register_operand" "")
7247 (match_operand:SI 1 "arm_add_operand" "")]
7250 arm_compare_op0 = operands[0];
7251 arm_compare_op1 = operands[1];
7256 (define_expand "cmpsf"
7257 [(match_operand:SF 0 "s_register_operand" "")
7258 (match_operand:SF 1 "arm_float_compare_operand" "")]
7259 "TARGET_32BIT && TARGET_HARD_FLOAT"
7261 arm_compare_op0 = operands[0];
7262 arm_compare_op1 = operands[1];
7267 (define_expand "cmpdf"
7268 [(match_operand:DF 0 "s_register_operand" "")
7269 (match_operand:DF 1 "arm_float_compare_operand" "")]
7270 "TARGET_32BIT && TARGET_HARD_FLOAT"
7272 arm_compare_op0 = operands[0];
7273 arm_compare_op1 = operands[1];
7278 (define_insn "*arm_cmpsi_insn"
7279 [(set (reg:CC CC_REGNUM)
7280 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
7281 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
7286 [(set_attr "conds" "set")]
7289 (define_insn "*arm_cmpsi_shiftsi"
7290 [(set (reg:CC CC_REGNUM)
7291 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
7292 (match_operator:SI 3 "shift_operator"
7293 [(match_operand:SI 1 "s_register_operand" "r")
7294 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
7297 [(set_attr "conds" "set")
7298 (set_attr "shift" "1")
7299 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
7300 (const_string "alu_shift")
7301 (const_string "alu_shift_reg")))]
7304 (define_insn "*arm_cmpsi_shiftsi_swp"
7305 [(set (reg:CC_SWP CC_REGNUM)
7306 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7307 [(match_operand:SI 1 "s_register_operand" "r")
7308 (match_operand:SI 2 "reg_or_int_operand" "rM")])
7309 (match_operand:SI 0 "s_register_operand" "r")))]
7312 [(set_attr "conds" "set")
7313 (set_attr "shift" "1")
7314 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
7315 (const_string "alu_shift")
7316 (const_string "alu_shift_reg")))]
7319 (define_insn "*arm_cmpsi_negshiftsi_si"
7320 [(set (reg:CC_Z CC_REGNUM)
7322 (neg:SI (match_operator:SI 1 "shift_operator"
7323 [(match_operand:SI 2 "s_register_operand" "r")
7324 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7325 (match_operand:SI 0 "s_register_operand" "r")))]
7328 [(set_attr "conds" "set")
7329 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7330 (const_string "alu_shift")
7331 (const_string "alu_shift_reg")))]
7334 ;; Cirrus SF compare instruction
7335 (define_insn "*cirrus_cmpsf"
7336 [(set (reg:CCFP CC_REGNUM)
7337 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
7338 (match_operand:SF 1 "cirrus_fp_register" "v")))]
7339 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7340 "cfcmps%?\\tr15, %V0, %V1"
7341 [(set_attr "type" "mav_farith")
7342 (set_attr "cirrus" "compare")]
7345 ;; Cirrus DF compare instruction
7346 (define_insn "*cirrus_cmpdf"
7347 [(set (reg:CCFP CC_REGNUM)
7348 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
7349 (match_operand:DF 1 "cirrus_fp_register" "v")))]
7350 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7351 "cfcmpd%?\\tr15, %V0, %V1"
7352 [(set_attr "type" "mav_farith")
7353 (set_attr "cirrus" "compare")]
7356 ;; Cirrus DI compare instruction
7357 (define_expand "cmpdi"
7358 [(match_operand:DI 0 "cirrus_fp_register" "")
7359 (match_operand:DI 1 "cirrus_fp_register" "")]
7360 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7362 arm_compare_op0 = operands[0];
7363 arm_compare_op1 = operands[1];
7367 (define_insn "*cirrus_cmpdi"
7368 [(set (reg:CC CC_REGNUM)
7369 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
7370 (match_operand:DI 1 "cirrus_fp_register" "v")))]
7371 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7372 "cfcmp64%?\\tr15, %V0, %V1"
7373 [(set_attr "type" "mav_farith")
7374 (set_attr "cirrus" "compare")]
7377 ; This insn allows redundant compares to be removed by cse, nothing should
7378 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7379 ; is deleted later on. The match_dup will match the mode here, so that
7380 ; mode changes of the condition codes aren't lost by this even though we don't
7381 ; specify what they are.
7383 (define_insn "*deleted_compare"
7384 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7386 "\\t%@ deleted compare"
7387 [(set_attr "conds" "set")
7388 (set_attr "length" "0")]
7392 ;; Conditional branch insns
7394 (define_expand "beq"
7396 (if_then_else (eq (match_dup 1) (const_int 0))
7397 (label_ref (match_operand 0 "" ""))
7400 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7403 (define_expand "bne"
7405 (if_then_else (ne (match_dup 1) (const_int 0))
7406 (label_ref (match_operand 0 "" ""))
7409 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7412 (define_expand "bgt"
7414 (if_then_else (gt (match_dup 1) (const_int 0))
7415 (label_ref (match_operand 0 "" ""))
7418 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7421 (define_expand "ble"
7423 (if_then_else (le (match_dup 1) (const_int 0))
7424 (label_ref (match_operand 0 "" ""))
7427 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7430 (define_expand "bge"
7432 (if_then_else (ge (match_dup 1) (const_int 0))
7433 (label_ref (match_operand 0 "" ""))
7436 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7439 (define_expand "blt"
7441 (if_then_else (lt (match_dup 1) (const_int 0))
7442 (label_ref (match_operand 0 "" ""))
7445 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7448 (define_expand "bgtu"
7450 (if_then_else (gtu (match_dup 1) (const_int 0))
7451 (label_ref (match_operand 0 "" ""))
7454 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7457 (define_expand "bleu"
7459 (if_then_else (leu (match_dup 1) (const_int 0))
7460 (label_ref (match_operand 0 "" ""))
7463 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7466 (define_expand "bgeu"
7468 (if_then_else (geu (match_dup 1) (const_int 0))
7469 (label_ref (match_operand 0 "" ""))
7472 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7475 (define_expand "bltu"
7477 (if_then_else (ltu (match_dup 1) (const_int 0))
7478 (label_ref (match_operand 0 "" ""))
7481 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7484 (define_expand "bunordered"
7486 (if_then_else (unordered (match_dup 1) (const_int 0))
7487 (label_ref (match_operand 0 "" ""))
7489 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7490 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7494 (define_expand "bordered"
7496 (if_then_else (ordered (match_dup 1) (const_int 0))
7497 (label_ref (match_operand 0 "" ""))
7499 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7500 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7504 (define_expand "bungt"
7506 (if_then_else (ungt (match_dup 1) (const_int 0))
7507 (label_ref (match_operand 0 "" ""))
7509 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7510 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
7513 (define_expand "bunlt"
7515 (if_then_else (unlt (match_dup 1) (const_int 0))
7516 (label_ref (match_operand 0 "" ""))
7518 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7519 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
7522 (define_expand "bunge"
7524 (if_then_else (unge (match_dup 1) (const_int 0))
7525 (label_ref (match_operand 0 "" ""))
7527 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7528 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
7531 (define_expand "bunle"
7533 (if_then_else (unle (match_dup 1) (const_int 0))
7534 (label_ref (match_operand 0 "" ""))
7536 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7537 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
7540 ;; The following two patterns need two branch instructions, since there is
7541 ;; no single instruction that will handle all cases.
7542 (define_expand "buneq"
7544 (if_then_else (uneq (match_dup 1) (const_int 0))
7545 (label_ref (match_operand 0 "" ""))
7547 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7548 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
7551 (define_expand "bltgt"
7553 (if_then_else (ltgt (match_dup 1) (const_int 0))
7554 (label_ref (match_operand 0 "" ""))
7556 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7557 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
7561 ;; Patterns to match conditional branch insns.
7564 ; Special pattern to match UNEQ.
7565 (define_insn "*arm_buneq"
7567 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7568 (label_ref (match_operand 0 "" ""))
7570 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7572 gcc_assert (!arm_ccfsm_state);
7574 return \"bvs\\t%l0\;beq\\t%l0\";
7576 [(set_attr "conds" "jump_clob")
7577 (set_attr "length" "8")]
7580 ; Special pattern to match LTGT.
7581 (define_insn "*arm_bltgt"
7583 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7584 (label_ref (match_operand 0 "" ""))
7586 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7588 gcc_assert (!arm_ccfsm_state);
7590 return \"bmi\\t%l0\;bgt\\t%l0\";
7592 [(set_attr "conds" "jump_clob")
7593 (set_attr "length" "8")]
7596 (define_insn "*arm_cond_branch"
7598 (if_then_else (match_operator 1 "arm_comparison_operator"
7599 [(match_operand 2 "cc_register" "") (const_int 0)])
7600 (label_ref (match_operand 0 "" ""))
7604 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7606 arm_ccfsm_state += 2;
7609 return \"b%d1\\t%l0\";
7611 [(set_attr "conds" "use")
7612 (set_attr "type" "branch")]
7615 ; Special pattern to match reversed UNEQ.
7616 (define_insn "*arm_buneq_reversed"
7618 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7620 (label_ref (match_operand 0 "" ""))))]
7621 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7623 gcc_assert (!arm_ccfsm_state);
7625 return \"bmi\\t%l0\;bgt\\t%l0\";
7627 [(set_attr "conds" "jump_clob")
7628 (set_attr "length" "8")]
7631 ; Special pattern to match reversed LTGT.
7632 (define_insn "*arm_bltgt_reversed"
7634 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7636 (label_ref (match_operand 0 "" ""))))]
7637 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7639 gcc_assert (!arm_ccfsm_state);
7641 return \"bvs\\t%l0\;beq\\t%l0\";
7643 [(set_attr "conds" "jump_clob")
7644 (set_attr "length" "8")]
7647 (define_insn "*arm_cond_branch_reversed"
7649 (if_then_else (match_operator 1 "arm_comparison_operator"
7650 [(match_operand 2 "cc_register" "") (const_int 0)])
7652 (label_ref (match_operand 0 "" ""))))]
7655 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7657 arm_ccfsm_state += 2;
7660 return \"b%D1\\t%l0\";
7662 [(set_attr "conds" "use")
7663 (set_attr "type" "branch")]
7670 (define_expand "seq"
7671 [(set (match_operand:SI 0 "s_register_operand" "")
7672 (eq:SI (match_dup 1) (const_int 0)))]
7674 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7677 (define_expand "sne"
7678 [(set (match_operand:SI 0 "s_register_operand" "")
7679 (ne:SI (match_dup 1) (const_int 0)))]
7681 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7684 (define_expand "sgt"
7685 [(set (match_operand:SI 0 "s_register_operand" "")
7686 (gt:SI (match_dup 1) (const_int 0)))]
7688 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7691 (define_expand "sle"
7692 [(set (match_operand:SI 0 "s_register_operand" "")
7693 (le:SI (match_dup 1) (const_int 0)))]
7695 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7698 (define_expand "sge"
7699 [(set (match_operand:SI 0 "s_register_operand" "")
7700 (ge:SI (match_dup 1) (const_int 0)))]
7702 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7705 (define_expand "slt"
7706 [(set (match_operand:SI 0 "s_register_operand" "")
7707 (lt:SI (match_dup 1) (const_int 0)))]
7709 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7712 (define_expand "sgtu"
7713 [(set (match_operand:SI 0 "s_register_operand" "")
7714 (gtu:SI (match_dup 1) (const_int 0)))]
7716 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7719 (define_expand "sleu"
7720 [(set (match_operand:SI 0 "s_register_operand" "")
7721 (leu:SI (match_dup 1) (const_int 0)))]
7723 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7726 (define_expand "sgeu"
7727 [(set (match_operand:SI 0 "s_register_operand" "")
7728 (geu:SI (match_dup 1) (const_int 0)))]
7730 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7733 (define_expand "sltu"
7734 [(set (match_operand:SI 0 "s_register_operand" "")
7735 (ltu:SI (match_dup 1) (const_int 0)))]
7737 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7740 (define_expand "sunordered"
7741 [(set (match_operand:SI 0 "s_register_operand" "")
7742 (unordered:SI (match_dup 1) (const_int 0)))]
7743 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7744 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7748 (define_expand "sordered"
7749 [(set (match_operand:SI 0 "s_register_operand" "")
7750 (ordered:SI (match_dup 1) (const_int 0)))]
7751 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7752 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7756 (define_expand "sungt"
7757 [(set (match_operand:SI 0 "s_register_operand" "")
7758 (ungt:SI (match_dup 1) (const_int 0)))]
7759 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7760 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7764 (define_expand "sunge"
7765 [(set (match_operand:SI 0 "s_register_operand" "")
7766 (unge:SI (match_dup 1) (const_int 0)))]
7767 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7768 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7772 (define_expand "sunlt"
7773 [(set (match_operand:SI 0 "s_register_operand" "")
7774 (unlt:SI (match_dup 1) (const_int 0)))]
7775 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7776 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7780 (define_expand "sunle"
7781 [(set (match_operand:SI 0 "s_register_operand" "")
7782 (unle:SI (match_dup 1) (const_int 0)))]
7783 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7784 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7788 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7789 ;;; simple ARM instructions.
7791 ; (define_expand "suneq"
7792 ; [(set (match_operand:SI 0 "s_register_operand" "")
7793 ; (uneq:SI (match_dup 1) (const_int 0)))]
7794 ; "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7795 ; "gcc_unreachable ();"
7798 ; (define_expand "sltgt"
7799 ; [(set (match_operand:SI 0 "s_register_operand" "")
7800 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7801 ; "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7802 ; "gcc_unreachable ();"
7805 (define_insn "*mov_scc"
7806 [(set (match_operand:SI 0 "s_register_operand" "=r")
7807 (match_operator:SI 1 "arm_comparison_operator"
7808 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7810 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7811 [(set_attr "conds" "use")
7812 (set_attr "length" "8")]
7815 (define_insn "*mov_negscc"
7816 [(set (match_operand:SI 0 "s_register_operand" "=r")
7817 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7818 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7820 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7821 [(set_attr "conds" "use")
7822 (set_attr "length" "8")]
7825 (define_insn "*mov_notscc"
7826 [(set (match_operand:SI 0 "s_register_operand" "=r")
7827 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7828 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7830 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7831 [(set_attr "conds" "use")
7832 (set_attr "length" "8")]
7835 (define_expand "cstoresi4"
7836 [(set (match_operand:SI 0 "s_register_operand" "")
7837 (match_operator:SI 1 "arm_comparison_operator"
7838 [(match_operand:SI 2 "s_register_operand" "")
7839 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7842 rtx op3, scratch, scratch2;
7844 if (operands[3] == const0_rtx)
7846 switch (GET_CODE (operands[1]))
7849 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7853 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7857 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7858 NULL_RTX, 0, OPTAB_WIDEN);
7859 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7860 NULL_RTX, 0, OPTAB_WIDEN);
7861 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7862 operands[0], 1, OPTAB_WIDEN);
7866 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7868 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7869 NULL_RTX, 1, OPTAB_WIDEN);
7873 scratch = expand_binop (SImode, ashr_optab, operands[2],
7874 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7875 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7876 NULL_RTX, 0, OPTAB_WIDEN);
7877 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7881 /* LT is handled by generic code. No need for unsigned with 0. */
7888 switch (GET_CODE (operands[1]))
7891 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7892 NULL_RTX, 0, OPTAB_WIDEN);
7893 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7897 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7898 NULL_RTX, 0, OPTAB_WIDEN);
7899 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7903 op3 = force_reg (SImode, operands[3]);
7905 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7906 NULL_RTX, 1, OPTAB_WIDEN);
7907 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7908 NULL_RTX, 0, OPTAB_WIDEN);
7909 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7915 if (!thumb1_cmp_operand (op3, SImode))
7916 op3 = force_reg (SImode, op3);
7917 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7918 NULL_RTX, 0, OPTAB_WIDEN);
7919 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7920 NULL_RTX, 1, OPTAB_WIDEN);
7921 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7926 op3 = force_reg (SImode, operands[3]);
7927 scratch = force_reg (SImode, const0_rtx);
7928 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7934 if (!thumb1_cmp_operand (op3, SImode))
7935 op3 = force_reg (SImode, op3);
7936 scratch = force_reg (SImode, const0_rtx);
7937 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7943 if (!thumb1_cmp_operand (op3, SImode))
7944 op3 = force_reg (SImode, op3);
7945 scratch = gen_reg_rtx (SImode);
7946 emit_insn (gen_cstoresi_nltu_thumb1 (scratch, operands[2], op3));
7947 emit_insn (gen_negsi2 (operands[0], scratch));
7951 op3 = force_reg (SImode, operands[3]);
7952 scratch = gen_reg_rtx (SImode);
7953 emit_insn (gen_cstoresi_nltu_thumb1 (scratch, op3, operands[2]));
7954 emit_insn (gen_negsi2 (operands[0], scratch));
7957 /* No good sequences for GT, LT. */
7964 (define_expand "cstoresi_eq0_thumb1"
7966 [(set (match_operand:SI 0 "s_register_operand" "")
7967 (eq:SI (match_operand:SI 1 "s_register_operand" "")
7969 (clobber (match_dup:SI 2))])]
7971 "operands[2] = gen_reg_rtx (SImode);"
7974 (define_expand "cstoresi_ne0_thumb1"
7976 [(set (match_operand:SI 0 "s_register_operand" "")
7977 (ne:SI (match_operand:SI 1 "s_register_operand" "")
7979 (clobber (match_dup:SI 2))])]
7981 "operands[2] = gen_reg_rtx (SImode);"
7984 (define_insn "*cstoresi_eq0_thumb1_insn"
7985 [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
7986 (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
7988 (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
7991 neg\\t%0, %1\;adc\\t%0, %0, %1
7992 neg\\t%2, %1\;adc\\t%0, %1, %2"
7993 [(set_attr "length" "4")]
7996 (define_insn "*cstoresi_ne0_thumb1_insn"
7997 [(set (match_operand:SI 0 "s_register_operand" "=l")
7998 (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8000 (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8002 "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8003 [(set_attr "length" "4")]
8006 (define_insn "cstoresi_nltu_thumb1"
8007 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8008 (neg:SI (gtu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8009 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8011 "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8012 [(set_attr "length" "4")]
8015 ;; Used as part of the expansion of thumb les sequence.
8016 (define_insn "thumb1_addsi3_addgeu"
8017 [(set (match_operand:SI 0 "s_register_operand" "=l")
8018 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8019 (match_operand:SI 2 "s_register_operand" "l"))
8020 (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8021 (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8023 "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8024 [(set_attr "length" "4")]
8028 ;; Conditional move insns
8030 (define_expand "movsicc"
8031 [(set (match_operand:SI 0 "s_register_operand" "")
8032 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
8033 (match_operand:SI 2 "arm_not_operand" "")
8034 (match_operand:SI 3 "arm_not_operand" "")))]
8038 enum rtx_code code = GET_CODE (operands[1]);
8041 if (code == UNEQ || code == LTGT)
8044 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
8045 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8049 (define_expand "movsfcc"
8050 [(set (match_operand:SF 0 "s_register_operand" "")
8051 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
8052 (match_operand:SF 2 "s_register_operand" "")
8053 (match_operand:SF 3 "nonmemory_operand" "")))]
8057 enum rtx_code code = GET_CODE (operands[1]);
8060 if (code == UNEQ || code == LTGT)
8063 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
8064 Otherwise, ensure it is a valid FP add operand */
8065 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
8066 || (!arm_float_add_operand (operands[3], SFmode)))
8067 operands[3] = force_reg (SFmode, operands[3]);
8069 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
8070 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8074 (define_expand "movdfcc"
8075 [(set (match_operand:DF 0 "s_register_operand" "")
8076 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
8077 (match_operand:DF 2 "s_register_operand" "")
8078 (match_operand:DF 3 "arm_float_add_operand" "")))]
8079 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
8082 enum rtx_code code = GET_CODE (operands[1]);
8085 if (code == UNEQ || code == LTGT)
8088 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
8089 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8093 (define_insn "*movsicc_insn"
8094 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8096 (match_operator 3 "arm_comparison_operator"
8097 [(match_operand 4 "cc_register" "") (const_int 0)])
8098 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8099 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8106 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8107 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8108 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8109 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8110 [(set_attr "length" "4,4,4,4,8,8,8,8")
8111 (set_attr "conds" "use")]
8114 (define_insn "*movsfcc_soft_insn"
8115 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8116 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8117 [(match_operand 4 "cc_register" "") (const_int 0)])
8118 (match_operand:SF 1 "s_register_operand" "0,r")
8119 (match_operand:SF 2 "s_register_operand" "r,0")))]
8120 "TARGET_ARM && TARGET_SOFT_FLOAT"
8124 [(set_attr "conds" "use")]
8128 ;; Jump and linkage insns
8130 (define_expand "jump"
8132 (label_ref (match_operand 0 "" "")))]
8137 (define_insn "*arm_jump"
8139 (label_ref (match_operand 0 "" "")))]
8143 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8145 arm_ccfsm_state += 2;
8148 return \"b%?\\t%l0\";
8151 [(set_attr "predicable" "yes")]
8154 (define_insn "*thumb_jump"
8156 (label_ref (match_operand 0 "" "")))]
8159 if (get_attr_length (insn) == 2)
8161 return \"bl\\t%l0\\t%@ far jump\";
8163 [(set (attr "far_jump")
8165 (eq_attr "length" "4")
8166 (const_string "yes")
8167 (const_string "no")))
8168 (set (attr "length")
8170 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8171 (le (minus (match_dup 0) (pc)) (const_int 2048)))
8176 (define_expand "call"
8177 [(parallel [(call (match_operand 0 "memory_operand" "")
8178 (match_operand 1 "general_operand" ""))
8179 (use (match_operand 2 "" ""))
8180 (clobber (reg:SI LR_REGNUM))])]
8186 /* In an untyped call, we can get NULL for operand 2. */
8187 if (operands[2] == NULL_RTX)
8188 operands[2] = const0_rtx;
8190 /* Decide if we should generate indirect calls by loading the
8191 32-bit address of the callee into a register before performing the
8193 callee = XEXP (operands[0], 0);
8194 if (GET_CODE (callee) == SYMBOL_REF
8195 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8197 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8199 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8200 arm_emit_call_insn (pat, XEXP (operands[0], 0));
8205 (define_expand "call_internal"
8206 [(parallel [(call (match_operand 0 "memory_operand" "")
8207 (match_operand 1 "general_operand" ""))
8208 (use (match_operand 2 "" ""))
8209 (clobber (reg:SI LR_REGNUM))])])
8211 (define_insn "*call_reg_armv5"
8212 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8213 (match_operand 1 "" ""))
8214 (use (match_operand 2 "" ""))
8215 (clobber (reg:SI LR_REGNUM))]
8216 "TARGET_ARM && arm_arch5"
8218 [(set_attr "type" "call")]
8221 (define_insn "*call_reg_arm"
8222 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8223 (match_operand 1 "" ""))
8224 (use (match_operand 2 "" ""))
8225 (clobber (reg:SI LR_REGNUM))]
8226 "TARGET_ARM && !arm_arch5"
8228 return output_call (operands);
8230 ;; length is worst case, normally it is only two
8231 [(set_attr "length" "12")
8232 (set_attr "type" "call")]
8235 (define_insn "*call_mem"
8236 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
8237 (match_operand 1 "" ""))
8238 (use (match_operand 2 "" ""))
8239 (clobber (reg:SI LR_REGNUM))]
8242 return output_call_mem (operands);
8244 [(set_attr "length" "12")
8245 (set_attr "type" "call")]
8248 (define_insn "*call_reg_thumb1_v5"
8249 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
8250 (match_operand 1 "" ""))
8251 (use (match_operand 2 "" ""))
8252 (clobber (reg:SI LR_REGNUM))]
8253 "TARGET_THUMB1 && arm_arch5"
8255 [(set_attr "length" "2")
8256 (set_attr "type" "call")]
8259 (define_insn "*call_reg_thumb1"
8260 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
8261 (match_operand 1 "" ""))
8262 (use (match_operand 2 "" ""))
8263 (clobber (reg:SI LR_REGNUM))]
8264 "TARGET_THUMB1 && !arm_arch5"
8267 if (!TARGET_CALLER_INTERWORKING)
8268 return thumb_call_via_reg (operands[0]);
8269 else if (operands[1] == const0_rtx)
8270 return \"bl\\t%__interwork_call_via_%0\";
8271 else if (frame_pointer_needed)
8272 return \"bl\\t%__interwork_r7_call_via_%0\";
8274 return \"bl\\t%__interwork_r11_call_via_%0\";
8276 [(set_attr "type" "call")]
8279 (define_expand "call_value"
8280 [(parallel [(set (match_operand 0 "" "")
8281 (call (match_operand 1 "memory_operand" "")
8282 (match_operand 2 "general_operand" "")))
8283 (use (match_operand 3 "" ""))
8284 (clobber (reg:SI LR_REGNUM))])]
8290 /* In an untyped call, we can get NULL for operand 2. */
8291 if (operands[3] == 0)
8292 operands[3] = const0_rtx;
8294 /* Decide if we should generate indirect calls by loading the
8295 32-bit address of the callee into a register before performing the
8297 callee = XEXP (operands[1], 0);
8298 if (GET_CODE (callee) == SYMBOL_REF
8299 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8301 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8303 pat = gen_call_value_internal (operands[0], operands[1],
8304 operands[2], operands[3]);
8305 arm_emit_call_insn (pat, XEXP (operands[1], 0));
8310 (define_expand "call_value_internal"
8311 [(parallel [(set (match_operand 0 "" "")
8312 (call (match_operand 1 "memory_operand" "")
8313 (match_operand 2 "general_operand" "")))
8314 (use (match_operand 3 "" ""))
8315 (clobber (reg:SI LR_REGNUM))])])
8317 (define_insn "*call_value_reg_armv5"
8318 [(set (match_operand 0 "" "")
8319 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8320 (match_operand 2 "" "")))
8321 (use (match_operand 3 "" ""))
8322 (clobber (reg:SI LR_REGNUM))]
8323 "TARGET_ARM && arm_arch5"
8325 [(set_attr "type" "call")]
8328 (define_insn "*call_value_reg_arm"
8329 [(set (match_operand 0 "" "")
8330 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8331 (match_operand 2 "" "")))
8332 (use (match_operand 3 "" ""))
8333 (clobber (reg:SI LR_REGNUM))]
8334 "TARGET_ARM && !arm_arch5"
8336 return output_call (&operands[1]);
8338 [(set_attr "length" "12")
8339 (set_attr "type" "call")]
8342 (define_insn "*call_value_mem"
8343 [(set (match_operand 0 "" "")
8344 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
8345 (match_operand 2 "" "")))
8346 (use (match_operand 3 "" ""))
8347 (clobber (reg:SI LR_REGNUM))]
8348 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
8350 return output_call_mem (&operands[1]);
8352 [(set_attr "length" "12")
8353 (set_attr "type" "call")]
8356 (define_insn "*call_value_reg_thumb1_v5"
8357 [(set (match_operand 0 "" "")
8358 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
8359 (match_operand 2 "" "")))
8360 (use (match_operand 3 "" ""))
8361 (clobber (reg:SI LR_REGNUM))]
8362 "TARGET_THUMB1 && arm_arch5"
8364 [(set_attr "length" "2")
8365 (set_attr "type" "call")]
8368 (define_insn "*call_value_reg_thumb1"
8369 [(set (match_operand 0 "" "")
8370 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
8371 (match_operand 2 "" "")))
8372 (use (match_operand 3 "" ""))
8373 (clobber (reg:SI LR_REGNUM))]
8374 "TARGET_THUMB1 && !arm_arch5"
8377 if (!TARGET_CALLER_INTERWORKING)
8378 return thumb_call_via_reg (operands[1]);
8379 else if (operands[2] == const0_rtx)
8380 return \"bl\\t%__interwork_call_via_%1\";
8381 else if (frame_pointer_needed)
8382 return \"bl\\t%__interwork_r7_call_via_%1\";
8384 return \"bl\\t%__interwork_r11_call_via_%1\";
8386 [(set_attr "type" "call")]
8389 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8390 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8392 (define_insn "*call_symbol"
8393 [(call (mem:SI (match_operand:SI 0 "" ""))
8394 (match_operand 1 "" ""))
8395 (use (match_operand 2 "" ""))
8396 (clobber (reg:SI LR_REGNUM))]
8398 && (GET_CODE (operands[0]) == SYMBOL_REF)
8399 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8402 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8404 [(set_attr "type" "call")]
8407 (define_insn "*call_value_symbol"
8408 [(set (match_operand 0 "" "")
8409 (call (mem:SI (match_operand:SI 1 "" ""))
8410 (match_operand:SI 2 "" "")))
8411 (use (match_operand 3 "" ""))
8412 (clobber (reg:SI LR_REGNUM))]
8414 && (GET_CODE (operands[1]) == SYMBOL_REF)
8415 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8418 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8420 [(set_attr "type" "call")]
8423 (define_insn "*call_insn"
8424 [(call (mem:SI (match_operand:SI 0 "" ""))
8425 (match_operand:SI 1 "" ""))
8426 (use (match_operand 2 "" ""))
8427 (clobber (reg:SI LR_REGNUM))]
8429 && GET_CODE (operands[0]) == SYMBOL_REF
8430 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8432 [(set_attr "length" "4")
8433 (set_attr "type" "call")]
8436 (define_insn "*call_value_insn"
8437 [(set (match_operand 0 "" "")
8438 (call (mem:SI (match_operand 1 "" ""))
8439 (match_operand 2 "" "")))
8440 (use (match_operand 3 "" ""))
8441 (clobber (reg:SI LR_REGNUM))]
8443 && GET_CODE (operands[1]) == SYMBOL_REF
8444 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8446 [(set_attr "length" "4")
8447 (set_attr "type" "call")]
8450 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8451 (define_expand "sibcall"
8452 [(parallel [(call (match_operand 0 "memory_operand" "")
8453 (match_operand 1 "general_operand" ""))
8455 (use (match_operand 2 "" ""))])]
8459 if (operands[2] == NULL_RTX)
8460 operands[2] = const0_rtx;
8464 (define_expand "sibcall_value"
8465 [(parallel [(set (match_operand 0 "" "")
8466 (call (match_operand 1 "memory_operand" "")
8467 (match_operand 2 "general_operand" "")))
8469 (use (match_operand 3 "" ""))])]
8473 if (operands[3] == NULL_RTX)
8474 operands[3] = const0_rtx;
8478 (define_insn "*sibcall_insn"
8479 [(call (mem:SI (match_operand:SI 0 "" "X"))
8480 (match_operand 1 "" ""))
8482 (use (match_operand 2 "" ""))]
8483 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
8485 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8487 [(set_attr "type" "call")]
8490 (define_insn "*sibcall_value_insn"
8491 [(set (match_operand 0 "" "")
8492 (call (mem:SI (match_operand:SI 1 "" "X"))
8493 (match_operand 2 "" "")))
8495 (use (match_operand 3 "" ""))]
8496 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
8498 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8500 [(set_attr "type" "call")]
8503 ;; Often the return insn will be the same as loading from memory, so set attr
8504 (define_insn "return"
8506 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8509 if (arm_ccfsm_state == 2)
8511 arm_ccfsm_state += 2;
8514 return output_return_instruction (const_true_rtx, TRUE, FALSE);
8516 [(set_attr "type" "load1")
8517 (set_attr "length" "12")
8518 (set_attr "predicable" "yes")]
8521 (define_insn "*cond_return"
8523 (if_then_else (match_operator 0 "arm_comparison_operator"
8524 [(match_operand 1 "cc_register" "") (const_int 0)])
8527 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
8530 if (arm_ccfsm_state == 2)
8532 arm_ccfsm_state += 2;
8535 return output_return_instruction (operands[0], TRUE, FALSE);
8537 [(set_attr "conds" "use")
8538 (set_attr "length" "12")
8539 (set_attr "type" "load1")]
8542 (define_insn "*cond_return_inverted"
8544 (if_then_else (match_operator 0 "arm_comparison_operator"
8545 [(match_operand 1 "cc_register" "") (const_int 0)])
8548 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
8551 if (arm_ccfsm_state == 2)
8553 arm_ccfsm_state += 2;
8556 return output_return_instruction (operands[0], TRUE, TRUE);
8558 [(set_attr "conds" "use")
8559 (set_attr "length" "12")
8560 (set_attr "type" "load1")]
8563 ;; Generate a sequence of instructions to determine if the processor is
8564 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8567 (define_expand "return_addr_mask"
8569 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8571 (set (match_operand:SI 0 "s_register_operand" "")
8572 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8574 (const_int 67108860)))] ; 0x03fffffc
8577 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8580 (define_insn "*check_arch2"
8581 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8582 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8585 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8586 [(set_attr "length" "8")
8587 (set_attr "conds" "set")]
8590 ;; Call subroutine returning any type.
8592 (define_expand "untyped_call"
8593 [(parallel [(call (match_operand 0 "" "")
8595 (match_operand 1 "" "")
8596 (match_operand 2 "" "")])]
8601 rtx par = gen_rtx_PARALLEL (VOIDmode,
8602 rtvec_alloc (XVECLEN (operands[2], 0)));
8603 rtx addr = gen_reg_rtx (Pmode);
8607 emit_move_insn (addr, XEXP (operands[1], 0));
8608 mem = change_address (operands[1], BLKmode, addr);
8610 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8612 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8614 /* Default code only uses r0 as a return value, but we could
8615 be using anything up to 4 registers. */
8616 if (REGNO (src) == R0_REGNUM)
8617 src = gen_rtx_REG (TImode, R0_REGNUM);
8619 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8621 size += GET_MODE_SIZE (GET_MODE (src));
8624 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8629 for (i = 0; i < XVECLEN (par, 0); i++)
8631 HOST_WIDE_INT offset = 0;
8632 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8635 emit_move_insn (addr, plus_constant (addr, size));
8637 mem = change_address (mem, GET_MODE (reg), NULL);
8638 if (REGNO (reg) == R0_REGNUM)
8640 /* On thumb we have to use a write-back instruction. */
8641 emit_insn (arm_gen_store_multiple (R0_REGNUM, 4, addr, TRUE,
8642 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8643 size = TARGET_ARM ? 16 : 0;
8647 emit_move_insn (mem, reg);
8648 size = GET_MODE_SIZE (GET_MODE (reg));
8652 /* The optimizer does not know that the call sets the function value
8653 registers we stored in the result block. We avoid problems by
8654 claiming that all hard registers are used and clobbered at this
8656 emit_insn (gen_blockage ());
8662 (define_expand "untyped_return"
8663 [(match_operand:BLK 0 "memory_operand" "")
8664 (match_operand 1 "" "")]
8669 rtx addr = gen_reg_rtx (Pmode);
8673 emit_move_insn (addr, XEXP (operands[0], 0));
8674 mem = change_address (operands[0], BLKmode, addr);
8676 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8678 HOST_WIDE_INT offset = 0;
8679 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8682 emit_move_insn (addr, plus_constant (addr, size));
8684 mem = change_address (mem, GET_MODE (reg), NULL);
8685 if (REGNO (reg) == R0_REGNUM)
8687 /* On thumb we have to use a write-back instruction. */
8688 emit_insn (arm_gen_load_multiple (R0_REGNUM, 4, addr, TRUE,
8689 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8690 size = TARGET_ARM ? 16 : 0;
8694 emit_move_insn (reg, mem);
8695 size = GET_MODE_SIZE (GET_MODE (reg));
8699 /* Emit USE insns before the return. */
8700 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8701 emit_insn (gen_rtx_USE (VOIDmode,
8702 SET_DEST (XVECEXP (operands[1], 0, i))));
8704 /* Construct the return. */
8705 expand_naked_return ();
8711 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8712 ;; all of memory. This blocks insns from being moved across this point.
8714 (define_insn "blockage"
8715 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8718 [(set_attr "length" "0")
8719 (set_attr "type" "block")]
8722 (define_expand "casesi"
8723 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8724 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8725 (match_operand:SI 2 "const_int_operand" "") ; total range
8726 (match_operand:SI 3 "" "") ; table label
8727 (match_operand:SI 4 "" "")] ; Out of range label
8732 if (operands[1] != const0_rtx)
8734 reg = gen_reg_rtx (SImode);
8736 emit_insn (gen_addsi3 (reg, operands[0],
8737 GEN_INT (-INTVAL (operands[1]))));
8741 if (!const_ok_for_arm (INTVAL (operands[2])))
8742 operands[2] = force_reg (SImode, operands[2]);
8746 emit_jump_insn (gen_arm_casesi_internal (operands[0], operands[2],
8747 operands[3], operands[4]));
8751 emit_jump_insn (gen_thumb2_casesi_internal_pic (operands[0],
8752 operands[2], operands[3], operands[4]));
8756 emit_jump_insn (gen_thumb2_casesi_internal (operands[0], operands[2],
8757 operands[3], operands[4]));
8763 ;; The USE in this pattern is needed to tell flow analysis that this is
8764 ;; a CASESI insn. It has no other purpose.
8765 (define_insn "arm_casesi_internal"
8766 [(parallel [(set (pc)
8768 (leu (match_operand:SI 0 "s_register_operand" "r")
8769 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8770 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8771 (label_ref (match_operand 2 "" ""))))
8772 (label_ref (match_operand 3 "" ""))))
8773 (clobber (reg:CC CC_REGNUM))
8774 (use (label_ref (match_dup 2)))])]
8778 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8779 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8781 [(set_attr "conds" "clob")
8782 (set_attr "length" "12")]
8785 (define_expand "indirect_jump"
8787 (match_operand:SI 0 "s_register_operand" ""))]
8790 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8791 address and use bx. */
8795 tmp = gen_reg_rtx (SImode);
8796 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8802 ;; NB Never uses BX.
8803 (define_insn "*arm_indirect_jump"
8805 (match_operand:SI 0 "s_register_operand" "r"))]
8807 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8808 [(set_attr "predicable" "yes")]
8811 (define_insn "*load_indirect_jump"
8813 (match_operand:SI 0 "memory_operand" "m"))]
8815 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8816 [(set_attr "type" "load1")
8817 (set_attr "pool_range" "4096")
8818 (set_attr "neg_pool_range" "4084")
8819 (set_attr "predicable" "yes")]
8822 ;; NB Never uses BX.
8823 (define_insn "*thumb1_indirect_jump"
8825 (match_operand:SI 0 "register_operand" "l*r"))]
8828 [(set_attr "conds" "clob")
8829 (set_attr "length" "2")]
8839 if (TARGET_UNIFIED_ASM)
8842 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8843 return \"mov\\tr8, r8\";
8845 [(set (attr "length")
8846 (if_then_else (eq_attr "is_thumb" "yes")
8852 ;; Patterns to allow combination of arithmetic, cond code and shifts
8854 (define_insn "*arith_shiftsi"
8855 [(set (match_operand:SI 0 "s_register_operand" "=r")
8856 (match_operator:SI 1 "shiftable_operator"
8857 [(match_operator:SI 3 "shift_operator"
8858 [(match_operand:SI 4 "s_register_operand" "r")
8859 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8860 (match_operand:SI 2 "s_register_operand" "r")]))]
8862 "%i1%?\\t%0, %2, %4%S3"
8863 [(set_attr "predicable" "yes")
8864 (set_attr "shift" "4")
8865 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8866 (const_string "alu_shift")
8867 (const_string "alu_shift_reg")))]
8871 [(set (match_operand:SI 0 "s_register_operand" "")
8872 (match_operator:SI 1 "shiftable_operator"
8873 [(match_operator:SI 2 "shiftable_operator"
8874 [(match_operator:SI 3 "shift_operator"
8875 [(match_operand:SI 4 "s_register_operand" "")
8876 (match_operand:SI 5 "reg_or_int_operand" "")])
8877 (match_operand:SI 6 "s_register_operand" "")])
8878 (match_operand:SI 7 "arm_rhs_operand" "")]))
8879 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8882 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8885 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8888 (define_insn "*arith_shiftsi_compare0"
8889 [(set (reg:CC_NOOV CC_REGNUM)
8890 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8891 [(match_operator:SI 3 "shift_operator"
8892 [(match_operand:SI 4 "s_register_operand" "r")
8893 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8894 (match_operand:SI 2 "s_register_operand" "r")])
8896 (set (match_operand:SI 0 "s_register_operand" "=r")
8897 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8900 "%i1%.\\t%0, %2, %4%S3"
8901 [(set_attr "conds" "set")
8902 (set_attr "shift" "4")
8903 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8904 (const_string "alu_shift")
8905 (const_string "alu_shift_reg")))]
8908 (define_insn "*arith_shiftsi_compare0_scratch"
8909 [(set (reg:CC_NOOV CC_REGNUM)
8910 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8911 [(match_operator:SI 3 "shift_operator"
8912 [(match_operand:SI 4 "s_register_operand" "r")
8913 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8914 (match_operand:SI 2 "s_register_operand" "r")])
8916 (clobber (match_scratch:SI 0 "=r"))]
8918 "%i1%.\\t%0, %2, %4%S3"
8919 [(set_attr "conds" "set")
8920 (set_attr "shift" "4")
8921 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8922 (const_string "alu_shift")
8923 (const_string "alu_shift_reg")))]
8926 (define_insn "*sub_shiftsi"
8927 [(set (match_operand:SI 0 "s_register_operand" "=r")
8928 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8929 (match_operator:SI 2 "shift_operator"
8930 [(match_operand:SI 3 "s_register_operand" "r")
8931 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
8933 "sub%?\\t%0, %1, %3%S2"
8934 [(set_attr "predicable" "yes")
8935 (set_attr "shift" "3")
8936 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8937 (const_string "alu_shift")
8938 (const_string "alu_shift_reg")))]
8941 (define_insn "*sub_shiftsi_compare0"
8942 [(set (reg:CC_NOOV CC_REGNUM)
8944 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8945 (match_operator:SI 2 "shift_operator"
8946 [(match_operand:SI 3 "s_register_operand" "r")
8947 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8949 (set (match_operand:SI 0 "s_register_operand" "=r")
8950 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
8953 "sub%.\\t%0, %1, %3%S2"
8954 [(set_attr "conds" "set")
8955 (set_attr "shift" "3")
8956 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8957 (const_string "alu_shift")
8958 (const_string "alu_shift_reg")))]
8961 (define_insn "*sub_shiftsi_compare0_scratch"
8962 [(set (reg:CC_NOOV CC_REGNUM)
8964 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8965 (match_operator:SI 2 "shift_operator"
8966 [(match_operand:SI 3 "s_register_operand" "r")
8967 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8969 (clobber (match_scratch:SI 0 "=r"))]
8971 "sub%.\\t%0, %1, %3%S2"
8972 [(set_attr "conds" "set")
8973 (set_attr "shift" "3")
8974 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8975 (const_string "alu_shift")
8976 (const_string "alu_shift_reg")))]
8981 (define_insn "*and_scc"
8982 [(set (match_operand:SI 0 "s_register_operand" "=r")
8983 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8984 [(match_operand 3 "cc_register" "") (const_int 0)])
8985 (match_operand:SI 2 "s_register_operand" "r")))]
8987 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8988 [(set_attr "conds" "use")
8989 (set_attr "length" "8")]
8992 (define_insn "*ior_scc"
8993 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8994 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8995 [(match_operand 3 "cc_register" "") (const_int 0)])
8996 (match_operand:SI 1 "s_register_operand" "0,?r")))]
9000 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
9001 [(set_attr "conds" "use")
9002 (set_attr "length" "4,8")]
9005 (define_insn "*compare_scc"
9006 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9007 (match_operator:SI 1 "arm_comparison_operator"
9008 [(match_operand:SI 2 "s_register_operand" "r,r")
9009 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9010 (clobber (reg:CC CC_REGNUM))]
9013 if (operands[3] == const0_rtx)
9015 if (GET_CODE (operands[1]) == LT)
9016 return \"mov\\t%0, %2, lsr #31\";
9018 if (GET_CODE (operands[1]) == GE)
9019 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
9021 if (GET_CODE (operands[1]) == EQ)
9022 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
9025 if (GET_CODE (operands[1]) == NE)
9027 if (which_alternative == 1)
9028 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
9029 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
9031 if (which_alternative == 1)
9032 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9034 output_asm_insn (\"cmp\\t%2, %3\", operands);
9035 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
9037 [(set_attr "conds" "clob")
9038 (set_attr "length" "12")]
9041 (define_insn "*cond_move"
9042 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9043 (if_then_else:SI (match_operator 3 "equality_operator"
9044 [(match_operator 4 "arm_comparison_operator"
9045 [(match_operand 5 "cc_register" "") (const_int 0)])
9047 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9048 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9051 if (GET_CODE (operands[3]) == NE)
9053 if (which_alternative != 1)
9054 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9055 if (which_alternative != 0)
9056 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9059 if (which_alternative != 0)
9060 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9061 if (which_alternative != 1)
9062 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9065 [(set_attr "conds" "use")
9066 (set_attr "length" "4,4,8")]
9069 (define_insn "*cond_arith"
9070 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9071 (match_operator:SI 5 "shiftable_operator"
9072 [(match_operator:SI 4 "arm_comparison_operator"
9073 [(match_operand:SI 2 "s_register_operand" "r,r")
9074 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9075 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9076 (clobber (reg:CC CC_REGNUM))]
9079 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9080 return \"%i5\\t%0, %1, %2, lsr #31\";
9082 output_asm_insn (\"cmp\\t%2, %3\", operands);
9083 if (GET_CODE (operands[5]) == AND)
9084 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9085 else if (GET_CODE (operands[5]) == MINUS)
9086 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9087 else if (which_alternative != 0)
9088 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9089 return \"%i5%d4\\t%0, %1, #1\";
9091 [(set_attr "conds" "clob")
9092 (set_attr "length" "12")]
9095 (define_insn "*cond_sub"
9096 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9097 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9098 (match_operator:SI 4 "arm_comparison_operator"
9099 [(match_operand:SI 2 "s_register_operand" "r,r")
9100 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9101 (clobber (reg:CC CC_REGNUM))]
9104 output_asm_insn (\"cmp\\t%2, %3\", operands);
9105 if (which_alternative != 0)
9106 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9107 return \"sub%d4\\t%0, %1, #1\";
9109 [(set_attr "conds" "clob")
9110 (set_attr "length" "8,12")]
9113 ;; ??? Is it worth using these conditional patterns in Thumb-2 mode?
9114 (define_insn "*cmp_ite0"
9115 [(set (match_operand 6 "dominant_cc_register" "")
9118 (match_operator 4 "arm_comparison_operator"
9119 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
9120 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
9121 (match_operator:SI 5 "arm_comparison_operator"
9122 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
9123 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
9129 static const char * const opcodes[4][2] =
9131 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
9132 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
9133 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
9134 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
9135 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
9136 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
9137 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
9138 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
9141 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9143 return opcodes[which_alternative][swap];
9145 [(set_attr "conds" "set")
9146 (set_attr "length" "8")]
9149 (define_insn "*cmp_ite1"
9150 [(set (match_operand 6 "dominant_cc_register" "")
9153 (match_operator 4 "arm_comparison_operator"
9154 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
9155 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
9156 (match_operator:SI 5 "arm_comparison_operator"
9157 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
9158 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
9164 static const char * const opcodes[4][2] =
9166 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
9167 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
9168 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
9169 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
9170 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
9171 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
9172 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
9173 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
9176 comparison_dominates_p (GET_CODE (operands[5]),
9177 reverse_condition (GET_CODE (operands[4])));
9179 return opcodes[which_alternative][swap];
9181 [(set_attr "conds" "set")
9182 (set_attr "length" "8")]
9185 (define_insn "*cmp_and"
9186 [(set (match_operand 6 "dominant_cc_register" "")
9189 (match_operator 4 "arm_comparison_operator"
9190 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
9191 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
9192 (match_operator:SI 5 "arm_comparison_operator"
9193 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
9194 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
9199 static const char *const opcodes[4][2] =
9201 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
9202 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
9203 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
9204 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
9205 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
9206 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
9207 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
9208 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
9211 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9213 return opcodes[which_alternative][swap];
9215 [(set_attr "conds" "set")
9216 (set_attr "predicable" "no")
9217 (set_attr "length" "8")]
9220 (define_insn "*cmp_ior"
9221 [(set (match_operand 6 "dominant_cc_register" "")
9224 (match_operator 4 "arm_comparison_operator"
9225 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
9226 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
9227 (match_operator:SI 5 "arm_comparison_operator"
9228 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
9229 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
9234 static const char *const opcodes[4][2] =
9236 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
9237 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
9238 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
9239 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
9240 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
9241 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
9242 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
9243 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
9246 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9248 return opcodes[which_alternative][swap];
9251 [(set_attr "conds" "set")
9252 (set_attr "length" "8")]
9255 (define_insn_and_split "*ior_scc_scc"
9256 [(set (match_operand:SI 0 "s_register_operand" "=r")
9257 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9258 [(match_operand:SI 1 "s_register_operand" "r")
9259 (match_operand:SI 2 "arm_add_operand" "rIL")])
9260 (match_operator:SI 6 "arm_comparison_operator"
9261 [(match_operand:SI 4 "s_register_operand" "r")
9262 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9263 (clobber (reg:CC CC_REGNUM))]
9265 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9268 "TARGET_ARM && reload_completed"
9272 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9273 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9275 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9277 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9280 [(set_attr "conds" "clob")
9281 (set_attr "length" "16")])
9283 ; If the above pattern is followed by a CMP insn, then the compare is
9284 ; redundant, since we can rework the conditional instruction that follows.
9285 (define_insn_and_split "*ior_scc_scc_cmp"
9286 [(set (match_operand 0 "dominant_cc_register" "")
9287 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9288 [(match_operand:SI 1 "s_register_operand" "r")
9289 (match_operand:SI 2 "arm_add_operand" "rIL")])
9290 (match_operator:SI 6 "arm_comparison_operator"
9291 [(match_operand:SI 4 "s_register_operand" "r")
9292 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9294 (set (match_operand:SI 7 "s_register_operand" "=r")
9295 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9296 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9299 "TARGET_ARM && reload_completed"
9303 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9304 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9306 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9308 [(set_attr "conds" "set")
9309 (set_attr "length" "16")])
9311 (define_insn_and_split "*and_scc_scc"
9312 [(set (match_operand:SI 0 "s_register_operand" "=r")
9313 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9314 [(match_operand:SI 1 "s_register_operand" "r")
9315 (match_operand:SI 2 "arm_add_operand" "rIL")])
9316 (match_operator:SI 6 "arm_comparison_operator"
9317 [(match_operand:SI 4 "s_register_operand" "r")
9318 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9319 (clobber (reg:CC CC_REGNUM))]
9321 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9324 "TARGET_ARM && reload_completed
9325 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9330 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9331 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9333 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9335 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9338 [(set_attr "conds" "clob")
9339 (set_attr "length" "16")])
9341 ; If the above pattern is followed by a CMP insn, then the compare is
9342 ; redundant, since we can rework the conditional instruction that follows.
9343 (define_insn_and_split "*and_scc_scc_cmp"
9344 [(set (match_operand 0 "dominant_cc_register" "")
9345 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9346 [(match_operand:SI 1 "s_register_operand" "r")
9347 (match_operand:SI 2 "arm_add_operand" "rIL")])
9348 (match_operator:SI 6 "arm_comparison_operator"
9349 [(match_operand:SI 4 "s_register_operand" "r")
9350 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9352 (set (match_operand:SI 7 "s_register_operand" "=r")
9353 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9354 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9357 "TARGET_ARM && reload_completed"
9361 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9362 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9364 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9366 [(set_attr "conds" "set")
9367 (set_attr "length" "16")])
9369 ;; If there is no dominance in the comparison, then we can still save an
9370 ;; instruction in the AND case, since we can know that the second compare
9371 ;; need only zero the value if false (if true, then the value is already
9373 (define_insn_and_split "*and_scc_scc_nodom"
9374 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
9375 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9376 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9377 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9378 (match_operator:SI 6 "arm_comparison_operator"
9379 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9380 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9381 (clobber (reg:CC CC_REGNUM))]
9383 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9386 "TARGET_ARM && reload_completed"
9387 [(parallel [(set (match_dup 0)
9388 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9389 (clobber (reg:CC CC_REGNUM))])
9390 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9392 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9395 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9396 operands[4], operands[5]),
9398 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9400 [(set_attr "conds" "clob")
9401 (set_attr "length" "20")])
9404 [(set (reg:CC_NOOV CC_REGNUM)
9405 (compare:CC_NOOV (ior:SI
9406 (and:SI (match_operand:SI 0 "s_register_operand" "")
9408 (match_operator:SI 1 "comparison_operator"
9409 [(match_operand:SI 2 "s_register_operand" "")
9410 (match_operand:SI 3 "arm_add_operand" "")]))
9412 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9415 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9417 (set (reg:CC_NOOV CC_REGNUM)
9418 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9423 [(set (reg:CC_NOOV CC_REGNUM)
9424 (compare:CC_NOOV (ior:SI
9425 (match_operator:SI 1 "comparison_operator"
9426 [(match_operand:SI 2 "s_register_operand" "")
9427 (match_operand:SI 3 "arm_add_operand" "")])
9428 (and:SI (match_operand:SI 0 "s_register_operand" "")
9431 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9434 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9436 (set (reg:CC_NOOV CC_REGNUM)
9437 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9440 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9442 (define_insn "*negscc"
9443 [(set (match_operand:SI 0 "s_register_operand" "=r")
9444 (neg:SI (match_operator 3 "arm_comparison_operator"
9445 [(match_operand:SI 1 "s_register_operand" "r")
9446 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9447 (clobber (reg:CC CC_REGNUM))]
9450 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9451 return \"mov\\t%0, %1, asr #31\";
9453 if (GET_CODE (operands[3]) == NE)
9454 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
9456 output_asm_insn (\"cmp\\t%1, %2\", operands);
9457 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
9458 return \"mvn%d3\\t%0, #0\";
9460 [(set_attr "conds" "clob")
9461 (set_attr "length" "12")]
9464 (define_insn "movcond"
9465 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9467 (match_operator 5 "arm_comparison_operator"
9468 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9469 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9470 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9471 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9472 (clobber (reg:CC CC_REGNUM))]
9475 if (GET_CODE (operands[5]) == LT
9476 && (operands[4] == const0_rtx))
9478 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
9480 if (operands[2] == const0_rtx)
9481 return \"and\\t%0, %1, %3, asr #31\";
9482 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9484 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
9486 if (operands[1] == const0_rtx)
9487 return \"bic\\t%0, %2, %3, asr #31\";
9488 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9490 /* The only case that falls through to here is when both ops 1 & 2
9494 if (GET_CODE (operands[5]) == GE
9495 && (operands[4] == const0_rtx))
9497 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
9499 if (operands[2] == const0_rtx)
9500 return \"bic\\t%0, %1, %3, asr #31\";
9501 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9503 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
9505 if (operands[1] == const0_rtx)
9506 return \"and\\t%0, %2, %3, asr #31\";
9507 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9509 /* The only case that falls through to here is when both ops 1 & 2
9512 if (GET_CODE (operands[4]) == CONST_INT
9513 && !const_ok_for_arm (INTVAL (operands[4])))
9514 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9516 output_asm_insn (\"cmp\\t%3, %4\", operands);
9517 if (which_alternative != 0)
9518 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9519 if (which_alternative != 1)
9520 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9523 [(set_attr "conds" "clob")
9524 (set_attr "length" "8,8,12")]
9527 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9529 (define_insn "*ifcompare_plus_move"
9530 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9531 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9532 [(match_operand:SI 4 "s_register_operand" "r,r")
9533 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9535 (match_operand:SI 2 "s_register_operand" "r,r")
9536 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9537 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9538 (clobber (reg:CC CC_REGNUM))]
9541 [(set_attr "conds" "clob")
9542 (set_attr "length" "8,12")]
9545 (define_insn "*if_plus_move"
9546 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9548 (match_operator 4 "arm_comparison_operator"
9549 [(match_operand 5 "cc_register" "") (const_int 0)])
9551 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9552 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9553 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9557 sub%d4\\t%0, %2, #%n3
9558 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9559 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9560 [(set_attr "conds" "use")
9561 (set_attr "length" "4,4,8,8")
9562 (set_attr "type" "*,*,*,*")]
9565 (define_insn "*ifcompare_move_plus"
9566 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9567 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9568 [(match_operand:SI 4 "s_register_operand" "r,r")
9569 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9570 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9572 (match_operand:SI 2 "s_register_operand" "r,r")
9573 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9574 (clobber (reg:CC CC_REGNUM))]
9577 [(set_attr "conds" "clob")
9578 (set_attr "length" "8,12")]
9581 (define_insn "*if_move_plus"
9582 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9584 (match_operator 4 "arm_comparison_operator"
9585 [(match_operand 5 "cc_register" "") (const_int 0)])
9586 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9588 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9589 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9593 sub%D4\\t%0, %2, #%n3
9594 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9595 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9596 [(set_attr "conds" "use")
9597 (set_attr "length" "4,4,8,8")
9598 (set_attr "type" "*,*,*,*")]
9601 (define_insn "*ifcompare_arith_arith"
9602 [(set (match_operand:SI 0 "s_register_operand" "=r")
9603 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9604 [(match_operand:SI 5 "s_register_operand" "r")
9605 (match_operand:SI 6 "arm_add_operand" "rIL")])
9606 (match_operator:SI 8 "shiftable_operator"
9607 [(match_operand:SI 1 "s_register_operand" "r")
9608 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9609 (match_operator:SI 7 "shiftable_operator"
9610 [(match_operand:SI 3 "s_register_operand" "r")
9611 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9612 (clobber (reg:CC CC_REGNUM))]
9615 [(set_attr "conds" "clob")
9616 (set_attr "length" "12")]
9619 (define_insn "*if_arith_arith"
9620 [(set (match_operand:SI 0 "s_register_operand" "=r")
9621 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9622 [(match_operand 8 "cc_register" "") (const_int 0)])
9623 (match_operator:SI 6 "shiftable_operator"
9624 [(match_operand:SI 1 "s_register_operand" "r")
9625 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9626 (match_operator:SI 7 "shiftable_operator"
9627 [(match_operand:SI 3 "s_register_operand" "r")
9628 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9630 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9631 [(set_attr "conds" "use")
9632 (set_attr "length" "8")]
9635 (define_insn "*ifcompare_arith_move"
9636 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9637 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9638 [(match_operand:SI 2 "s_register_operand" "r,r")
9639 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9640 (match_operator:SI 7 "shiftable_operator"
9641 [(match_operand:SI 4 "s_register_operand" "r,r")
9642 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9643 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9644 (clobber (reg:CC CC_REGNUM))]
9647 /* If we have an operation where (op x 0) is the identity operation and
9648 the conditional operator is LT or GE and we are comparing against zero and
9649 everything is in registers then we can do this in two instructions. */
9650 if (operands[3] == const0_rtx
9651 && GET_CODE (operands[7]) != AND
9652 && GET_CODE (operands[5]) == REG
9653 && GET_CODE (operands[1]) == REG
9654 && REGNO (operands[1]) == REGNO (operands[4])
9655 && REGNO (operands[4]) != REGNO (operands[0]))
9657 if (GET_CODE (operands[6]) == LT)
9658 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9659 else if (GET_CODE (operands[6]) == GE)
9660 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9662 if (GET_CODE (operands[3]) == CONST_INT
9663 && !const_ok_for_arm (INTVAL (operands[3])))
9664 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9666 output_asm_insn (\"cmp\\t%2, %3\", operands);
9667 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9668 if (which_alternative != 0)
9669 return \"mov%D6\\t%0, %1\";
9672 [(set_attr "conds" "clob")
9673 (set_attr "length" "8,12")]
9676 (define_insn "*if_arith_move"
9677 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9678 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9679 [(match_operand 6 "cc_register" "") (const_int 0)])
9680 (match_operator:SI 5 "shiftable_operator"
9681 [(match_operand:SI 2 "s_register_operand" "r,r")
9682 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9683 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9687 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9688 [(set_attr "conds" "use")
9689 (set_attr "length" "4,8")
9690 (set_attr "type" "*,*")]
9693 (define_insn "*ifcompare_move_arith"
9694 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9695 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9696 [(match_operand:SI 4 "s_register_operand" "r,r")
9697 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9698 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9699 (match_operator:SI 7 "shiftable_operator"
9700 [(match_operand:SI 2 "s_register_operand" "r,r")
9701 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9702 (clobber (reg:CC CC_REGNUM))]
9705 /* If we have an operation where (op x 0) is the identity operation and
9706 the conditional operator is LT or GE and we are comparing against zero and
9707 everything is in registers then we can do this in two instructions */
9708 if (operands[5] == const0_rtx
9709 && GET_CODE (operands[7]) != AND
9710 && GET_CODE (operands[3]) == REG
9711 && GET_CODE (operands[1]) == REG
9712 && REGNO (operands[1]) == REGNO (operands[2])
9713 && REGNO (operands[2]) != REGNO (operands[0]))
9715 if (GET_CODE (operands[6]) == GE)
9716 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9717 else if (GET_CODE (operands[6]) == LT)
9718 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9721 if (GET_CODE (operands[5]) == CONST_INT
9722 && !const_ok_for_arm (INTVAL (operands[5])))
9723 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9725 output_asm_insn (\"cmp\\t%4, %5\", operands);
9727 if (which_alternative != 0)
9728 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9729 return \"%I7%D6\\t%0, %2, %3\";
9731 [(set_attr "conds" "clob")
9732 (set_attr "length" "8,12")]
9735 (define_insn "*if_move_arith"
9736 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9738 (match_operator 4 "arm_comparison_operator"
9739 [(match_operand 6 "cc_register" "") (const_int 0)])
9740 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9741 (match_operator:SI 5 "shiftable_operator"
9742 [(match_operand:SI 2 "s_register_operand" "r,r")
9743 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9747 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9748 [(set_attr "conds" "use")
9749 (set_attr "length" "4,8")
9750 (set_attr "type" "*,*")]
9753 (define_insn "*ifcompare_move_not"
9754 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9756 (match_operator 5 "arm_comparison_operator"
9757 [(match_operand:SI 3 "s_register_operand" "r,r")
9758 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9759 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9761 (match_operand:SI 2 "s_register_operand" "r,r"))))
9762 (clobber (reg:CC CC_REGNUM))]
9765 [(set_attr "conds" "clob")
9766 (set_attr "length" "8,12")]
9769 (define_insn "*if_move_not"
9770 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9772 (match_operator 4 "arm_comparison_operator"
9773 [(match_operand 3 "cc_register" "") (const_int 0)])
9774 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9775 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9779 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9780 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9781 [(set_attr "conds" "use")
9782 (set_attr "length" "4,8,8")]
9785 (define_insn "*ifcompare_not_move"
9786 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9788 (match_operator 5 "arm_comparison_operator"
9789 [(match_operand:SI 3 "s_register_operand" "r,r")
9790 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9792 (match_operand:SI 2 "s_register_operand" "r,r"))
9793 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9794 (clobber (reg:CC CC_REGNUM))]
9797 [(set_attr "conds" "clob")
9798 (set_attr "length" "8,12")]
9801 (define_insn "*if_not_move"
9802 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9804 (match_operator 4 "arm_comparison_operator"
9805 [(match_operand 3 "cc_register" "") (const_int 0)])
9806 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9807 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9811 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9812 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9813 [(set_attr "conds" "use")
9814 (set_attr "length" "4,8,8")]
9817 (define_insn "*ifcompare_shift_move"
9818 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9820 (match_operator 6 "arm_comparison_operator"
9821 [(match_operand:SI 4 "s_register_operand" "r,r")
9822 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9823 (match_operator:SI 7 "shift_operator"
9824 [(match_operand:SI 2 "s_register_operand" "r,r")
9825 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9826 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9827 (clobber (reg:CC CC_REGNUM))]
9830 [(set_attr "conds" "clob")
9831 (set_attr "length" "8,12")]
9834 (define_insn "*if_shift_move"
9835 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9837 (match_operator 5 "arm_comparison_operator"
9838 [(match_operand 6 "cc_register" "") (const_int 0)])
9839 (match_operator:SI 4 "shift_operator"
9840 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9841 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9842 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9846 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9847 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9848 [(set_attr "conds" "use")
9849 (set_attr "shift" "2")
9850 (set_attr "length" "4,8,8")
9851 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9852 (const_string "alu_shift")
9853 (const_string "alu_shift_reg")))]
9856 (define_insn "*ifcompare_move_shift"
9857 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9859 (match_operator 6 "arm_comparison_operator"
9860 [(match_operand:SI 4 "s_register_operand" "r,r")
9861 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9862 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9863 (match_operator:SI 7 "shift_operator"
9864 [(match_operand:SI 2 "s_register_operand" "r,r")
9865 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9866 (clobber (reg:CC CC_REGNUM))]
9869 [(set_attr "conds" "clob")
9870 (set_attr "length" "8,12")]
9873 (define_insn "*if_move_shift"
9874 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9876 (match_operator 5 "arm_comparison_operator"
9877 [(match_operand 6 "cc_register" "") (const_int 0)])
9878 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9879 (match_operator:SI 4 "shift_operator"
9880 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9881 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9885 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9886 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9887 [(set_attr "conds" "use")
9888 (set_attr "shift" "2")
9889 (set_attr "length" "4,8,8")
9890 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9891 (const_string "alu_shift")
9892 (const_string "alu_shift_reg")))]
9895 (define_insn "*ifcompare_shift_shift"
9896 [(set (match_operand:SI 0 "s_register_operand" "=r")
9898 (match_operator 7 "arm_comparison_operator"
9899 [(match_operand:SI 5 "s_register_operand" "r")
9900 (match_operand:SI 6 "arm_add_operand" "rIL")])
9901 (match_operator:SI 8 "shift_operator"
9902 [(match_operand:SI 1 "s_register_operand" "r")
9903 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9904 (match_operator:SI 9 "shift_operator"
9905 [(match_operand:SI 3 "s_register_operand" "r")
9906 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9907 (clobber (reg:CC CC_REGNUM))]
9910 [(set_attr "conds" "clob")
9911 (set_attr "length" "12")]
9914 (define_insn "*if_shift_shift"
9915 [(set (match_operand:SI 0 "s_register_operand" "=r")
9917 (match_operator 5 "arm_comparison_operator"
9918 [(match_operand 8 "cc_register" "") (const_int 0)])
9919 (match_operator:SI 6 "shift_operator"
9920 [(match_operand:SI 1 "s_register_operand" "r")
9921 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9922 (match_operator:SI 7 "shift_operator"
9923 [(match_operand:SI 3 "s_register_operand" "r")
9924 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9926 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9927 [(set_attr "conds" "use")
9928 (set_attr "shift" "1")
9929 (set_attr "length" "8")
9930 (set (attr "type") (if_then_else
9931 (and (match_operand 2 "const_int_operand" "")
9932 (match_operand 4 "const_int_operand" ""))
9933 (const_string "alu_shift")
9934 (const_string "alu_shift_reg")))]
9937 (define_insn "*ifcompare_not_arith"
9938 [(set (match_operand:SI 0 "s_register_operand" "=r")
9940 (match_operator 6 "arm_comparison_operator"
9941 [(match_operand:SI 4 "s_register_operand" "r")
9942 (match_operand:SI 5 "arm_add_operand" "rIL")])
9943 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9944 (match_operator:SI 7 "shiftable_operator"
9945 [(match_operand:SI 2 "s_register_operand" "r")
9946 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9947 (clobber (reg:CC CC_REGNUM))]
9950 [(set_attr "conds" "clob")
9951 (set_attr "length" "12")]
9954 (define_insn "*if_not_arith"
9955 [(set (match_operand:SI 0 "s_register_operand" "=r")
9957 (match_operator 5 "arm_comparison_operator"
9958 [(match_operand 4 "cc_register" "") (const_int 0)])
9959 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9960 (match_operator:SI 6 "shiftable_operator"
9961 [(match_operand:SI 2 "s_register_operand" "r")
9962 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9964 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9965 [(set_attr "conds" "use")
9966 (set_attr "length" "8")]
9969 (define_insn "*ifcompare_arith_not"
9970 [(set (match_operand:SI 0 "s_register_operand" "=r")
9972 (match_operator 6 "arm_comparison_operator"
9973 [(match_operand:SI 4 "s_register_operand" "r")
9974 (match_operand:SI 5 "arm_add_operand" "rIL")])
9975 (match_operator:SI 7 "shiftable_operator"
9976 [(match_operand:SI 2 "s_register_operand" "r")
9977 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9978 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9979 (clobber (reg:CC CC_REGNUM))]
9982 [(set_attr "conds" "clob")
9983 (set_attr "length" "12")]
9986 (define_insn "*if_arith_not"
9987 [(set (match_operand:SI 0 "s_register_operand" "=r")
9989 (match_operator 5 "arm_comparison_operator"
9990 [(match_operand 4 "cc_register" "") (const_int 0)])
9991 (match_operator:SI 6 "shiftable_operator"
9992 [(match_operand:SI 2 "s_register_operand" "r")
9993 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9994 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9996 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9997 [(set_attr "conds" "use")
9998 (set_attr "length" "8")]
10001 (define_insn "*ifcompare_neg_move"
10002 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10004 (match_operator 5 "arm_comparison_operator"
10005 [(match_operand:SI 3 "s_register_operand" "r,r")
10006 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10007 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10008 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10009 (clobber (reg:CC CC_REGNUM))]
10012 [(set_attr "conds" "clob")
10013 (set_attr "length" "8,12")]
10016 (define_insn "*if_neg_move"
10017 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10019 (match_operator 4 "arm_comparison_operator"
10020 [(match_operand 3 "cc_register" "") (const_int 0)])
10021 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10022 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10025 rsb%d4\\t%0, %2, #0
10026 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
10027 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
10028 [(set_attr "conds" "use")
10029 (set_attr "length" "4,8,8")]
10032 (define_insn "*ifcompare_move_neg"
10033 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10035 (match_operator 5 "arm_comparison_operator"
10036 [(match_operand:SI 3 "s_register_operand" "r,r")
10037 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10038 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10039 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10040 (clobber (reg:CC CC_REGNUM))]
10043 [(set_attr "conds" "clob")
10044 (set_attr "length" "8,12")]
10047 (define_insn "*if_move_neg"
10048 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10050 (match_operator 4 "arm_comparison_operator"
10051 [(match_operand 3 "cc_register" "") (const_int 0)])
10052 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10053 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10056 rsb%D4\\t%0, %2, #0
10057 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
10058 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
10059 [(set_attr "conds" "use")
10060 (set_attr "length" "4,8,8")]
10063 (define_insn "*arith_adjacentmem"
10064 [(set (match_operand:SI 0 "s_register_operand" "=r")
10065 (match_operator:SI 1 "shiftable_operator"
10066 [(match_operand:SI 2 "memory_operand" "m")
10067 (match_operand:SI 3 "memory_operand" "m")]))
10068 (clobber (match_scratch:SI 4 "=r"))]
10069 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10075 HOST_WIDE_INT val1 = 0, val2 = 0;
10077 if (REGNO (operands[0]) > REGNO (operands[4]))
10079 ldm[1] = operands[4];
10080 ldm[2] = operands[0];
10084 ldm[1] = operands[0];
10085 ldm[2] = operands[4];
10088 base_reg = XEXP (operands[2], 0);
10090 if (!REG_P (base_reg))
10092 val1 = INTVAL (XEXP (base_reg, 1));
10093 base_reg = XEXP (base_reg, 0);
10096 if (!REG_P (XEXP (operands[3], 0)))
10097 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10099 arith[0] = operands[0];
10100 arith[3] = operands[1];
10114 if (val1 !=0 && val2 != 0)
10118 if (val1 == 4 || val2 == 4)
10119 /* Other val must be 8, since we know they are adjacent and neither
10121 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10122 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10124 ldm[0] = ops[0] = operands[4];
10126 ops[2] = GEN_INT (val1);
10127 output_add_immediate (ops);
10129 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10131 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10135 /* Offset is out of range for a single add, so use two ldr. */
10138 ops[2] = GEN_INT (val1);
10139 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10141 ops[2] = GEN_INT (val2);
10142 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10145 else if (val1 != 0)
10148 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10150 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10155 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10157 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10159 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10162 [(set_attr "length" "12")
10163 (set_attr "predicable" "yes")
10164 (set_attr "type" "load1")]
10167 ; This pattern is never tried by combine, so do it as a peephole
10170 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10171 (match_operand:SI 1 "arm_general_register_operand" ""))
10172 (set (reg:CC CC_REGNUM)
10173 (compare:CC (match_dup 1) (const_int 0)))]
10175 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10176 (set (match_dup 0) (match_dup 1))])]
10180 ; Peepholes to spot possible load- and store-multiples, if the ordering is
10181 ; reversed, check that the memory references aren't volatile.
10184 [(set (match_operand:SI 0 "s_register_operand" "=r")
10185 (match_operand:SI 4 "memory_operand" "m"))
10186 (set (match_operand:SI 1 "s_register_operand" "=r")
10187 (match_operand:SI 5 "memory_operand" "m"))
10188 (set (match_operand:SI 2 "s_register_operand" "=r")
10189 (match_operand:SI 6 "memory_operand" "m"))
10190 (set (match_operand:SI 3 "s_register_operand" "=r")
10191 (match_operand:SI 7 "memory_operand" "m"))]
10192 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
10194 return emit_ldm_seq (operands, 4);
10199 [(set (match_operand:SI 0 "s_register_operand" "=r")
10200 (match_operand:SI 3 "memory_operand" "m"))
10201 (set (match_operand:SI 1 "s_register_operand" "=r")
10202 (match_operand:SI 4 "memory_operand" "m"))
10203 (set (match_operand:SI 2 "s_register_operand" "=r")
10204 (match_operand:SI 5 "memory_operand" "m"))]
10205 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
10207 return emit_ldm_seq (operands, 3);
10212 [(set (match_operand:SI 0 "s_register_operand" "=r")
10213 (match_operand:SI 2 "memory_operand" "m"))
10214 (set (match_operand:SI 1 "s_register_operand" "=r")
10215 (match_operand:SI 3 "memory_operand" "m"))]
10216 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
10218 return emit_ldm_seq (operands, 2);
10223 [(set (match_operand:SI 4 "memory_operand" "=m")
10224 (match_operand:SI 0 "s_register_operand" "r"))
10225 (set (match_operand:SI 5 "memory_operand" "=m")
10226 (match_operand:SI 1 "s_register_operand" "r"))
10227 (set (match_operand:SI 6 "memory_operand" "=m")
10228 (match_operand:SI 2 "s_register_operand" "r"))
10229 (set (match_operand:SI 7 "memory_operand" "=m")
10230 (match_operand:SI 3 "s_register_operand" "r"))]
10231 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
10233 return emit_stm_seq (operands, 4);
10238 [(set (match_operand:SI 3 "memory_operand" "=m")
10239 (match_operand:SI 0 "s_register_operand" "r"))
10240 (set (match_operand:SI 4 "memory_operand" "=m")
10241 (match_operand:SI 1 "s_register_operand" "r"))
10242 (set (match_operand:SI 5 "memory_operand" "=m")
10243 (match_operand:SI 2 "s_register_operand" "r"))]
10244 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
10246 return emit_stm_seq (operands, 3);
10251 [(set (match_operand:SI 2 "memory_operand" "=m")
10252 (match_operand:SI 0 "s_register_operand" "r"))
10253 (set (match_operand:SI 3 "memory_operand" "=m")
10254 (match_operand:SI 1 "s_register_operand" "r"))]
10255 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
10257 return emit_stm_seq (operands, 2);
10262 [(set (match_operand:SI 0 "s_register_operand" "")
10263 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10265 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10266 [(match_operand:SI 3 "s_register_operand" "")
10267 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10268 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10270 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10271 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10276 ;; This split can be used because CC_Z mode implies that the following
10277 ;; branch will be an equality, or an unsigned inequality, so the sign
10278 ;; extension is not needed.
10281 [(set (reg:CC_Z CC_REGNUM)
10283 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10285 (match_operand 1 "const_int_operand" "")))
10286 (clobber (match_scratch:SI 2 ""))]
10288 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10289 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10290 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10291 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10293 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10296 ;; ??? Check the patterns above for Thumb-2 usefulness
10298 (define_expand "prologue"
10299 [(clobber (const_int 0))]
10302 arm_expand_prologue ();
10304 thumb1_expand_prologue ();
10309 (define_expand "epilogue"
10310 [(clobber (const_int 0))]
10313 if (current_function_calls_eh_return)
10314 emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
10316 thumb1_expand_epilogue ();
10317 else if (USE_RETURN_INSN (FALSE))
10319 emit_jump_insn (gen_return ());
10322 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10324 gen_rtx_RETURN (VOIDmode)),
10325 VUNSPEC_EPILOGUE));
10330 ;; Note - although unspec_volatile's USE all hard registers,
10331 ;; USEs are ignored after relaod has completed. Thus we need
10332 ;; to add an unspec of the link register to ensure that flow
10333 ;; does not think that it is unused by the sibcall branch that
10334 ;; will replace the standard function epilogue.
10335 (define_insn "sibcall_epilogue"
10336 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
10337 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10340 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
10341 return output_return_instruction (const_true_rtx, FALSE, FALSE);
10342 return arm_output_epilogue (next_nonnote_insn (insn));
10344 ;; Length is absolute worst case
10345 [(set_attr "length" "44")
10346 (set_attr "type" "block")
10347 ;; We don't clobber the conditions, but the potential length of this
10348 ;; operation is sufficient to make conditionalizing the sequence
10349 ;; unlikely to be profitable.
10350 (set_attr "conds" "clob")]
10353 (define_insn "*epilogue_insns"
10354 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
10358 return arm_output_epilogue (NULL);
10359 else /* TARGET_THUMB1 */
10360 return thumb_unexpanded_epilogue ();
10362 ; Length is absolute worst case
10363 [(set_attr "length" "44")
10364 (set_attr "type" "block")
10365 ;; We don't clobber the conditions, but the potential length of this
10366 ;; operation is sufficient to make conditionalizing the sequence
10367 ;; unlikely to be profitable.
10368 (set_attr "conds" "clob")]
10371 (define_expand "eh_epilogue"
10372 [(use (match_operand:SI 0 "register_operand" ""))
10373 (use (match_operand:SI 1 "register_operand" ""))
10374 (use (match_operand:SI 2 "register_operand" ""))]
10378 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10379 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
10381 rtx ra = gen_rtx_REG (Pmode, 2);
10383 emit_move_insn (ra, operands[2]);
10386 /* This is a hack -- we may have crystalized the function type too
10388 cfun->machine->func_type = 0;
10392 ;; This split is only used during output to reduce the number of patterns
10393 ;; that need assembler instructions adding to them. We allowed the setting
10394 ;; of the conditions to be implicit during rtl generation so that
10395 ;; the conditional compare patterns would work. However this conflicts to
10396 ;; some extent with the conditional data operations, so we have to split them
10399 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10400 ;; conditional execution sufficient?
10403 [(set (match_operand:SI 0 "s_register_operand" "")
10404 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10405 [(match_operand 2 "" "") (match_operand 3 "" "")])
10407 (match_operand 4 "" "")))
10408 (clobber (reg:CC CC_REGNUM))]
10409 "TARGET_ARM && reload_completed"
10410 [(set (match_dup 5) (match_dup 6))
10411 (cond_exec (match_dup 7)
10412 (set (match_dup 0) (match_dup 4)))]
10415 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10416 operands[2], operands[3]);
10417 enum rtx_code rc = GET_CODE (operands[1]);
10419 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10420 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10421 if (mode == CCFPmode || mode == CCFPEmode)
10422 rc = reverse_condition_maybe_unordered (rc);
10424 rc = reverse_condition (rc);
10426 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10431 [(set (match_operand:SI 0 "s_register_operand" "")
10432 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10433 [(match_operand 2 "" "") (match_operand 3 "" "")])
10434 (match_operand 4 "" "")
10436 (clobber (reg:CC CC_REGNUM))]
10437 "TARGET_ARM && reload_completed"
10438 [(set (match_dup 5) (match_dup 6))
10439 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10440 (set (match_dup 0) (match_dup 4)))]
10443 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10444 operands[2], operands[3]);
10446 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10447 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10452 [(set (match_operand:SI 0 "s_register_operand" "")
10453 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10454 [(match_operand 2 "" "") (match_operand 3 "" "")])
10455 (match_operand 4 "" "")
10456 (match_operand 5 "" "")))
10457 (clobber (reg:CC CC_REGNUM))]
10458 "TARGET_ARM && reload_completed"
10459 [(set (match_dup 6) (match_dup 7))
10460 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10461 (set (match_dup 0) (match_dup 4)))
10462 (cond_exec (match_dup 8)
10463 (set (match_dup 0) (match_dup 5)))]
10466 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10467 operands[2], operands[3]);
10468 enum rtx_code rc = GET_CODE (operands[1]);
10470 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10471 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10472 if (mode == CCFPmode || mode == CCFPEmode)
10473 rc = reverse_condition_maybe_unordered (rc);
10475 rc = reverse_condition (rc);
10477 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10482 [(set (match_operand:SI 0 "s_register_operand" "")
10483 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10484 [(match_operand:SI 2 "s_register_operand" "")
10485 (match_operand:SI 3 "arm_add_operand" "")])
10486 (match_operand:SI 4 "arm_rhs_operand" "")
10488 (match_operand:SI 5 "s_register_operand" ""))))
10489 (clobber (reg:CC CC_REGNUM))]
10490 "TARGET_ARM && reload_completed"
10491 [(set (match_dup 6) (match_dup 7))
10492 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10493 (set (match_dup 0) (match_dup 4)))
10494 (cond_exec (match_dup 8)
10495 (set (match_dup 0) (not:SI (match_dup 5))))]
10498 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10499 operands[2], operands[3]);
10500 enum rtx_code rc = GET_CODE (operands[1]);
10502 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10503 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10504 if (mode == CCFPmode || mode == CCFPEmode)
10505 rc = reverse_condition_maybe_unordered (rc);
10507 rc = reverse_condition (rc);
10509 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10513 (define_insn "*cond_move_not"
10514 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10515 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10516 [(match_operand 3 "cc_register" "") (const_int 0)])
10517 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10519 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10523 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10524 [(set_attr "conds" "use")
10525 (set_attr "length" "4,8")]
10528 ;; The next two patterns occur when an AND operation is followed by a
10529 ;; scc insn sequence
10531 (define_insn "*sign_extract_onebit"
10532 [(set (match_operand:SI 0 "s_register_operand" "=r")
10533 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10535 (match_operand:SI 2 "const_int_operand" "n")))
10536 (clobber (reg:CC CC_REGNUM))]
10539 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10540 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10541 return \"mvnne\\t%0, #0\";
10543 [(set_attr "conds" "clob")
10544 (set_attr "length" "8")]
10547 (define_insn "*not_signextract_onebit"
10548 [(set (match_operand:SI 0 "s_register_operand" "=r")
10550 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10552 (match_operand:SI 2 "const_int_operand" "n"))))
10553 (clobber (reg:CC CC_REGNUM))]
10556 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10557 output_asm_insn (\"tst\\t%1, %2\", operands);
10558 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10559 return \"movne\\t%0, #0\";
10561 [(set_attr "conds" "clob")
10562 (set_attr "length" "12")]
10564 ;; ??? The above patterns need auditing for Thumb-2
10566 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10567 ;; expressions. For simplicity, the first register is also in the unspec
10569 (define_insn "*push_multi"
10570 [(match_parallel 2 "multi_register_push"
10571 [(set (match_operand:BLK 0 "memory_operand" "=m")
10572 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10573 UNSPEC_PUSH_MULT))])]
10577 int num_saves = XVECLEN (operands[2], 0);
10579 /* For the StrongARM at least it is faster to
10580 use STR to store only a single register.
10581 In Thumb mode always use push, and the assembler will pick
10582 something appropriate. */
10583 if (num_saves == 1 && TARGET_ARM)
10584 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10591 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10593 strcpy (pattern, \"push\\t{%1\");
10595 for (i = 1; i < num_saves; i++)
10597 strcat (pattern, \", %|\");
10599 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10602 strcat (pattern, \"}\");
10603 output_asm_insn (pattern, operands);
10608 [(set_attr "type" "store4")]
10611 (define_insn "stack_tie"
10612 [(set (mem:BLK (scratch))
10613 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10614 (match_operand:SI 1 "s_register_operand" "r")]
10618 [(set_attr "length" "0")]
10621 ;; Similarly for the floating point registers
10622 (define_insn "*push_fp_multi"
10623 [(match_parallel 2 "multi_register_push"
10624 [(set (match_operand:BLK 0 "memory_operand" "=m")
10625 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10626 UNSPEC_PUSH_MULT))])]
10627 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
10632 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10633 output_asm_insn (pattern, operands);
10636 [(set_attr "type" "f_store")]
10639 ;; Special patterns for dealing with the constant pool
10641 (define_insn "align_4"
10642 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10645 assemble_align (32);
10650 (define_insn "align_8"
10651 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10654 assemble_align (64);
10659 (define_insn "consttable_end"
10660 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10663 making_const_table = FALSE;
10668 (define_insn "consttable_1"
10669 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10672 making_const_table = TRUE;
10673 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10674 assemble_zeros (3);
10677 [(set_attr "length" "4")]
10680 (define_insn "consttable_2"
10681 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10684 making_const_table = TRUE;
10685 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10686 assemble_zeros (2);
10689 [(set_attr "length" "4")]
10692 (define_insn "consttable_4"
10693 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10697 making_const_table = TRUE;
10698 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10703 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10704 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10708 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10713 [(set_attr "length" "4")]
10716 (define_insn "consttable_8"
10717 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10721 making_const_table = TRUE;
10722 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10727 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10728 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10732 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10737 [(set_attr "length" "8")]
10740 (define_insn "consttable_16"
10741 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10745 making_const_table = TRUE;
10746 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10751 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10752 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10756 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10761 [(set_attr "length" "16")]
10764 ;; Miscellaneous Thumb patterns
10766 (define_expand "tablejump"
10767 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10768 (use (label_ref (match_operand 1 "" "")))])]
10773 /* Hopefully, CSE will eliminate this copy. */
10774 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10775 rtx reg2 = gen_reg_rtx (SImode);
10777 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10778 operands[0] = reg2;
10783 ;; NB never uses BX.
10784 (define_insn "*thumb1_tablejump"
10785 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10786 (use (label_ref (match_operand 1 "" "")))]
10789 [(set_attr "length" "2")]
10792 ;; V5 Instructions,
10794 (define_insn "clzsi2"
10795 [(set (match_operand:SI 0 "s_register_operand" "=r")
10796 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10797 "TARGET_32BIT && arm_arch5"
10799 [(set_attr "predicable" "yes")
10800 (set_attr "insn" "clz")])
10802 ;; V5E instructions.
10804 (define_insn "prefetch"
10805 [(prefetch (match_operand:SI 0 "address_operand" "p")
10806 (match_operand:SI 1 "" "")
10807 (match_operand:SI 2 "" ""))]
10808 "TARGET_32BIT && arm_arch5e"
10811 ;; General predication pattern
10814 [(match_operator 0 "arm_comparison_operator"
10815 [(match_operand 1 "cc_register" "")
10821 (define_insn "prologue_use"
10822 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10824 "%@ %0 needed for prologue"
10828 ;; Patterns for exception handling
10830 (define_expand "eh_return"
10831 [(use (match_operand 0 "general_operand" ""))]
10836 emit_insn (gen_arm_eh_return (operands[0]));
10838 emit_insn (gen_thumb_eh_return (operands[0]));
10843 ;; We can't expand this before we know where the link register is stored.
10844 (define_insn_and_split "arm_eh_return"
10845 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10847 (clobber (match_scratch:SI 1 "=&r"))]
10850 "&& reload_completed"
10854 arm_set_return_address (operands[0], operands[1]);
10859 (define_insn_and_split "thumb_eh_return"
10860 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
10862 (clobber (match_scratch:SI 1 "=&l"))]
10865 "&& reload_completed"
10869 thumb_set_return_address (operands[0], operands[1]);
10877 (define_insn "load_tp_hard"
10878 [(set (match_operand:SI 0 "register_operand" "=r")
10879 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10881 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10882 [(set_attr "predicable" "yes")]
10885 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10886 (define_insn "load_tp_soft"
10887 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10888 (clobber (reg:SI LR_REGNUM))
10889 (clobber (reg:SI IP_REGNUM))
10890 (clobber (reg:CC CC_REGNUM))]
10892 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10893 [(set_attr "conds" "clob")]
10896 ;; Load the FPA co-processor patterns
10898 ;; Load the Maverick co-processor patterns
10899 (include "cirrus.md")
10900 ;; Vector bits common to IWMMXT and Neon
10901 (include "vec-common.md")
10902 ;; Load the Intel Wireless Multimedia Extension patterns
10903 (include "iwmmxt.md")
10904 ;; Load the VFP co-processor patterns
10906 ;; Thumb-2 patterns
10907 (include "thumb2.md")
10909 (include "neon.md")