1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
5 ;; and Martin Simmons (@harleqn.co.uk).
6 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published
12 ;; by the Free Software Foundation; either version 2, or (at your
13 ;; option) any later version.
15 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 ;; License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;---------------------------------------------------------------------------
33 [(R0_REGNUM 0) ; First CORE register
34 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (CC_REGNUM 24) ; Condition code pseudo register
39 (LAST_ARM_REGNUM 15) ;
40 (FPA_F0_REGNUM 16) ; FIRST_FPA_REGNUM
41 (FPA_F7_REGNUM 23) ; LAST_FPA_REGNUM
44 ;; 3rd operand to select_dominance_cc_mode
53 ;; Note: sin and cos are no-longer used.
56 [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT):
57 ; operand 0 is the result,
58 ; operand 1 the parameter.
59 (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT):
60 ; operand 0 is the result,
61 ; operand 1 the parameter.
62 (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
63 ; operand 0 is the first register,
64 ; subsequent registers are in parallel (use ...)
66 (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
67 ; usage, that is, we will add the pic_register
68 ; value to it before trying to dereference it.
69 (UNSPEC_PIC_BASE 4) ; Adding the PC value to the offset to the
70 ; GLOBAL_OFFSET_TABLE. The operation is fully
71 ; described by the RTL but must be wrapped to
72 ; prevent combine from trying to rip it apart.
73 (UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
74 ; being scheduled before the stack adjustment insn.
75 (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
76 ; this unspec is used to prevent the deletion of
77 ; instructions setting registers for EH handling
78 ; and stack frame generation. Operand 0 is the
80 (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
81 (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
82 (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
83 (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
84 (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
85 (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
86 (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
87 (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
88 (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
89 (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
90 (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
91 (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
92 (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
96 ;; UNSPEC_VOLATILE Usage:
99 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
101 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
102 ; instruction epilogue sequence that isn't expanded
103 ; into normal RTL. Used for both normal and sibcall
105 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
106 ; for inlined constants.
107 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
109 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
111 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
113 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
115 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
117 (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
118 (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
119 (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
120 (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
121 (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
122 (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
123 (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
128 ;;---------------------------------------------------------------------------
131 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
132 ; generating ARM code. This is used to control the length of some insn
133 ; patterns that share the same RTL in both ARM and Thumb code.
134 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
136 ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
137 ; scheduling decisions for the load unit and the multiplier.
138 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
140 ; IS_XSCALE is set to 'yes' when compiling for XScale.
141 (define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
143 ;; Operand number of an input operand that is shifted. Zero if the
144 ;; given instruction does not shift one of its input operands.
145 (define_attr "shift" "" (const_int 0))
147 ; Floating Point Unit. If we only have floating point emulation, then there
148 ; is no point in scheduling the floating point insns. (Well, for best
149 ; performance we should try and group them together).
150 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
151 (const (symbol_ref "arm_fpu_attr")))
153 ; LENGTH of an instruction (in bytes)
154 (define_attr "length" "" (const_int 4))
156 ; POOL_RANGE is how far away from a constant pool entry that this insn
157 ; can be placed. If the distance is zero, then this insn will never
158 ; reference the pool.
159 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
160 ; before its address.
161 (define_attr "pool_range" "" (const_int 0))
162 (define_attr "neg_pool_range" "" (const_int 0))
164 ; An assembler sequence may clobber the condition codes without us knowing.
165 ; If such an insn references the pool, then we have no way of knowing how,
166 ; so use the most conservative value for pool_range.
167 (define_asm_attributes
168 [(set_attr "conds" "clob")
169 (set_attr "length" "4")
170 (set_attr "pool_range" "250")])
172 ;; The instruction used to implement a particular pattern. This
173 ;; information is used by pipeline descriptions to provide accurate
174 ;; scheduling information.
177 "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,other"
178 (const_string "other"))
180 ; TYPE attribute is used to detect floating point instructions which, if
181 ; running on a co-processor can run in parallel with other, basic instructions
182 ; If write-buffer scheduling is enabled then it can also be used in the
183 ; scheduling of writes.
185 ; Classification of each insn
186 ; alu any alu instruction that doesn't hit memory or fp
187 ; regs or have a shifted source operand
188 ; alu_shift any data instruction that doesn't hit memory or fp
189 ; regs, but has a source operand shifted by a constant
190 ; alu_shift_reg any data instruction that doesn't hit memory or fp
191 ; regs, but has a source operand shifted by a register value
192 ; mult a multiply instruction
193 ; block blockage insn, this blocks all functional units
194 ; float a floating point arithmetic operation (subject to expansion)
195 ; fdivd DFmode floating point division
196 ; fdivs SFmode floating point division
197 ; fmul Floating point multiply
198 ; ffmul Fast floating point multiply
199 ; farith Floating point arithmetic (4 cycle)
200 ; ffarith Fast floating point arithmetic (2 cycle)
201 ; float_em a floating point arithmetic operation that is normally emulated
202 ; even on a machine with an fpa.
203 ; f_load a floating point load from memory
204 ; f_store a floating point store to memory
205 ; f_mem_r a transfer of a floating point register to a real reg via mem
206 ; r_mem_f the reverse of f_mem_r
207 ; f_2_r fast transfer float to arm (no memory needed)
208 ; r_2_f fast transfer arm to float
210 ; call a subroutine call
211 ; load_byte load byte(s) from memory to arm registers
212 ; load1 load 1 word from memory to arm registers
213 ; load2 load 2 words from memory to arm registers
214 ; load3 load 3 words from memory to arm registers
215 ; load4 load 4 words from memory to arm registers
216 ; store store 1 word to memory from arm registers
217 ; store2 store 2 words
218 ; store3 store 3 words
219 ; store4 store 4 (or more) words
220 ; Additions for Cirrus Maverick co-processor:
221 ; mav_farith Floating point arithmetic (4 cycle)
222 ; mav_dmult Double multiplies (7 cycle)
225 "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
227 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
228 (const_string "mult")
229 (const_string "alu")))
231 ; Load scheduling, set from the arm_ld_sched variable
232 ; initialized by arm_override_options()
233 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
235 ; condition codes: this one is used by final_prescan_insn to speed up
236 ; conditionalizing instructions. It saves having to scan the rtl to see if
237 ; it uses or alters the condition codes.
239 ; USE means that the condition codes are used by the insn in the process of
240 ; outputting code, this means (at present) that we can't use the insn in
243 ; SET means that the purpose of the insn is to set the condition codes in a
244 ; well defined manner.
246 ; CLOB means that the condition codes are altered in an undefined manner, if
247 ; they are altered at all
249 ; JUMP_CLOB is used when the condition cannot be represented by a single
250 ; instruction (UNEQ and LTGT). These cannot be predicated.
252 ; NOCOND means that the condition codes are neither altered nor affect the
253 ; output of this insn
255 (define_attr "conds" "use,set,clob,jump_clob,nocond"
256 (if_then_else (eq_attr "type" "call")
257 (const_string "clob")
258 (const_string "nocond")))
260 ; Predicable means that the insn can be conditionally executed based on
261 ; an automatically added predicate (additional patterns are generated by
262 ; gen...). We default to 'no' because no Thumb patterns match this rule
263 ; and not all ARM patterns do.
264 (define_attr "predicable" "no,yes" (const_string "no"))
266 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
267 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
268 ; suffer blockages enough to warrant modelling this (and it can adversely
269 ; affect the schedule).
270 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
272 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
273 ; to stall the processor. Used with model_wbuf above.
274 (define_attr "write_conflict" "no,yes"
275 (if_then_else (eq_attr "type"
276 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
278 (const_string "no")))
280 ; Classify the insns into those that take one cycle and those that take more
281 ; than one on the main cpu execution unit.
282 (define_attr "core_cycles" "single,multi"
283 (if_then_else (eq_attr "type"
284 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
285 (const_string "single")
286 (const_string "multi")))
288 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
289 ;; distant label. Only applicable to Thumb code.
290 (define_attr "far_jump" "yes,no" (const_string "no"))
293 ;;---------------------------------------------------------------------------
296 ; A list of modes that are exactly 64 bits in size. We use this to expand
297 ; some splits that are the same for all modes when operating on ARM
299 (define_mode_macro ANY64 [DI DF V8QI V4HI V2SI V2SF])
301 ;;---------------------------------------------------------------------------
304 (include "predicates.md")
306 ;;---------------------------------------------------------------------------
307 ;; Pipeline descriptions
309 ;; Processor type. This is created automatically from arm-cores.def.
310 (include "arm-tune.md")
312 ;; True if the generic scheduling description should be used.
314 (define_attr "generic_sched" "yes,no"
316 (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
318 (const_string "yes"))))
320 (include "arm-generic.md")
321 (include "arm926ejs.md")
322 (include "arm1026ejs.md")
323 (include "arm1136jfs.md")
326 ;;---------------------------------------------------------------------------
331 ;; Note: For DImode insns, there is normally no reason why operands should
332 ;; not be in the same register, what we don't want is for something being
333 ;; written to partially overlap something that is an input.
334 ;; Cirrus 64bit additions should not be split because we have a native
335 ;; 64bit addition instructions.
337 (define_expand "adddi3"
339 [(set (match_operand:DI 0 "s_register_operand" "")
340 (plus:DI (match_operand:DI 1 "s_register_operand" "")
341 (match_operand:DI 2 "s_register_operand" "")))
342 (clobber (reg:CC CC_REGNUM))])]
345 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
347 if (!cirrus_fp_register (operands[0], DImode))
348 operands[0] = force_reg (DImode, operands[0]);
349 if (!cirrus_fp_register (operands[1], DImode))
350 operands[1] = force_reg (DImode, operands[1]);
351 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
357 if (GET_CODE (operands[1]) != REG)
358 operands[1] = force_reg (SImode, operands[1]);
359 if (GET_CODE (operands[2]) != REG)
360 operands[2] = force_reg (SImode, operands[2]);
365 (define_insn "*thumb_adddi3"
366 [(set (match_operand:DI 0 "register_operand" "=l")
367 (plus:DI (match_operand:DI 1 "register_operand" "%0")
368 (match_operand:DI 2 "register_operand" "l")))
369 (clobber (reg:CC CC_REGNUM))
372 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
373 [(set_attr "length" "4")]
376 (define_insn_and_split "*arm_adddi3"
377 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
378 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
379 (match_operand:DI 2 "s_register_operand" "r, 0")))
380 (clobber (reg:CC CC_REGNUM))]
381 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
383 "TARGET_ARM && reload_completed"
384 [(parallel [(set (reg:CC_C CC_REGNUM)
385 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
387 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
388 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
389 (plus:SI (match_dup 4) (match_dup 5))))]
392 operands[3] = gen_highpart (SImode, operands[0]);
393 operands[0] = gen_lowpart (SImode, operands[0]);
394 operands[4] = gen_highpart (SImode, operands[1]);
395 operands[1] = gen_lowpart (SImode, operands[1]);
396 operands[5] = gen_highpart (SImode, operands[2]);
397 operands[2] = gen_lowpart (SImode, operands[2]);
399 [(set_attr "conds" "clob")
400 (set_attr "length" "8")]
403 (define_insn_and_split "*adddi_sesidi_di"
404 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
405 (plus:DI (sign_extend:DI
406 (match_operand:SI 2 "s_register_operand" "r,r"))
407 (match_operand:DI 1 "s_register_operand" "r,0")))
408 (clobber (reg:CC CC_REGNUM))]
409 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
411 "TARGET_ARM && reload_completed"
412 [(parallel [(set (reg:CC_C CC_REGNUM)
413 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
415 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
416 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
417 (plus:SI (ashiftrt:SI (match_dup 2)
422 operands[3] = gen_highpart (SImode, operands[0]);
423 operands[0] = gen_lowpart (SImode, operands[0]);
424 operands[4] = gen_highpart (SImode, operands[1]);
425 operands[1] = gen_lowpart (SImode, operands[1]);
426 operands[2] = gen_lowpart (SImode, operands[2]);
428 [(set_attr "conds" "clob")
429 (set_attr "length" "8")]
432 (define_insn_and_split "*adddi_zesidi_di"
433 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
434 (plus:DI (zero_extend:DI
435 (match_operand:SI 2 "s_register_operand" "r,r"))
436 (match_operand:DI 1 "s_register_operand" "r,0")))
437 (clobber (reg:CC CC_REGNUM))]
438 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
440 "TARGET_ARM && reload_completed"
441 [(parallel [(set (reg:CC_C CC_REGNUM)
442 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
444 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
445 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
446 (plus:SI (match_dup 4) (const_int 0))))]
449 operands[3] = gen_highpart (SImode, operands[0]);
450 operands[0] = gen_lowpart (SImode, operands[0]);
451 operands[4] = gen_highpart (SImode, operands[1]);
452 operands[1] = gen_lowpart (SImode, operands[1]);
453 operands[2] = gen_lowpart (SImode, operands[2]);
455 [(set_attr "conds" "clob")
456 (set_attr "length" "8")]
459 (define_expand "addsi3"
460 [(set (match_operand:SI 0 "s_register_operand" "")
461 (plus:SI (match_operand:SI 1 "s_register_operand" "")
462 (match_operand:SI 2 "reg_or_int_operand" "")))]
465 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
467 arm_split_constant (PLUS, SImode, NULL_RTX,
468 INTVAL (operands[2]), operands[0], operands[1],
469 optimize && !no_new_pseudos);
475 ; If there is a scratch available, this will be faster than synthesizing the
478 [(match_scratch:SI 3 "r")
479 (set (match_operand:SI 0 "arm_general_register_operand" "")
480 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
481 (match_operand:SI 2 "const_int_operand" "")))]
483 !(const_ok_for_arm (INTVAL (operands[2]))
484 || const_ok_for_arm (-INTVAL (operands[2])))
485 && const_ok_for_arm (~INTVAL (operands[2]))"
486 [(set (match_dup 3) (match_dup 2))
487 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
491 (define_insn_and_split "*arm_addsi3"
492 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
493 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
494 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
501 GET_CODE (operands[2]) == CONST_INT
502 && !(const_ok_for_arm (INTVAL (operands[2]))
503 || const_ok_for_arm (-INTVAL (operands[2])))"
504 [(clobber (const_int 0))]
506 arm_split_constant (PLUS, SImode, curr_insn,
507 INTVAL (operands[2]), operands[0],
511 [(set_attr "length" "4,4,16")
512 (set_attr "predicable" "yes")]
515 ;; Register group 'k' is a single register group containing only the stack
516 ;; register. Trying to reload it will always fail catastrophically,
517 ;; so never allow those alternatives to match if reloading is needed.
519 (define_insn "*thumb_addsi3"
520 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
521 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
522 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
525 static const char * const asms[] =
527 \"add\\t%0, %0, %2\",
528 \"sub\\t%0, %0, #%n2\",
529 \"add\\t%0, %1, %2\",
530 \"add\\t%0, %0, %2\",
531 \"add\\t%0, %0, %2\",
532 \"add\\t%0, %1, %2\",
535 if ((which_alternative == 2 || which_alternative == 6)
536 && GET_CODE (operands[2]) == CONST_INT
537 && INTVAL (operands[2]) < 0)
538 return \"sub\\t%0, %1, #%n2\";
539 return asms[which_alternative];
541 [(set_attr "length" "2")]
544 ;; Reloading and elimination of the frame pointer can
545 ;; sometimes cause this optimization to be missed.
547 [(set (match_operand:SI 0 "arm_general_register_operand" "")
548 (match_operand:SI 1 "const_int_operand" ""))
550 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
552 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
553 && (INTVAL (operands[1]) & 3) == 0"
554 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
558 (define_insn "*addsi3_compare0"
559 [(set (reg:CC_NOOV CC_REGNUM)
561 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
562 (match_operand:SI 2 "arm_add_operand" "rI,L"))
564 (set (match_operand:SI 0 "s_register_operand" "=r,r")
565 (plus:SI (match_dup 1) (match_dup 2)))]
569 sub%?s\\t%0, %1, #%n2"
570 [(set_attr "conds" "set")]
573 (define_insn "*addsi3_compare0_scratch"
574 [(set (reg:CC_NOOV CC_REGNUM)
576 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
577 (match_operand:SI 1 "arm_add_operand" "rI,L"))
583 [(set_attr "conds" "set")]
586 (define_insn "*compare_negsi_si"
587 [(set (reg:CC_Z CC_REGNUM)
589 (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
590 (match_operand:SI 1 "s_register_operand" "r")))]
593 [(set_attr "conds" "set")]
596 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
597 ;; addend is a constant.
598 (define_insn "*cmpsi2_addneg"
599 [(set (reg:CC CC_REGNUM)
601 (match_operand:SI 1 "s_register_operand" "r,r")
602 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
603 (set (match_operand:SI 0 "s_register_operand" "=r,r")
604 (plus:SI (match_dup 1)
605 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
606 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
609 add%?s\\t%0, %1, #%n2"
610 [(set_attr "conds" "set")]
613 ;; Convert the sequence
615 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
619 ;; bcs dest ((unsigned)rn >= 1)
620 ;; similarly for the beq variant using bcc.
621 ;; This is a common looping idiom (while (n--))
623 [(set (match_operand:SI 0 "arm_general_register_operand" "")
624 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
626 (set (match_operand 2 "cc_register" "")
627 (compare (match_dup 0) (const_int -1)))
629 (if_then_else (match_operator 3 "equality_operator"
630 [(match_dup 2) (const_int 0)])
631 (match_operand 4 "" "")
632 (match_operand 5 "" "")))]
633 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
637 (match_dup 1) (const_int 1)))
638 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
640 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
643 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
644 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
647 operands[2], const0_rtx);"
650 ;; The next four insns work because they compare the result with one of
651 ;; the operands, and we know that the use of the condition code is
652 ;; either GEU or LTU, so we can use the carry flag from the addition
653 ;; instead of doing the compare a second time.
654 (define_insn "*addsi3_compare_op1"
655 [(set (reg:CC_C CC_REGNUM)
657 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
658 (match_operand:SI 2 "arm_add_operand" "rI,L"))
660 (set (match_operand:SI 0 "s_register_operand" "=r,r")
661 (plus:SI (match_dup 1) (match_dup 2)))]
665 sub%?s\\t%0, %1, #%n2"
666 [(set_attr "conds" "set")]
669 (define_insn "*addsi3_compare_op2"
670 [(set (reg:CC_C CC_REGNUM)
672 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
673 (match_operand:SI 2 "arm_add_operand" "rI,L"))
675 (set (match_operand:SI 0 "s_register_operand" "=r,r")
676 (plus:SI (match_dup 1) (match_dup 2)))]
680 sub%?s\\t%0, %1, #%n2"
681 [(set_attr "conds" "set")]
684 (define_insn "*compare_addsi2_op0"
685 [(set (reg:CC_C CC_REGNUM)
687 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
688 (match_operand:SI 1 "arm_add_operand" "rI,L"))
694 [(set_attr "conds" "set")]
697 (define_insn "*compare_addsi2_op1"
698 [(set (reg:CC_C CC_REGNUM)
700 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
701 (match_operand:SI 1 "arm_add_operand" "rI,L"))
707 [(set_attr "conds" "set")]
710 (define_insn "*addsi3_carryin"
711 [(set (match_operand:SI 0 "s_register_operand" "=r")
712 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
713 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
714 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
717 [(set_attr "conds" "use")]
720 (define_insn "*addsi3_carryin_shift"
721 [(set (match_operand:SI 0 "s_register_operand" "=r")
722 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
724 (match_operator:SI 2 "shift_operator"
725 [(match_operand:SI 3 "s_register_operand" "r")
726 (match_operand:SI 4 "reg_or_int_operand" "rM")])
727 (match_operand:SI 1 "s_register_operand" "r"))))]
729 "adc%?\\t%0, %1, %3%S2"
730 [(set_attr "conds" "use")
731 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
732 (const_string "alu_shift")
733 (const_string "alu_shift_reg")))]
736 (define_insn "*addsi3_carryin_alt1"
737 [(set (match_operand:SI 0 "s_register_operand" "=r")
738 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
739 (match_operand:SI 2 "arm_rhs_operand" "rI"))
740 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
743 [(set_attr "conds" "use")]
746 (define_insn "*addsi3_carryin_alt2"
747 [(set (match_operand:SI 0 "s_register_operand" "=r")
748 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
749 (match_operand:SI 1 "s_register_operand" "r"))
750 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
753 [(set_attr "conds" "use")]
756 (define_insn "*addsi3_carryin_alt3"
757 [(set (match_operand:SI 0 "s_register_operand" "=r")
758 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
759 (match_operand:SI 2 "arm_rhs_operand" "rI"))
760 (match_operand:SI 1 "s_register_operand" "r")))]
763 [(set_attr "conds" "use")]
766 (define_insn "incscc"
767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
768 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
769 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
770 (match_operand:SI 1 "s_register_operand" "0,?r")))]
774 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
775 [(set_attr "conds" "use")
776 (set_attr "length" "4,8")]
779 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
781 [(set (match_operand:SI 0 "s_register_operand" "")
782 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
783 (match_operand:SI 2 "s_register_operand" ""))
785 (clobber (match_operand:SI 3 "s_register_operand" ""))]
787 [(set (match_dup 3) (match_dup 1))
788 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
790 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
793 (define_expand "addsf3"
794 [(set (match_operand:SF 0 "s_register_operand" "")
795 (plus:SF (match_operand:SF 1 "s_register_operand" "")
796 (match_operand:SF 2 "arm_float_add_operand" "")))]
797 "TARGET_ARM && TARGET_HARD_FLOAT"
800 && !cirrus_fp_register (operands[2], SFmode))
801 operands[2] = force_reg (SFmode, operands[2]);
804 (define_expand "adddf3"
805 [(set (match_operand:DF 0 "s_register_operand" "")
806 (plus:DF (match_operand:DF 1 "s_register_operand" "")
807 (match_operand:DF 2 "arm_float_add_operand" "")))]
808 "TARGET_ARM && TARGET_HARD_FLOAT"
811 && !cirrus_fp_register (operands[2], DFmode))
812 operands[2] = force_reg (DFmode, operands[2]);
815 (define_expand "subdi3"
817 [(set (match_operand:DI 0 "s_register_operand" "")
818 (minus:DI (match_operand:DI 1 "s_register_operand" "")
819 (match_operand:DI 2 "s_register_operand" "")))
820 (clobber (reg:CC CC_REGNUM))])]
823 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
825 && cirrus_fp_register (operands[0], DImode)
826 && cirrus_fp_register (operands[1], DImode))
828 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
834 if (GET_CODE (operands[1]) != REG)
835 operands[1] = force_reg (SImode, operands[1]);
836 if (GET_CODE (operands[2]) != REG)
837 operands[2] = force_reg (SImode, operands[2]);
842 (define_insn "*arm_subdi3"
843 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
844 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
845 (match_operand:DI 2 "s_register_operand" "r,0,0")))
846 (clobber (reg:CC CC_REGNUM))]
848 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
849 [(set_attr "conds" "clob")
850 (set_attr "length" "8")]
853 (define_insn "*thumb_subdi3"
854 [(set (match_operand:DI 0 "register_operand" "=l")
855 (minus:DI (match_operand:DI 1 "register_operand" "0")
856 (match_operand:DI 2 "register_operand" "l")))
857 (clobber (reg:CC CC_REGNUM))]
859 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
860 [(set_attr "length" "4")]
863 (define_insn "*subdi_di_zesidi"
864 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
865 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
867 (match_operand:SI 2 "s_register_operand" "r,r"))))
868 (clobber (reg:CC CC_REGNUM))]
870 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
871 [(set_attr "conds" "clob")
872 (set_attr "length" "8")]
875 (define_insn "*subdi_di_sesidi"
876 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
877 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
879 (match_operand:SI 2 "s_register_operand" "r,r"))))
880 (clobber (reg:CC CC_REGNUM))]
882 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
883 [(set_attr "conds" "clob")
884 (set_attr "length" "8")]
887 (define_insn "*subdi_zesidi_di"
888 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
889 (minus:DI (zero_extend:DI
890 (match_operand:SI 2 "s_register_operand" "r,r"))
891 (match_operand:DI 1 "s_register_operand" "?r,0")))
892 (clobber (reg:CC CC_REGNUM))]
894 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
895 [(set_attr "conds" "clob")
896 (set_attr "length" "8")]
899 (define_insn "*subdi_sesidi_di"
900 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
901 (minus:DI (sign_extend:DI
902 (match_operand:SI 2 "s_register_operand" "r,r"))
903 (match_operand:DI 1 "s_register_operand" "?r,0")))
904 (clobber (reg:CC CC_REGNUM))]
906 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
907 [(set_attr "conds" "clob")
908 (set_attr "length" "8")]
911 (define_insn "*subdi_zesidi_zesidi"
912 [(set (match_operand:DI 0 "s_register_operand" "=r")
913 (minus:DI (zero_extend:DI
914 (match_operand:SI 1 "s_register_operand" "r"))
916 (match_operand:SI 2 "s_register_operand" "r"))))
917 (clobber (reg:CC CC_REGNUM))]
919 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
920 [(set_attr "conds" "clob")
921 (set_attr "length" "8")]
924 (define_expand "subsi3"
925 [(set (match_operand:SI 0 "s_register_operand" "")
926 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
927 (match_operand:SI 2 "s_register_operand" "")))]
930 if (GET_CODE (operands[1]) == CONST_INT)
934 arm_split_constant (MINUS, SImode, NULL_RTX,
935 INTVAL (operands[1]), operands[0],
936 operands[2], optimize && !no_new_pseudos);
939 else /* TARGET_THUMB */
940 operands[1] = force_reg (SImode, operands[1]);
945 (define_insn "*thumb_subsi3_insn"
946 [(set (match_operand:SI 0 "register_operand" "=l")
947 (minus:SI (match_operand:SI 1 "register_operand" "l")
948 (match_operand:SI 2 "register_operand" "l")))]
951 [(set_attr "length" "2")]
954 (define_insn_and_split "*arm_subsi3_insn"
955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
956 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
957 (match_operand:SI 2 "s_register_operand" "r,r")))]
963 && GET_CODE (operands[1]) == CONST_INT
964 && !const_ok_for_arm (INTVAL (operands[1]))"
965 [(clobber (const_int 0))]
967 arm_split_constant (MINUS, SImode, curr_insn,
968 INTVAL (operands[1]), operands[0], operands[2], 0);
971 [(set_attr "length" "4,16")
972 (set_attr "predicable" "yes")]
976 [(match_scratch:SI 3 "r")
977 (set (match_operand:SI 0 "arm_general_register_operand" "")
978 (minus:SI (match_operand:SI 1 "const_int_operand" "")
979 (match_operand:SI 2 "arm_general_register_operand" "")))]
981 && !const_ok_for_arm (INTVAL (operands[1]))
982 && const_ok_for_arm (~INTVAL (operands[1]))"
983 [(set (match_dup 3) (match_dup 1))
984 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
988 (define_insn "*subsi3_compare0"
989 [(set (reg:CC_NOOV CC_REGNUM)
991 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
992 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
994 (set (match_operand:SI 0 "s_register_operand" "=r,r")
995 (minus:SI (match_dup 1) (match_dup 2)))]
1000 [(set_attr "conds" "set")]
1003 (define_insn "decscc"
1004 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1005 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1006 (match_operator:SI 2 "arm_comparison_operator"
1007 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1011 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1012 [(set_attr "conds" "use")
1013 (set_attr "length" "*,8")]
1016 (define_expand "subsf3"
1017 [(set (match_operand:SF 0 "s_register_operand" "")
1018 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1019 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1020 "TARGET_ARM && TARGET_HARD_FLOAT"
1022 if (TARGET_MAVERICK)
1024 if (!cirrus_fp_register (operands[1], SFmode))
1025 operands[1] = force_reg (SFmode, operands[1]);
1026 if (!cirrus_fp_register (operands[2], SFmode))
1027 operands[2] = force_reg (SFmode, operands[2]);
1031 (define_expand "subdf3"
1032 [(set (match_operand:DF 0 "s_register_operand" "")
1033 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1034 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1035 "TARGET_ARM && TARGET_HARD_FLOAT"
1037 if (TARGET_MAVERICK)
1039 if (!cirrus_fp_register (operands[1], DFmode))
1040 operands[1] = force_reg (DFmode, operands[1]);
1041 if (!cirrus_fp_register (operands[2], DFmode))
1042 operands[2] = force_reg (DFmode, operands[2]);
1047 ;; Multiplication insns
1049 (define_expand "mulsi3"
1050 [(set (match_operand:SI 0 "s_register_operand" "")
1051 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1052 (match_operand:SI 1 "s_register_operand" "")))]
1057 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1058 (define_insn "*arm_mulsi3"
1059 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1060 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1061 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1063 "mul%?\\t%0, %2, %1"
1064 [(set_attr "insn" "mul")
1065 (set_attr "predicable" "yes")]
1068 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1069 ; 1 and 2; are the same, because reload will make operand 0 match
1070 ; operand 1 without realizing that this conflicts with operand 2. We fix
1071 ; this by adding another alternative to match this case, and then `reload'
1072 ; it ourselves. This alternative must come first.
1073 (define_insn "*thumb_mulsi3"
1074 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1075 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1076 (match_operand:SI 2 "register_operand" "l,l,l")))]
1079 if (which_alternative < 2)
1080 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1082 return \"mul\\t%0, %0, %2\";
1084 [(set_attr "length" "4,4,2")
1085 (set_attr "insn" "mul")]
1088 (define_insn "*mulsi3_compare0"
1089 [(set (reg:CC_NOOV CC_REGNUM)
1090 (compare:CC_NOOV (mult:SI
1091 (match_operand:SI 2 "s_register_operand" "r,r")
1092 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1094 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1095 (mult:SI (match_dup 2) (match_dup 1)))]
1097 "mul%?s\\t%0, %2, %1"
1098 [(set_attr "conds" "set")
1099 (set_attr "insn" "muls")]
1102 (define_insn "*mulsi_compare0_scratch"
1103 [(set (reg:CC_NOOV CC_REGNUM)
1104 (compare:CC_NOOV (mult:SI
1105 (match_operand:SI 2 "s_register_operand" "r,r")
1106 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1108 (clobber (match_scratch:SI 0 "=&r,&r"))]
1110 "mul%?s\\t%0, %2, %1"
1111 [(set_attr "conds" "set")
1112 (set_attr "insn" "muls")]
1115 ;; Unnamed templates to match MLA instruction.
1117 (define_insn "*mulsi3addsi"
1118 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1120 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1121 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1122 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1124 "mla%?\\t%0, %2, %1, %3"
1125 [(set_attr "insn" "mla")
1126 (set_attr "predicable" "yes")]
1129 (define_insn "*mulsi3addsi_compare0"
1130 [(set (reg:CC_NOOV CC_REGNUM)
1133 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1134 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1135 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1137 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1138 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1141 "mla%?s\\t%0, %2, %1, %3"
1142 [(set_attr "conds" "set")
1143 (set_attr "insn" "mlas")]
1146 (define_insn "*mulsi3addsi_compare0_scratch"
1147 [(set (reg:CC_NOOV CC_REGNUM)
1150 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1151 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1152 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1154 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1156 "mla%?s\\t%0, %2, %1, %3"
1157 [(set_attr "conds" "set")
1158 (set_attr "insn" "mlas")]
1161 ;; Unnamed template to match long long multiply-accumulate (smlal)
1163 (define_insn "*mulsidi3adddi"
1164 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1167 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1168 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1169 (match_operand:DI 1 "s_register_operand" "0")))]
1170 "TARGET_ARM && arm_arch3m"
1171 "smlal%?\\t%Q0, %R0, %3, %2"
1172 [(set_attr "insn" "smlal")
1173 (set_attr "predicable" "yes")]
1176 (define_insn "mulsidi3"
1177 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1179 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1180 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1181 "TARGET_ARM && arm_arch3m"
1182 "smull%?\\t%Q0, %R0, %1, %2"
1183 [(set_attr "insn" "smull")
1184 (set_attr "predicable" "yes")]
1187 (define_insn "umulsidi3"
1188 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1190 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1191 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1192 "TARGET_ARM && arm_arch3m"
1193 "umull%?\\t%Q0, %R0, %1, %2"
1194 [(set_attr "insn" "umull")
1195 (set_attr "predicable" "yes")]
1198 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1200 (define_insn "*umulsidi3adddi"
1201 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1204 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1205 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1206 (match_operand:DI 1 "s_register_operand" "0")))]
1207 "TARGET_ARM && arm_arch3m"
1208 "umlal%?\\t%Q0, %R0, %3, %2"
1209 [(set_attr "insn" "umlal")
1210 (set_attr "predicable" "yes")]
1213 (define_insn "smulsi3_highpart"
1214 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1218 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1219 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1221 (clobber (match_scratch:SI 3 "=&r,&r"))]
1222 "TARGET_ARM && arm_arch3m"
1223 "smull%?\\t%3, %0, %2, %1"
1224 [(set_attr "insn" "smull")
1225 (set_attr "predicable" "yes")]
1228 (define_insn "umulsi3_highpart"
1229 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1233 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1234 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1236 (clobber (match_scratch:SI 3 "=&r,&r"))]
1237 "TARGET_ARM && arm_arch3m"
1238 "umull%?\\t%3, %0, %2, %1"
1239 [(set_attr "insn" "umull")
1240 (set_attr "predicable" "yes")]
1243 (define_insn "mulhisi3"
1244 [(set (match_operand:SI 0 "s_register_operand" "=r")
1245 (mult:SI (sign_extend:SI
1246 (match_operand:HI 1 "s_register_operand" "%r"))
1248 (match_operand:HI 2 "s_register_operand" "r"))))]
1249 "TARGET_ARM && arm_arch5e"
1250 "smulbb%?\\t%0, %1, %2"
1251 [(set_attr "insn" "smulxy")
1252 (set_attr "predicable" "yes")]
1255 (define_insn "*mulhisi3tb"
1256 [(set (match_operand:SI 0 "s_register_operand" "=r")
1257 (mult:SI (ashiftrt:SI
1258 (match_operand:SI 1 "s_register_operand" "r")
1261 (match_operand:HI 2 "s_register_operand" "r"))))]
1262 "TARGET_ARM && arm_arch5e"
1263 "smultb%?\\t%0, %1, %2"
1264 [(set_attr "insn" "smulxy")
1265 (set_attr "predicable" "yes")]
1268 (define_insn "*mulhisi3bt"
1269 [(set (match_operand:SI 0 "s_register_operand" "=r")
1270 (mult:SI (sign_extend:SI
1271 (match_operand:HI 1 "s_register_operand" "r"))
1273 (match_operand:SI 2 "s_register_operand" "r")
1275 "TARGET_ARM && arm_arch5e"
1276 "smulbt%?\\t%0, %1, %2"
1277 [(set_attr "insn" "smulxy")
1278 (set_attr "predicable" "yes")]
1281 (define_insn "*mulhisi3tt"
1282 [(set (match_operand:SI 0 "s_register_operand" "=r")
1283 (mult:SI (ashiftrt:SI
1284 (match_operand:SI 1 "s_register_operand" "r")
1287 (match_operand:SI 2 "s_register_operand" "r")
1289 "TARGET_ARM && arm_arch5e"
1290 "smultt%?\\t%0, %1, %2"
1291 [(set_attr "insn" "smulxy")
1292 (set_attr "predicable" "yes")]
1295 (define_insn "*mulhisi3addsi"
1296 [(set (match_operand:SI 0 "s_register_operand" "=r")
1297 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1298 (mult:SI (sign_extend:SI
1299 (match_operand:HI 2 "s_register_operand" "%r"))
1301 (match_operand:HI 3 "s_register_operand" "r")))))]
1302 "TARGET_ARM && arm_arch5e"
1303 "smlabb%?\\t%0, %2, %3, %1"
1304 [(set_attr "insn" "smlaxy")
1305 (set_attr "predicable" "yes")]
1308 (define_insn "*mulhidi3adddi"
1309 [(set (match_operand:DI 0 "s_register_operand" "=r")
1311 (match_operand:DI 1 "s_register_operand" "0")
1312 (mult:DI (sign_extend:DI
1313 (match_operand:HI 2 "s_register_operand" "%r"))
1315 (match_operand:HI 3 "s_register_operand" "r")))))]
1316 "TARGET_ARM && arm_arch5e"
1317 "smlalbb%?\\t%Q0, %R0, %2, %3"
1318 [(set_attr "insn" "smlalxy")
1319 (set_attr "predicable" "yes")])
1321 (define_expand "mulsf3"
1322 [(set (match_operand:SF 0 "s_register_operand" "")
1323 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1324 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1325 "TARGET_ARM && TARGET_HARD_FLOAT"
1328 && !cirrus_fp_register (operands[2], SFmode))
1329 operands[2] = force_reg (SFmode, operands[2]);
1332 (define_expand "muldf3"
1333 [(set (match_operand:DF 0 "s_register_operand" "")
1334 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1335 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1336 "TARGET_ARM && TARGET_HARD_FLOAT"
1339 && !cirrus_fp_register (operands[2], DFmode))
1340 operands[2] = force_reg (DFmode, operands[2]);
1345 (define_expand "divsf3"
1346 [(set (match_operand:SF 0 "s_register_operand" "")
1347 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1348 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1349 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1352 (define_expand "divdf3"
1353 [(set (match_operand:DF 0 "s_register_operand" "")
1354 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1355 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1356 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1361 (define_expand "modsf3"
1362 [(set (match_operand:SF 0 "s_register_operand" "")
1363 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1364 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1365 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1368 (define_expand "moddf3"
1369 [(set (match_operand:DF 0 "s_register_operand" "")
1370 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1371 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1372 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1375 ;; Boolean and,ior,xor insns
1377 ;; Split up double word logical operations
1379 ;; Split up simple DImode logical operations. Simply perform the logical
1380 ;; operation on the upper and lower halves of the registers.
1382 [(set (match_operand:DI 0 "s_register_operand" "")
1383 (match_operator:DI 6 "logical_binary_operator"
1384 [(match_operand:DI 1 "s_register_operand" "")
1385 (match_operand:DI 2 "s_register_operand" "")]))]
1386 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1387 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1388 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1391 operands[3] = gen_highpart (SImode, operands[0]);
1392 operands[0] = gen_lowpart (SImode, operands[0]);
1393 operands[4] = gen_highpart (SImode, operands[1]);
1394 operands[1] = gen_lowpart (SImode, operands[1]);
1395 operands[5] = gen_highpart (SImode, operands[2]);
1396 operands[2] = gen_lowpart (SImode, operands[2]);
1401 [(set (match_operand:DI 0 "s_register_operand" "")
1402 (match_operator:DI 6 "logical_binary_operator"
1403 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1404 (match_operand:DI 1 "s_register_operand" "")]))]
1405 "TARGET_ARM && reload_completed"
1406 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1407 (set (match_dup 3) (match_op_dup:SI 6
1408 [(ashiftrt:SI (match_dup 2) (const_int 31))
1412 operands[3] = gen_highpart (SImode, operands[0]);
1413 operands[0] = gen_lowpart (SImode, operands[0]);
1414 operands[4] = gen_highpart (SImode, operands[1]);
1415 operands[1] = gen_lowpart (SImode, operands[1]);
1416 operands[5] = gen_highpart (SImode, operands[2]);
1417 operands[2] = gen_lowpart (SImode, operands[2]);
1421 ;; The zero extend of operand 2 means we can just copy the high part of
1422 ;; operand1 into operand0.
1424 [(set (match_operand:DI 0 "s_register_operand" "")
1426 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1427 (match_operand:DI 1 "s_register_operand" "")))]
1428 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1429 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1430 (set (match_dup 3) (match_dup 4))]
1433 operands[4] = gen_highpart (SImode, operands[1]);
1434 operands[3] = gen_highpart (SImode, operands[0]);
1435 operands[0] = gen_lowpart (SImode, operands[0]);
1436 operands[1] = gen_lowpart (SImode, operands[1]);
1440 ;; The zero extend of operand 2 means we can just copy the high part of
1441 ;; operand1 into operand0.
1443 [(set (match_operand:DI 0 "s_register_operand" "")
1445 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1446 (match_operand:DI 1 "s_register_operand" "")))]
1447 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1448 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1449 (set (match_dup 3) (match_dup 4))]
1452 operands[4] = gen_highpart (SImode, operands[1]);
1453 operands[3] = gen_highpart (SImode, operands[0]);
1454 operands[0] = gen_lowpart (SImode, operands[0]);
1455 operands[1] = gen_lowpart (SImode, operands[1]);
1459 (define_insn "anddi3"
1460 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1461 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1462 (match_operand:DI 2 "s_register_operand" "r,r")))]
1463 "TARGET_ARM && ! TARGET_IWMMXT"
1465 [(set_attr "length" "8")]
1468 (define_insn_and_split "*anddi_zesidi_di"
1469 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1470 (and:DI (zero_extend:DI
1471 (match_operand:SI 2 "s_register_operand" "r,r"))
1472 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1475 "TARGET_ARM && reload_completed"
1476 ; The zero extend of operand 2 clears the high word of the output
1478 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1479 (set (match_dup 3) (const_int 0))]
1482 operands[3] = gen_highpart (SImode, operands[0]);
1483 operands[0] = gen_lowpart (SImode, operands[0]);
1484 operands[1] = gen_lowpart (SImode, operands[1]);
1486 [(set_attr "length" "8")]
1489 (define_insn "*anddi_sesdi_di"
1490 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1491 (and:DI (sign_extend:DI
1492 (match_operand:SI 2 "s_register_operand" "r,r"))
1493 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1496 [(set_attr "length" "8")]
1499 (define_expand "andsi3"
1500 [(set (match_operand:SI 0 "s_register_operand" "")
1501 (and:SI (match_operand:SI 1 "s_register_operand" "")
1502 (match_operand:SI 2 "reg_or_int_operand" "")))]
1507 if (GET_CODE (operands[2]) == CONST_INT)
1509 arm_split_constant (AND, SImode, NULL_RTX,
1510 INTVAL (operands[2]), operands[0],
1511 operands[1], optimize && !no_new_pseudos);
1516 else /* TARGET_THUMB */
1518 if (GET_CODE (operands[2]) != CONST_INT)
1519 operands[2] = force_reg (SImode, operands[2]);
1524 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1526 operands[2] = force_reg (SImode,
1527 GEN_INT (~INTVAL (operands[2])));
1529 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1534 for (i = 9; i <= 31; i++)
1536 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1538 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1542 else if ((((HOST_WIDE_INT) 1) << i) - 1
1543 == ~INTVAL (operands[2]))
1545 rtx shift = GEN_INT (i);
1546 rtx reg = gen_reg_rtx (SImode);
1548 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1549 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1555 operands[2] = force_reg (SImode, operands[2]);
1561 (define_insn_and_split "*arm_andsi3_insn"
1562 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1563 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1564 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1568 bic%?\\t%0, %1, #%B2
1571 && GET_CODE (operands[2]) == CONST_INT
1572 && !(const_ok_for_arm (INTVAL (operands[2]))
1573 || const_ok_for_arm (~INTVAL (operands[2])))"
1574 [(clobber (const_int 0))]
1576 arm_split_constant (AND, SImode, curr_insn,
1577 INTVAL (operands[2]), operands[0], operands[1], 0);
1580 [(set_attr "length" "4,4,16")
1581 (set_attr "predicable" "yes")]
1584 (define_insn "*thumb_andsi3_insn"
1585 [(set (match_operand:SI 0 "register_operand" "=l")
1586 (and:SI (match_operand:SI 1 "register_operand" "%0")
1587 (match_operand:SI 2 "register_operand" "l")))]
1590 [(set_attr "length" "2")]
1593 (define_insn "*andsi3_compare0"
1594 [(set (reg:CC_NOOV CC_REGNUM)
1596 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1597 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1599 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1600 (and:SI (match_dup 1) (match_dup 2)))]
1604 bic%?s\\t%0, %1, #%B2"
1605 [(set_attr "conds" "set")]
1608 (define_insn "*andsi3_compare0_scratch"
1609 [(set (reg:CC_NOOV CC_REGNUM)
1611 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1612 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1614 (clobber (match_scratch:SI 2 "=X,r"))]
1618 bic%?s\\t%2, %0, #%B1"
1619 [(set_attr "conds" "set")]
1622 (define_insn "*zeroextractsi_compare0_scratch"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1624 (compare:CC_NOOV (zero_extract:SI
1625 (match_operand:SI 0 "s_register_operand" "r")
1626 (match_operand 1 "const_int_operand" "n")
1627 (match_operand 2 "const_int_operand" "n"))
1630 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1631 && INTVAL (operands[1]) > 0
1632 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1633 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1635 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1636 << INTVAL (operands[2]));
1637 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1640 [(set_attr "conds" "set")]
1643 (define_insn_and_split "*ne_zeroextractsi"
1644 [(set (match_operand:SI 0 "s_register_operand" "=r")
1645 (ne:SI (zero_extract:SI
1646 (match_operand:SI 1 "s_register_operand" "r")
1647 (match_operand:SI 2 "const_int_operand" "n")
1648 (match_operand:SI 3 "const_int_operand" "n"))
1650 (clobber (reg:CC CC_REGNUM))]
1652 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1653 && INTVAL (operands[2]) > 0
1654 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1655 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1658 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1659 && INTVAL (operands[2]) > 0
1660 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1661 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1662 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1663 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1665 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1667 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1668 (match_dup 0) (const_int 1)))]
1670 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1671 << INTVAL (operands[3]));
1673 [(set_attr "conds" "clob")
1674 (set_attr "length" "8")]
1677 (define_insn_and_split "*ne_zeroextractsi_shifted"
1678 [(set (match_operand:SI 0 "s_register_operand" "=r")
1679 (ne:SI (zero_extract:SI
1680 (match_operand:SI 1 "s_register_operand" "r")
1681 (match_operand:SI 2 "const_int_operand" "n")
1684 (clobber (reg:CC CC_REGNUM))]
1688 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1689 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1691 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1693 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1694 (match_dup 0) (const_int 1)))]
1696 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1698 [(set_attr "conds" "clob")
1699 (set_attr "length" "8")]
1702 (define_insn_and_split "*ite_ne_zeroextractsi"
1703 [(set (match_operand:SI 0 "s_register_operand" "=r")
1704 (if_then_else:SI (ne (zero_extract:SI
1705 (match_operand:SI 1 "s_register_operand" "r")
1706 (match_operand:SI 2 "const_int_operand" "n")
1707 (match_operand:SI 3 "const_int_operand" "n"))
1709 (match_operand:SI 4 "arm_not_operand" "rIK")
1711 (clobber (reg:CC CC_REGNUM))]
1713 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1714 && INTVAL (operands[2]) > 0
1715 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1716 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1717 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1720 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1721 && INTVAL (operands[2]) > 0
1722 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1723 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1724 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1725 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1726 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1728 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1730 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1731 (match_dup 0) (match_dup 4)))]
1733 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1734 << INTVAL (operands[3]));
1736 [(set_attr "conds" "clob")
1737 (set_attr "length" "8")]
1740 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
1741 [(set (match_operand:SI 0 "s_register_operand" "=r")
1742 (if_then_else:SI (ne (zero_extract:SI
1743 (match_operand:SI 1 "s_register_operand" "r")
1744 (match_operand:SI 2 "const_int_operand" "n")
1747 (match_operand:SI 3 "arm_not_operand" "rIK")
1749 (clobber (reg:CC CC_REGNUM))]
1750 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1752 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1753 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1754 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1756 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1758 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1759 (match_dup 0) (match_dup 3)))]
1761 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1763 [(set_attr "conds" "clob")
1764 (set_attr "length" "8")]
1768 [(set (match_operand:SI 0 "s_register_operand" "")
1769 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1770 (match_operand:SI 2 "const_int_operand" "")
1771 (match_operand:SI 3 "const_int_operand" "")))
1772 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1774 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1775 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1777 HOST_WIDE_INT temp = INTVAL (operands[2]);
1779 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1780 operands[3] = GEN_INT (32 - temp);
1785 [(set (match_operand:SI 0 "s_register_operand" "")
1786 (match_operator:SI 1 "shiftable_operator"
1787 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1788 (match_operand:SI 3 "const_int_operand" "")
1789 (match_operand:SI 4 "const_int_operand" ""))
1790 (match_operand:SI 5 "s_register_operand" "")]))
1791 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1793 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1796 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1799 HOST_WIDE_INT temp = INTVAL (operands[3]);
1801 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1802 operands[4] = GEN_INT (32 - temp);
1807 [(set (match_operand:SI 0 "s_register_operand" "")
1808 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1809 (match_operand:SI 2 "const_int_operand" "")
1810 (match_operand:SI 3 "const_int_operand" "")))]
1812 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1813 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1815 HOST_WIDE_INT temp = INTVAL (operands[2]);
1817 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1818 operands[3] = GEN_INT (32 - temp);
1823 [(set (match_operand:SI 0 "s_register_operand" "")
1824 (match_operator:SI 1 "shiftable_operator"
1825 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1826 (match_operand:SI 3 "const_int_operand" "")
1827 (match_operand:SI 4 "const_int_operand" ""))
1828 (match_operand:SI 5 "s_register_operand" "")]))
1829 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1831 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1834 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1837 HOST_WIDE_INT temp = INTVAL (operands[3]);
1839 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1840 operands[4] = GEN_INT (32 - temp);
1844 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1845 ;;; represented by the bitfield, then this will produce incorrect results.
1846 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1847 ;;; which have a real bit-field insert instruction, the truncation happens
1848 ;;; in the bit-field insert instruction itself. Since arm does not have a
1849 ;;; bit-field insert instruction, we would have to emit code here to truncate
1850 ;;; the value before we insert. This loses some of the advantage of having
1851 ;;; this insv pattern, so this pattern needs to be reevalutated.
1853 (define_expand "insv"
1854 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1855 (match_operand:SI 1 "general_operand" "")
1856 (match_operand:SI 2 "general_operand" ""))
1857 (match_operand:SI 3 "reg_or_int_operand" ""))]
1861 int start_bit = INTVAL (operands[2]);
1862 int width = INTVAL (operands[1]);
1863 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1864 rtx target, subtarget;
1866 target = operands[0];
1867 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1868 subreg as the final target. */
1869 if (GET_CODE (target) == SUBREG)
1871 subtarget = gen_reg_rtx (SImode);
1872 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1873 < GET_MODE_SIZE (SImode))
1874 target = SUBREG_REG (target);
1879 if (GET_CODE (operands[3]) == CONST_INT)
1881 /* Since we are inserting a known constant, we may be able to
1882 reduce the number of bits that we have to clear so that
1883 the mask becomes simple. */
1884 /* ??? This code does not check to see if the new mask is actually
1885 simpler. It may not be. */
1886 rtx op1 = gen_reg_rtx (SImode);
1887 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1888 start of this pattern. */
1889 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1890 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1892 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1893 emit_insn (gen_iorsi3 (subtarget, op1,
1894 gen_int_mode (op3_value << start_bit, SImode)));
1896 else if (start_bit == 0
1897 && !(const_ok_for_arm (mask)
1898 || const_ok_for_arm (~mask)))
1900 /* A Trick, since we are setting the bottom bits in the word,
1901 we can shift operand[3] up, operand[0] down, OR them together
1902 and rotate the result back again. This takes 3 insns, and
1903 the third might be mergeable into another op. */
1904 /* The shift up copes with the possibility that operand[3] is
1905 wider than the bitfield. */
1906 rtx op0 = gen_reg_rtx (SImode);
1907 rtx op1 = gen_reg_rtx (SImode);
1909 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1910 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1911 emit_insn (gen_iorsi3 (op1, op1, op0));
1912 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1914 else if ((width + start_bit == 32)
1915 && !(const_ok_for_arm (mask)
1916 || const_ok_for_arm (~mask)))
1918 /* Similar trick, but slightly less efficient. */
1920 rtx op0 = gen_reg_rtx (SImode);
1921 rtx op1 = gen_reg_rtx (SImode);
1923 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1924 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1925 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1926 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1930 rtx op0 = GEN_INT (mask);
1931 rtx op1 = gen_reg_rtx (SImode);
1932 rtx op2 = gen_reg_rtx (SImode);
1934 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1936 rtx tmp = gen_reg_rtx (SImode);
1938 emit_insn (gen_movsi (tmp, op0));
1942 /* Mask out any bits in operand[3] that are not needed. */
1943 emit_insn (gen_andsi3 (op1, operands[3], op0));
1945 if (GET_CODE (op0) == CONST_INT
1946 && (const_ok_for_arm (mask << start_bit)
1947 || const_ok_for_arm (~(mask << start_bit))))
1949 op0 = GEN_INT (~(mask << start_bit));
1950 emit_insn (gen_andsi3 (op2, operands[0], op0));
1954 if (GET_CODE (op0) == CONST_INT)
1956 rtx tmp = gen_reg_rtx (SImode);
1958 emit_insn (gen_movsi (tmp, op0));
1963 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1965 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1969 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1971 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1974 if (subtarget != target)
1976 /* If TARGET is still a SUBREG, then it must be wider than a word,
1977 so we must be careful only to set the subword we were asked to. */
1978 if (GET_CODE (target) == SUBREG)
1979 emit_move_insn (target, subtarget);
1981 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1988 ; constants for op 2 will never be given to these patterns.
1989 (define_insn_and_split "*anddi_notdi_di"
1990 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1991 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1992 (match_operand:DI 2 "s_register_operand" "0,r")))]
1995 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1996 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
1997 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2000 operands[3] = gen_highpart (SImode, operands[0]);
2001 operands[0] = gen_lowpart (SImode, operands[0]);
2002 operands[4] = gen_highpart (SImode, operands[1]);
2003 operands[1] = gen_lowpart (SImode, operands[1]);
2004 operands[5] = gen_highpart (SImode, operands[2]);
2005 operands[2] = gen_lowpart (SImode, operands[2]);
2007 [(set_attr "length" "8")
2008 (set_attr "predicable" "yes")]
2011 (define_insn_and_split "*anddi_notzesidi_di"
2012 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2013 (and:DI (not:DI (zero_extend:DI
2014 (match_operand:SI 2 "s_register_operand" "r,r")))
2015 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2018 bic%?\\t%Q0, %Q1, %2
2020 ; (not (zero_extend ...)) allows us to just copy the high word from
2021 ; operand1 to operand0.
2024 && operands[0] != operands[1]"
2025 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2026 (set (match_dup 3) (match_dup 4))]
2029 operands[3] = gen_highpart (SImode, operands[0]);
2030 operands[0] = gen_lowpart (SImode, operands[0]);
2031 operands[4] = gen_highpart (SImode, operands[1]);
2032 operands[1] = gen_lowpart (SImode, operands[1]);
2034 [(set_attr "length" "4,8")
2035 (set_attr "predicable" "yes")]
2038 (define_insn_and_split "*anddi_notsesidi_di"
2039 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2040 (and:DI (not:DI (sign_extend:DI
2041 (match_operand:SI 2 "s_register_operand" "r,r")))
2042 (match_operand:DI 1 "s_register_operand" "0,r")))]
2045 "TARGET_ARM && reload_completed"
2046 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2047 (set (match_dup 3) (and:SI (not:SI
2048 (ashiftrt:SI (match_dup 2) (const_int 31)))
2052 operands[3] = gen_highpart (SImode, operands[0]);
2053 operands[0] = gen_lowpart (SImode, operands[0]);
2054 operands[4] = gen_highpart (SImode, operands[1]);
2055 operands[1] = gen_lowpart (SImode, operands[1]);
2057 [(set_attr "length" "8")
2058 (set_attr "predicable" "yes")]
2061 (define_insn "andsi_notsi_si"
2062 [(set (match_operand:SI 0 "s_register_operand" "=r")
2063 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2064 (match_operand:SI 1 "s_register_operand" "r")))]
2066 "bic%?\\t%0, %1, %2"
2067 [(set_attr "predicable" "yes")]
2070 (define_insn "bicsi3"
2071 [(set (match_operand:SI 0 "register_operand" "=l")
2072 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2073 (match_operand:SI 2 "register_operand" "0")))]
2076 [(set_attr "length" "2")]
2079 (define_insn "andsi_not_shiftsi_si"
2080 [(set (match_operand:SI 0 "s_register_operand" "=r")
2081 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2082 [(match_operand:SI 2 "s_register_operand" "r")
2083 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2084 (match_operand:SI 1 "s_register_operand" "r")))]
2086 "bic%?\\t%0, %1, %2%S4"
2087 [(set_attr "predicable" "yes")
2088 (set_attr "shift" "2")
2089 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2090 (const_string "alu_shift")
2091 (const_string "alu_shift_reg")))]
2094 (define_insn "*andsi_notsi_si_compare0"
2095 [(set (reg:CC_NOOV CC_REGNUM)
2097 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2098 (match_operand:SI 1 "s_register_operand" "r"))
2100 (set (match_operand:SI 0 "s_register_operand" "=r")
2101 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2103 "bic%?s\\t%0, %1, %2"
2104 [(set_attr "conds" "set")]
2107 (define_insn "*andsi_notsi_si_compare0_scratch"
2108 [(set (reg:CC_NOOV CC_REGNUM)
2110 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2111 (match_operand:SI 1 "s_register_operand" "r"))
2113 (clobber (match_scratch:SI 0 "=r"))]
2115 "bic%?s\\t%0, %1, %2"
2116 [(set_attr "conds" "set")]
2119 (define_insn "iordi3"
2120 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2121 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2122 (match_operand:DI 2 "s_register_operand" "r,r")))]
2123 "TARGET_ARM && ! TARGET_IWMMXT"
2125 [(set_attr "length" "8")
2126 (set_attr "predicable" "yes")]
2129 (define_insn "*iordi_zesidi_di"
2130 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2131 (ior:DI (zero_extend:DI
2132 (match_operand:SI 2 "s_register_operand" "r,r"))
2133 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2136 orr%?\\t%Q0, %Q1, %2
2138 [(set_attr "length" "4,8")
2139 (set_attr "predicable" "yes")]
2142 (define_insn "*iordi_sesidi_di"
2143 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2144 (ior:DI (sign_extend:DI
2145 (match_operand:SI 2 "s_register_operand" "r,r"))
2146 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2149 [(set_attr "length" "8")
2150 (set_attr "predicable" "yes")]
2153 (define_expand "iorsi3"
2154 [(set (match_operand:SI 0 "s_register_operand" "")
2155 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2156 (match_operand:SI 2 "reg_or_int_operand" "")))]
2159 if (GET_CODE (operands[2]) == CONST_INT)
2163 arm_split_constant (IOR, SImode, NULL_RTX,
2164 INTVAL (operands[2]), operands[0], operands[1],
2165 optimize && !no_new_pseudos);
2168 else /* TARGET_THUMB */
2169 operands [2] = force_reg (SImode, operands [2]);
2174 (define_insn_and_split "*arm_iorsi3"
2175 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2176 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2177 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2183 && GET_CODE (operands[2]) == CONST_INT
2184 && !const_ok_for_arm (INTVAL (operands[2]))"
2185 [(clobber (const_int 0))]
2187 arm_split_constant (IOR, SImode, curr_insn,
2188 INTVAL (operands[2]), operands[0], operands[1], 0);
2191 [(set_attr "length" "4,16")
2192 (set_attr "predicable" "yes")]
2195 (define_insn "*thumb_iorsi3"
2196 [(set (match_operand:SI 0 "register_operand" "=l")
2197 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2198 (match_operand:SI 2 "register_operand" "l")))]
2201 [(set_attr "length" "2")]
2205 [(match_scratch:SI 3 "r")
2206 (set (match_operand:SI 0 "arm_general_register_operand" "")
2207 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2208 (match_operand:SI 2 "const_int_operand" "")))]
2210 && !const_ok_for_arm (INTVAL (operands[2]))
2211 && const_ok_for_arm (~INTVAL (operands[2]))"
2212 [(set (match_dup 3) (match_dup 2))
2213 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2217 (define_insn "*iorsi3_compare0"
2218 [(set (reg:CC_NOOV CC_REGNUM)
2219 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2220 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2222 (set (match_operand:SI 0 "s_register_operand" "=r")
2223 (ior:SI (match_dup 1) (match_dup 2)))]
2225 "orr%?s\\t%0, %1, %2"
2226 [(set_attr "conds" "set")]
2229 (define_insn "*iorsi3_compare0_scratch"
2230 [(set (reg:CC_NOOV CC_REGNUM)
2231 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2232 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2234 (clobber (match_scratch:SI 0 "=r"))]
2236 "orr%?s\\t%0, %1, %2"
2237 [(set_attr "conds" "set")]
2240 (define_insn "xordi3"
2241 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2242 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2243 (match_operand:DI 2 "s_register_operand" "r,r")))]
2244 "TARGET_ARM && !TARGET_IWMMXT"
2246 [(set_attr "length" "8")
2247 (set_attr "predicable" "yes")]
2250 (define_insn "*xordi_zesidi_di"
2251 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2252 (xor:DI (zero_extend:DI
2253 (match_operand:SI 2 "s_register_operand" "r,r"))
2254 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2257 eor%?\\t%Q0, %Q1, %2
2259 [(set_attr "length" "4,8")
2260 (set_attr "predicable" "yes")]
2263 (define_insn "*xordi_sesidi_di"
2264 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2265 (xor:DI (sign_extend:DI
2266 (match_operand:SI 2 "s_register_operand" "r,r"))
2267 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2270 [(set_attr "length" "8")
2271 (set_attr "predicable" "yes")]
2274 (define_expand "xorsi3"
2275 [(set (match_operand:SI 0 "s_register_operand" "")
2276 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2277 (match_operand:SI 2 "arm_rhs_operand" "")))]
2280 if (GET_CODE (operands[2]) == CONST_INT)
2281 operands[2] = force_reg (SImode, operands[2]);
2285 (define_insn "*arm_xorsi3"
2286 [(set (match_operand:SI 0 "s_register_operand" "=r")
2287 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2288 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2290 "eor%?\\t%0, %1, %2"
2291 [(set_attr "predicable" "yes")]
2294 (define_insn "*thumb_xorsi3"
2295 [(set (match_operand:SI 0 "register_operand" "=l")
2296 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2297 (match_operand:SI 2 "register_operand" "l")))]
2300 [(set_attr "length" "2")]
2303 (define_insn "*xorsi3_compare0"
2304 [(set (reg:CC_NOOV CC_REGNUM)
2305 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2306 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2308 (set (match_operand:SI 0 "s_register_operand" "=r")
2309 (xor:SI (match_dup 1) (match_dup 2)))]
2311 "eor%?s\\t%0, %1, %2"
2312 [(set_attr "conds" "set")]
2315 (define_insn "*xorsi3_compare0_scratch"
2316 [(set (reg:CC_NOOV CC_REGNUM)
2317 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2318 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2322 [(set_attr "conds" "set")]
2325 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2326 ; (NOT D) we can sometimes merge the final NOT into one of the following
2330 [(set (match_operand:SI 0 "s_register_operand" "")
2331 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2332 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2333 (match_operand:SI 3 "arm_rhs_operand" "")))
2334 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2336 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2337 (not:SI (match_dup 3))))
2338 (set (match_dup 0) (not:SI (match_dup 4)))]
2342 (define_insn "*andsi_iorsi3_notsi"
2343 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2344 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2345 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2346 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2348 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2349 [(set_attr "length" "8")
2350 (set_attr "predicable" "yes")]
2354 [(set (match_operand:SI 0 "s_register_operand" "")
2355 (match_operator:SI 1 "logical_binary_operator"
2356 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2357 (match_operand:SI 3 "const_int_operand" "")
2358 (match_operand:SI 4 "const_int_operand" ""))
2359 (match_operator:SI 9 "logical_binary_operator"
2360 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2361 (match_operand:SI 6 "const_int_operand" ""))
2362 (match_operand:SI 7 "s_register_operand" "")])]))
2363 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2365 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2366 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2369 [(ashift:SI (match_dup 2) (match_dup 4))
2373 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2376 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2380 [(set (match_operand:SI 0 "s_register_operand" "")
2381 (match_operator:SI 1 "logical_binary_operator"
2382 [(match_operator:SI 9 "logical_binary_operator"
2383 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2384 (match_operand:SI 6 "const_int_operand" ""))
2385 (match_operand:SI 7 "s_register_operand" "")])
2386 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2387 (match_operand:SI 3 "const_int_operand" "")
2388 (match_operand:SI 4 "const_int_operand" ""))]))
2389 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2391 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2392 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2395 [(ashift:SI (match_dup 2) (match_dup 4))
2399 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2402 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2406 [(set (match_operand:SI 0 "s_register_operand" "")
2407 (match_operator:SI 1 "logical_binary_operator"
2408 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2409 (match_operand:SI 3 "const_int_operand" "")
2410 (match_operand:SI 4 "const_int_operand" ""))
2411 (match_operator:SI 9 "logical_binary_operator"
2412 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2413 (match_operand:SI 6 "const_int_operand" ""))
2414 (match_operand:SI 7 "s_register_operand" "")])]))
2415 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2417 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2418 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2421 [(ashift:SI (match_dup 2) (match_dup 4))
2425 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2428 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2432 [(set (match_operand:SI 0 "s_register_operand" "")
2433 (match_operator:SI 1 "logical_binary_operator"
2434 [(match_operator:SI 9 "logical_binary_operator"
2435 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2436 (match_operand:SI 6 "const_int_operand" ""))
2437 (match_operand:SI 7 "s_register_operand" "")])
2438 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2439 (match_operand:SI 3 "const_int_operand" "")
2440 (match_operand:SI 4 "const_int_operand" ""))]))
2441 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2443 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2444 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2447 [(ashift:SI (match_dup 2) (match_dup 4))
2451 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2454 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2458 ;; Minimum and maximum insns
2460 (define_insn "smaxsi3"
2461 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2462 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2463 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2464 (clobber (reg:CC CC_REGNUM))]
2467 cmp\\t%1, %2\;movlt\\t%0, %2
2468 cmp\\t%1, %2\;movge\\t%0, %1
2469 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2470 [(set_attr "conds" "clob")
2471 (set_attr "length" "8,8,12")]
2474 (define_insn "sminsi3"
2475 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2476 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2477 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2478 (clobber (reg:CC CC_REGNUM))]
2481 cmp\\t%1, %2\;movge\\t%0, %2
2482 cmp\\t%1, %2\;movlt\\t%0, %1
2483 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2484 [(set_attr "conds" "clob")
2485 (set_attr "length" "8,8,12")]
2488 (define_insn "umaxsi3"
2489 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2490 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2491 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2492 (clobber (reg:CC CC_REGNUM))]
2495 cmp\\t%1, %2\;movcc\\t%0, %2
2496 cmp\\t%1, %2\;movcs\\t%0, %1
2497 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2498 [(set_attr "conds" "clob")
2499 (set_attr "length" "8,8,12")]
2502 (define_insn "uminsi3"
2503 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2504 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2505 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2506 (clobber (reg:CC CC_REGNUM))]
2509 cmp\\t%1, %2\;movcs\\t%0, %2
2510 cmp\\t%1, %2\;movcc\\t%0, %1
2511 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2512 [(set_attr "conds" "clob")
2513 (set_attr "length" "8,8,12")]
2516 (define_insn "*store_minmaxsi"
2517 [(set (match_operand:SI 0 "memory_operand" "=m")
2518 (match_operator:SI 3 "minmax_operator"
2519 [(match_operand:SI 1 "s_register_operand" "r")
2520 (match_operand:SI 2 "s_register_operand" "r")]))
2521 (clobber (reg:CC CC_REGNUM))]
2524 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2525 operands[1], operands[2]);
2526 output_asm_insn (\"cmp\\t%1, %2\", operands);
2527 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2528 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2531 [(set_attr "conds" "clob")
2532 (set_attr "length" "12")
2533 (set_attr "type" "store1")]
2536 ; Reject the frame pointer in operand[1], since reloading this after
2537 ; it has been eliminated can cause carnage.
2538 (define_insn "*minmax_arithsi"
2539 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2540 (match_operator:SI 4 "shiftable_operator"
2541 [(match_operator:SI 5 "minmax_operator"
2542 [(match_operand:SI 2 "s_register_operand" "r,r")
2543 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2544 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2545 (clobber (reg:CC CC_REGNUM))]
2546 "TARGET_ARM && !arm_eliminable_register (operands[1])"
2549 enum rtx_code code = GET_CODE (operands[4]);
2551 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2552 operands[2], operands[3]);
2553 output_asm_insn (\"cmp\\t%2, %3\", operands);
2554 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2555 if (which_alternative != 0 || operands[3] != const0_rtx
2556 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2557 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2560 [(set_attr "conds" "clob")
2561 (set_attr "length" "12")]
2565 ;; Shift and rotation insns
2567 (define_expand "ashldi3"
2568 [(set (match_operand:DI 0 "s_register_operand" "")
2569 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2570 (match_operand:SI 2 "reg_or_int_operand" "")))]
2573 if (GET_CODE (operands[2]) == CONST_INT)
2575 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2577 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2580 /* Ideally we shouldn't fail here if we could know that operands[1]
2581 ends up already living in an iwmmxt register. Otherwise it's
2582 cheaper to have the alternate code being generated than moving
2583 values to iwmmxt regs and back. */
2586 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2591 (define_insn "arm_ashldi3_1bit"
2592 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2593 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2595 (clobber (reg:CC CC_REGNUM))]
2597 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2598 [(set_attr "conds" "clob")
2599 (set_attr "length" "8")]
2602 (define_expand "ashlsi3"
2603 [(set (match_operand:SI 0 "s_register_operand" "")
2604 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2605 (match_operand:SI 2 "arm_rhs_operand" "")))]
2608 if (GET_CODE (operands[2]) == CONST_INT
2609 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2611 emit_insn (gen_movsi (operands[0], const0_rtx));
2617 (define_insn "*thumb_ashlsi3"
2618 [(set (match_operand:SI 0 "register_operand" "=l,l")
2619 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2620 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2623 [(set_attr "length" "2")]
2626 (define_expand "ashrdi3"
2627 [(set (match_operand:DI 0 "s_register_operand" "")
2628 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2629 (match_operand:SI 2 "reg_or_int_operand" "")))]
2632 if (GET_CODE (operands[2]) == CONST_INT)
2634 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2636 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2639 /* Ideally we shouldn't fail here if we could know that operands[1]
2640 ends up already living in an iwmmxt register. Otherwise it's
2641 cheaper to have the alternate code being generated than moving
2642 values to iwmmxt regs and back. */
2645 else if (!TARGET_REALLY_IWMMXT)
2650 (define_insn "arm_ashrdi3_1bit"
2651 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2652 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2654 (clobber (reg:CC CC_REGNUM))]
2656 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2657 [(set_attr "conds" "clob")
2658 (set_attr "length" "8")]
2661 (define_expand "ashrsi3"
2662 [(set (match_operand:SI 0 "s_register_operand" "")
2663 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2664 (match_operand:SI 2 "arm_rhs_operand" "")))]
2667 if (GET_CODE (operands[2]) == CONST_INT
2668 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2669 operands[2] = GEN_INT (31);
2673 (define_insn "*thumb_ashrsi3"
2674 [(set (match_operand:SI 0 "register_operand" "=l,l")
2675 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2676 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2679 [(set_attr "length" "2")]
2682 (define_expand "lshrdi3"
2683 [(set (match_operand:DI 0 "s_register_operand" "")
2684 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2685 (match_operand:SI 2 "reg_or_int_operand" "")))]
2688 if (GET_CODE (operands[2]) == CONST_INT)
2690 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2692 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2695 /* Ideally we shouldn't fail here if we could know that operands[1]
2696 ends up already living in an iwmmxt register. Otherwise it's
2697 cheaper to have the alternate code being generated than moving
2698 values to iwmmxt regs and back. */
2701 else if (!TARGET_REALLY_IWMMXT)
2706 (define_insn "arm_lshrdi3_1bit"
2707 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2708 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2710 (clobber (reg:CC CC_REGNUM))]
2712 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2713 [(set_attr "conds" "clob")
2714 (set_attr "length" "8")]
2717 (define_expand "lshrsi3"
2718 [(set (match_operand:SI 0 "s_register_operand" "")
2719 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2720 (match_operand:SI 2 "arm_rhs_operand" "")))]
2723 if (GET_CODE (operands[2]) == CONST_INT
2724 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2726 emit_insn (gen_movsi (operands[0], const0_rtx));
2732 (define_insn "*thumb_lshrsi3"
2733 [(set (match_operand:SI 0 "register_operand" "=l,l")
2734 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2735 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2738 [(set_attr "length" "2")]
2741 (define_expand "rotlsi3"
2742 [(set (match_operand:SI 0 "s_register_operand" "")
2743 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2744 (match_operand:SI 2 "reg_or_int_operand" "")))]
2747 if (GET_CODE (operands[2]) == CONST_INT)
2748 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2751 rtx reg = gen_reg_rtx (SImode);
2752 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2758 (define_expand "rotrsi3"
2759 [(set (match_operand:SI 0 "s_register_operand" "")
2760 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2761 (match_operand:SI 2 "arm_rhs_operand" "")))]
2766 if (GET_CODE (operands[2]) == CONST_INT
2767 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2768 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2770 else /* TARGET_THUMB */
2772 if (GET_CODE (operands [2]) == CONST_INT)
2773 operands [2] = force_reg (SImode, operands[2]);
2778 (define_insn "*thumb_rotrsi3"
2779 [(set (match_operand:SI 0 "register_operand" "=l")
2780 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2781 (match_operand:SI 2 "register_operand" "l")))]
2784 [(set_attr "length" "2")]
2787 (define_insn "*arm_shiftsi3"
2788 [(set (match_operand:SI 0 "s_register_operand" "=r")
2789 (match_operator:SI 3 "shift_operator"
2790 [(match_operand:SI 1 "s_register_operand" "r")
2791 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2794 [(set_attr "predicable" "yes")
2795 (set_attr "shift" "1")
2796 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2797 (const_string "alu_shift")
2798 (const_string "alu_shift_reg")))]
2801 (define_insn "*shiftsi3_compare0"
2802 [(set (reg:CC_NOOV CC_REGNUM)
2803 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2804 [(match_operand:SI 1 "s_register_operand" "r")
2805 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2807 (set (match_operand:SI 0 "s_register_operand" "=r")
2808 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2810 "mov%?s\\t%0, %1%S3"
2811 [(set_attr "conds" "set")
2812 (set_attr "shift" "1")
2813 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2814 (const_string "alu_shift")
2815 (const_string "alu_shift_reg")))]
2818 (define_insn "*shiftsi3_compare0_scratch"
2819 [(set (reg:CC_NOOV CC_REGNUM)
2820 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2821 [(match_operand:SI 1 "s_register_operand" "r")
2822 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2824 (clobber (match_scratch:SI 0 "=r"))]
2826 "mov%?s\\t%0, %1%S3"
2827 [(set_attr "conds" "set")
2828 (set_attr "shift" "1")]
2831 (define_insn "*notsi_shiftsi"
2832 [(set (match_operand:SI 0 "s_register_operand" "=r")
2833 (not:SI (match_operator:SI 3 "shift_operator"
2834 [(match_operand:SI 1 "s_register_operand" "r")
2835 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2838 [(set_attr "predicable" "yes")
2839 (set_attr "shift" "1")
2840 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2841 (const_string "alu_shift")
2842 (const_string "alu_shift_reg")))]
2845 (define_insn "*notsi_shiftsi_compare0"
2846 [(set (reg:CC_NOOV CC_REGNUM)
2847 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2848 [(match_operand:SI 1 "s_register_operand" "r")
2849 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2851 (set (match_operand:SI 0 "s_register_operand" "=r")
2852 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2854 "mvn%?s\\t%0, %1%S3"
2855 [(set_attr "conds" "set")
2856 (set_attr "shift" "1")
2857 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2858 (const_string "alu_shift")
2859 (const_string "alu_shift_reg")))]
2862 (define_insn "*not_shiftsi_compare0_scratch"
2863 [(set (reg:CC_NOOV CC_REGNUM)
2864 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2865 [(match_operand:SI 1 "s_register_operand" "r")
2866 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2868 (clobber (match_scratch:SI 0 "=r"))]
2870 "mvn%?s\\t%0, %1%S3"
2871 [(set_attr "conds" "set")
2872 (set_attr "shift" "1")
2873 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2874 (const_string "alu_shift")
2875 (const_string "alu_shift_reg")))]
2878 ;; We don't really have extzv, but defining this using shifts helps
2879 ;; to reduce register pressure later on.
2881 (define_expand "extzv"
2883 (ashift:SI (match_operand:SI 1 "register_operand" "")
2884 (match_operand:SI 2 "const_int_operand" "")))
2885 (set (match_operand:SI 0 "register_operand" "")
2886 (lshiftrt:SI (match_dup 4)
2887 (match_operand:SI 3 "const_int_operand" "")))]
2891 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2892 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2894 operands[3] = GEN_INT (rshift);
2898 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2902 operands[2] = GEN_INT (lshift);
2903 operands[4] = gen_reg_rtx (SImode);
2908 ;; Unary arithmetic insns
2910 (define_expand "negdi2"
2912 [(set (match_operand:DI 0 "s_register_operand" "")
2913 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2914 (clobber (reg:CC CC_REGNUM))])]
2919 if (GET_CODE (operands[1]) != REG)
2920 operands[1] = force_reg (SImode, operands[1]);
2925 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
2926 ;; The second alternative is to allow the common case of a *full* overlap.
2927 (define_insn "*arm_negdi2"
2928 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2929 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
2930 (clobber (reg:CC CC_REGNUM))]
2932 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
2933 [(set_attr "conds" "clob")
2934 (set_attr "length" "8")]
2937 (define_insn "*thumb_negdi2"
2938 [(set (match_operand:DI 0 "register_operand" "=&l")
2939 (neg:DI (match_operand:DI 1 "register_operand" "l")))
2940 (clobber (reg:CC CC_REGNUM))]
2942 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
2943 [(set_attr "length" "6")]
2946 (define_expand "negsi2"
2947 [(set (match_operand:SI 0 "s_register_operand" "")
2948 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
2953 (define_insn "*arm_negsi2"
2954 [(set (match_operand:SI 0 "s_register_operand" "=r")
2955 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
2957 "rsb%?\\t%0, %1, #0"
2958 [(set_attr "predicable" "yes")]
2961 (define_insn "*thumb_negsi2"
2962 [(set (match_operand:SI 0 "register_operand" "=l")
2963 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
2966 [(set_attr "length" "2")]
2969 (define_expand "negsf2"
2970 [(set (match_operand:SF 0 "s_register_operand" "")
2971 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
2972 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2976 (define_expand "negdf2"
2977 [(set (match_operand:DF 0 "s_register_operand" "")
2978 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
2979 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2982 ;; abssi2 doesn't really clobber the condition codes if a different register
2983 ;; is being set. To keep things simple, assume during rtl manipulations that
2984 ;; it does, but tell the final scan operator the truth. Similarly for
2987 (define_expand "abssi2"
2989 [(set (match_operand:SI 0 "s_register_operand" "")
2990 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
2991 (clobber (reg:CC CC_REGNUM))])]
2995 (define_insn "*arm_abssi2"
2996 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
2997 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
2998 (clobber (reg:CC CC_REGNUM))]
3001 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
3002 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
3003 [(set_attr "conds" "clob,*")
3004 (set_attr "shift" "1")
3005 ;; predicable can't be set based on the variant, so left as no
3006 (set_attr "length" "8")]
3009 (define_insn "*neg_abssi2"
3010 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3011 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
3012 (clobber (reg:CC CC_REGNUM))]
3015 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
3016 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
3017 [(set_attr "conds" "clob,*")
3018 (set_attr "shift" "1")
3019 ;; predicable can't be set based on the variant, so left as no
3020 (set_attr "length" "8")]
3023 (define_expand "abssf2"
3024 [(set (match_operand:SF 0 "s_register_operand" "")
3025 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
3026 "TARGET_ARM && TARGET_HARD_FLOAT"
3029 (define_expand "absdf2"
3030 [(set (match_operand:DF 0 "s_register_operand" "")
3031 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
3032 "TARGET_ARM && TARGET_HARD_FLOAT"
3035 (define_expand "sqrtsf2"
3036 [(set (match_operand:SF 0 "s_register_operand" "")
3037 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
3038 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3041 (define_expand "sqrtdf2"
3042 [(set (match_operand:DF 0 "s_register_operand" "")
3043 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
3044 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3047 (define_insn_and_split "one_cmpldi2"
3048 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3049 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
3052 "TARGET_ARM && reload_completed"
3053 [(set (match_dup 0) (not:SI (match_dup 1)))
3054 (set (match_dup 2) (not:SI (match_dup 3)))]
3057 operands[2] = gen_highpart (SImode, operands[0]);
3058 operands[0] = gen_lowpart (SImode, operands[0]);
3059 operands[3] = gen_highpart (SImode, operands[1]);
3060 operands[1] = gen_lowpart (SImode, operands[1]);
3062 [(set_attr "length" "8")
3063 (set_attr "predicable" "yes")]
3066 (define_expand "one_cmplsi2"
3067 [(set (match_operand:SI 0 "s_register_operand" "")
3068 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
3073 (define_insn "*arm_one_cmplsi2"
3074 [(set (match_operand:SI 0 "s_register_operand" "=r")
3075 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
3078 [(set_attr "predicable" "yes")]
3081 (define_insn "*thumb_one_cmplsi2"
3082 [(set (match_operand:SI 0 "register_operand" "=l")
3083 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3086 [(set_attr "length" "2")]
3089 (define_insn "*notsi_compare0"
3090 [(set (reg:CC_NOOV CC_REGNUM)
3091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3093 (set (match_operand:SI 0 "s_register_operand" "=r")
3094 (not:SI (match_dup 1)))]
3097 [(set_attr "conds" "set")]
3100 (define_insn "*notsi_compare0_scratch"
3101 [(set (reg:CC_NOOV CC_REGNUM)
3102 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3104 (clobber (match_scratch:SI 0 "=r"))]
3107 [(set_attr "conds" "set")]
3110 ;; Fixed <--> Floating conversion insns
3112 (define_expand "floatsisf2"
3113 [(set (match_operand:SF 0 "s_register_operand" "")
3114 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3115 "TARGET_ARM && TARGET_HARD_FLOAT"
3117 if (TARGET_MAVERICK)
3119 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3124 (define_expand "floatsidf2"
3125 [(set (match_operand:DF 0 "s_register_operand" "")
3126 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3127 "TARGET_ARM && TARGET_HARD_FLOAT"
3129 if (TARGET_MAVERICK)
3131 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3136 (define_expand "fix_truncsfsi2"
3137 [(set (match_operand:SI 0 "s_register_operand" "")
3138 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3139 "TARGET_ARM && TARGET_HARD_FLOAT"
3141 if (TARGET_MAVERICK)
3143 if (!cirrus_fp_register (operands[0], SImode))
3144 operands[0] = force_reg (SImode, operands[0]);
3145 if (!cirrus_fp_register (operands[1], SFmode))
3146 operands[1] = force_reg (SFmode, operands[0]);
3147 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3152 (define_expand "fix_truncdfsi2"
3153 [(set (match_operand:SI 0 "s_register_operand" "")
3154 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3155 "TARGET_ARM && TARGET_HARD_FLOAT"
3157 if (TARGET_MAVERICK)
3159 if (!cirrus_fp_register (operands[1], DFmode))
3160 operands[1] = force_reg (DFmode, operands[0]);
3161 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3168 (define_expand "truncdfsf2"
3169 [(set (match_operand:SF 0 "s_register_operand" "")
3171 (match_operand:DF 1 "s_register_operand" "")))]
3172 "TARGET_ARM && TARGET_HARD_FLOAT"
3176 ;; Zero and sign extension instructions.
3178 (define_insn "zero_extendsidi2"
3179 [(set (match_operand:DI 0 "s_register_operand" "=r")
3180 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3183 if (REGNO (operands[1])
3184 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3185 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3186 return \"mov%?\\t%R0, #0\";
3188 [(set_attr "length" "8")
3189 (set_attr "predicable" "yes")]
3192 (define_insn "zero_extendqidi2"
3193 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3194 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3197 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3198 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3199 [(set_attr "length" "8")
3200 (set_attr "predicable" "yes")
3201 (set_attr "type" "*,load_byte")
3202 (set_attr "pool_range" "*,4092")
3203 (set_attr "neg_pool_range" "*,4084")]
3206 (define_insn "extendsidi2"
3207 [(set (match_operand:DI 0 "s_register_operand" "=r")
3208 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3211 if (REGNO (operands[1])
3212 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3213 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3214 return \"mov%?\\t%R0, %Q0, asr #31\";
3216 [(set_attr "length" "8")
3217 (set_attr "shift" "1")
3218 (set_attr "predicable" "yes")]
3221 (define_expand "zero_extendhisi2"
3223 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3225 (set (match_operand:SI 0 "s_register_operand" "")
3226 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3230 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3232 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3233 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3237 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3239 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3243 if (!s_register_operand (operands[1], HImode))
3244 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3248 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3249 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3253 operands[1] = gen_lowpart (SImode, operands[1]);
3254 operands[2] = gen_reg_rtx (SImode);
3258 (define_insn "*thumb_zero_extendhisi2"
3259 [(set (match_operand:SI 0 "register_operand" "=l")
3260 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3261 "TARGET_THUMB && !arm_arch6"
3263 rtx mem = XEXP (operands[1], 0);
3265 if (GET_CODE (mem) == CONST)
3266 mem = XEXP (mem, 0);
3268 if (GET_CODE (mem) == LABEL_REF)
3269 return \"ldr\\t%0, %1\";
3271 if (GET_CODE (mem) == PLUS)
3273 rtx a = XEXP (mem, 0);
3274 rtx b = XEXP (mem, 1);
3276 /* This can happen due to bugs in reload. */
3277 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3280 ops[0] = operands[0];
3283 output_asm_insn (\"mov %0, %1\", ops);
3285 XEXP (mem, 0) = operands[0];
3288 else if ( GET_CODE (a) == LABEL_REF
3289 && GET_CODE (b) == CONST_INT)
3290 return \"ldr\\t%0, %1\";
3293 return \"ldrh\\t%0, %1\";
3295 [(set_attr "length" "4")
3296 (set_attr "type" "load_byte")
3297 (set_attr "pool_range" "60")]
3300 (define_insn "*thumb_zero_extendhisi2_v6"
3301 [(set (match_operand:SI 0 "register_operand" "=l,l")
3302 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3303 "TARGET_THUMB && arm_arch6"
3307 if (which_alternative == 0)
3308 return \"uxth\\t%0, %1\";
3310 mem = XEXP (operands[1], 0);
3312 if (GET_CODE (mem) == CONST)
3313 mem = XEXP (mem, 0);
3315 if (GET_CODE (mem) == LABEL_REF)
3316 return \"ldr\\t%0, %1\";
3318 if (GET_CODE (mem) == PLUS)
3320 rtx a = XEXP (mem, 0);
3321 rtx b = XEXP (mem, 1);
3323 /* This can happen due to bugs in reload. */
3324 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3327 ops[0] = operands[0];
3330 output_asm_insn (\"mov %0, %1\", ops);
3332 XEXP (mem, 0) = operands[0];
3335 else if ( GET_CODE (a) == LABEL_REF
3336 && GET_CODE (b) == CONST_INT)
3337 return \"ldr\\t%0, %1\";
3340 return \"ldrh\\t%0, %1\";
3342 [(set_attr "length" "2,4")
3343 (set_attr "type" "alu_shift,load_byte")
3344 (set_attr "pool_range" "*,60")]
3347 (define_insn "*arm_zero_extendhisi2"
3348 [(set (match_operand:SI 0 "s_register_operand" "=r")
3349 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3350 "TARGET_ARM && arm_arch4 && !arm_arch6"
3352 [(set_attr "type" "load_byte")
3353 (set_attr "predicable" "yes")
3354 (set_attr "pool_range" "256")
3355 (set_attr "neg_pool_range" "244")]
3358 (define_insn "*arm_zero_extendhisi2_v6"
3359 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3360 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3361 "TARGET_ARM && arm_arch6"
3365 [(set_attr "type" "alu_shift,load_byte")
3366 (set_attr "predicable" "yes")
3367 (set_attr "pool_range" "*,256")
3368 (set_attr "neg_pool_range" "*,244")]
3371 (define_insn "*arm_zero_extendhisi2addsi"
3372 [(set (match_operand:SI 0 "s_register_operand" "=r")
3373 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3374 (match_operand:SI 2 "s_register_operand" "r")))]
3375 "TARGET_ARM && arm_arch6"
3376 "uxtah%?\\t%0, %2, %1"
3377 [(set_attr "type" "alu_shift")
3378 (set_attr "predicable" "yes")]
3382 [(set (match_operand:SI 0 "s_register_operand" "")
3383 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3384 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3385 "TARGET_ARM && (!arm_arch4)"
3386 [(set (match_dup 2) (match_dup 1))
3387 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
3389 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3395 [(set (match_operand:SI 0 "s_register_operand" "")
3396 (match_operator:SI 3 "shiftable_operator"
3397 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3398 (match_operand:SI 4 "s_register_operand" "")]))
3399 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3400 "TARGET_ARM && (!arm_arch4)"
3401 [(set (match_dup 2) (match_dup 1))
3404 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3406 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3411 (define_expand "zero_extendqisi2"
3412 [(set (match_operand:SI 0 "s_register_operand" "")
3413 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3416 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3420 emit_insn (gen_andsi3 (operands[0],
3421 gen_lowpart (SImode, operands[1]),
3424 else /* TARGET_THUMB */
3426 rtx temp = gen_reg_rtx (SImode);
3429 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3430 operands[1] = gen_lowpart (SImode, operands[1]);
3433 ops[1] = operands[1];
3434 ops[2] = GEN_INT (24);
3436 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3437 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3439 ops[0] = operands[0];
3441 ops[2] = GEN_INT (24);
3443 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3444 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3451 (define_insn "*thumb_zero_extendqisi2"
3452 [(set (match_operand:SI 0 "register_operand" "=l")
3453 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3454 "TARGET_THUMB && !arm_arch6"
3456 [(set_attr "length" "2")
3457 (set_attr "type" "load_byte")
3458 (set_attr "pool_range" "32")]
3461 (define_insn "*thumb_zero_extendqisi2_v6"
3462 [(set (match_operand:SI 0 "register_operand" "=l,l")
3463 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3464 "TARGET_THUMB && arm_arch6"
3468 [(set_attr "length" "2,2")
3469 (set_attr "type" "alu_shift,load_byte")
3470 (set_attr "pool_range" "*,32")]
3473 (define_insn "*arm_zero_extendqisi2"
3474 [(set (match_operand:SI 0 "s_register_operand" "=r")
3475 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3476 "TARGET_ARM && !arm_arch6"
3477 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3478 [(set_attr "type" "load_byte")
3479 (set_attr "predicable" "yes")
3480 (set_attr "pool_range" "4096")
3481 (set_attr "neg_pool_range" "4084")]
3484 (define_insn "*arm_zero_extendqisi2_v6"
3485 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3486 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3487 "TARGET_ARM && arm_arch6"
3490 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3491 [(set_attr "type" "alu_shift,load_byte")
3492 (set_attr "predicable" "yes")
3493 (set_attr "pool_range" "*,4096")
3494 (set_attr "neg_pool_range" "*,4084")]
3497 (define_insn "*arm_zero_extendqisi2addsi"
3498 [(set (match_operand:SI 0 "s_register_operand" "=r")
3499 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3500 (match_operand:SI 2 "s_register_operand" "r")))]
3501 "TARGET_ARM && arm_arch6"
3502 "uxtab%?\\t%0, %2, %1"
3503 [(set_attr "predicable" "yes")
3504 (set_attr "type" "alu_shift")]
3508 [(set (match_operand:SI 0 "s_register_operand" "")
3509 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3510 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3511 "TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3512 [(set (match_dup 2) (match_dup 1))
3513 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3517 (define_insn "*compareqi_eq0"
3518 [(set (reg:CC_Z CC_REGNUM)
3519 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3523 [(set_attr "conds" "set")]
3526 (define_expand "extendhisi2"
3528 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3530 (set (match_operand:SI 0 "s_register_operand" "")
3531 (ashiftrt:SI (match_dup 2)
3536 if (GET_CODE (operands[1]) == MEM)
3540 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3545 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3546 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3551 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3553 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3557 if (!s_register_operand (operands[1], HImode))
3558 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3563 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3565 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3566 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3571 operands[1] = gen_lowpart (SImode, operands[1]);
3572 operands[2] = gen_reg_rtx (SImode);
3576 (define_insn "thumb_extendhisi2"
3577 [(set (match_operand:SI 0 "register_operand" "=l")
3578 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
3579 (clobber (match_scratch:SI 2 "=&l"))]
3580 "TARGET_THUMB && !arm_arch6"
3584 rtx mem = XEXP (operands[1], 0);
3586 /* This code used to try to use 'V', and fix the address only if it was
3587 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3588 range of QImode offsets, and offsettable_address_p does a QImode
3591 if (GET_CODE (mem) == CONST)
3592 mem = XEXP (mem, 0);
3594 if (GET_CODE (mem) == LABEL_REF)
3595 return \"ldr\\t%0, %1\";
3597 if (GET_CODE (mem) == PLUS)
3599 rtx a = XEXP (mem, 0);
3600 rtx b = XEXP (mem, 1);
3602 if (GET_CODE (a) == LABEL_REF
3603 && GET_CODE (b) == CONST_INT)
3604 return \"ldr\\t%0, %1\";
3606 if (GET_CODE (b) == REG)
3607 return \"ldrsh\\t%0, %1\";
3615 ops[2] = const0_rtx;
3618 if (GET_CODE (ops[1]) != REG)
3624 ops[0] = operands[0];
3625 ops[3] = operands[2];
3626 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3629 [(set_attr "length" "4")
3630 (set_attr "type" "load_byte")
3631 (set_attr "pool_range" "1020")]
3634 ;; We used to have an early-clobber on the scratch register here.
3635 ;; However, there's a bug somewhere in reload which means that this
3636 ;; can be partially ignored during spill allocation if the memory
3637 ;; address also needs reloading; this causes an abort later on when
3638 ;; we try to verify the operands. Fortunately, we don't really need
3639 ;; the early-clobber: we can always use operand 0 if operand 2
3640 ;; overlaps the address.
3641 (define_insn "*thumb_extendhisi2_insn_v6"
3642 [(set (match_operand:SI 0 "register_operand" "=l,l")
3643 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
3644 (clobber (match_scratch:SI 2 "=X,l"))]
3645 "TARGET_THUMB && arm_arch6"
3651 if (which_alternative == 0)
3652 return \"sxth\\t%0, %1\";
3654 mem = XEXP (operands[1], 0);
3656 /* This code used to try to use 'V', and fix the address only if it was
3657 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3658 range of QImode offsets, and offsettable_address_p does a QImode
3661 if (GET_CODE (mem) == CONST)
3662 mem = XEXP (mem, 0);
3664 if (GET_CODE (mem) == LABEL_REF)
3665 return \"ldr\\t%0, %1\";
3667 if (GET_CODE (mem) == PLUS)
3669 rtx a = XEXP (mem, 0);
3670 rtx b = XEXP (mem, 1);
3672 if (GET_CODE (a) == LABEL_REF
3673 && GET_CODE (b) == CONST_INT)
3674 return \"ldr\\t%0, %1\";
3676 if (GET_CODE (b) == REG)
3677 return \"ldrsh\\t%0, %1\";
3685 ops[2] = const0_rtx;
3688 if (GET_CODE (ops[1]) != REG)
3694 ops[0] = operands[0];
3695 if (reg_mentioned_p (operands[2], ops[1]))
3698 ops[3] = operands[2];
3699 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3702 [(set_attr "length" "2,4")
3703 (set_attr "type" "alu_shift,load_byte")
3704 (set_attr "pool_range" "*,1020")]
3707 (define_expand "extendhisi2_mem"
3708 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3710 (zero_extend:SI (match_dup 7)))
3711 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
3712 (set (match_operand:SI 0 "" "")
3713 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
3718 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3720 mem1 = gen_rtx_MEM (QImode, addr);
3721 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3722 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3723 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3724 operands[0] = gen_lowpart (SImode, operands[0]);
3726 operands[2] = gen_reg_rtx (SImode);
3727 operands[3] = gen_reg_rtx (SImode);
3728 operands[6] = gen_reg_rtx (SImode);
3731 if (BYTES_BIG_ENDIAN)
3733 operands[4] = operands[2];
3734 operands[5] = operands[3];
3738 operands[4] = operands[3];
3739 operands[5] = operands[2];
3744 (define_insn "*arm_extendhisi2"
3745 [(set (match_operand:SI 0 "s_register_operand" "=r")
3746 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3747 "TARGET_ARM && arm_arch4 && !arm_arch6"
3749 [(set_attr "type" "load_byte")
3750 (set_attr "predicable" "yes")
3751 (set_attr "pool_range" "256")
3752 (set_attr "neg_pool_range" "244")]
3755 (define_insn "*arm_extendhisi2_v6"
3756 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3757 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3758 "TARGET_ARM && arm_arch6"
3762 [(set_attr "type" "alu_shift,load_byte")
3763 (set_attr "predicable" "yes")
3764 (set_attr "pool_range" "*,256")
3765 (set_attr "neg_pool_range" "*,244")]
3768 (define_insn "*arm_extendhisi2addsi"
3769 [(set (match_operand:SI 0 "s_register_operand" "=r")
3770 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3771 (match_operand:SI 2 "s_register_operand" "r")))]
3772 "TARGET_ARM && arm_arch6"
3773 "sxtah%?\\t%0, %2, %1"
3777 [(set (match_operand:SI 0 "s_register_operand" "")
3778 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3779 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3780 "TARGET_ARM && (!arm_arch4)"
3781 [(set (match_dup 2) (match_dup 1))
3782 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
3784 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3790 [(set (match_operand:SI 0 "s_register_operand" "")
3791 (match_operator:SI 3 "shiftable_operator"
3792 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3793 (match_operand:SI 4 "s_register_operand" "")]))
3794 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3795 "TARGET_ARM && (!arm_arch4)"
3796 [(set (match_dup 2) (match_dup 1))
3799 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3800 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3805 (define_expand "extendqihi2"
3807 (ashift:SI (match_operand:QI 1 "general_operand" "")
3809 (set (match_operand:HI 0 "s_register_operand" "")
3810 (ashiftrt:SI (match_dup 2)
3815 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
3817 emit_insn (gen_rtx_SET (VOIDmode,
3819 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
3822 if (!s_register_operand (operands[1], QImode))
3823 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3824 operands[0] = gen_lowpart (SImode, operands[0]);
3825 operands[1] = gen_lowpart (SImode, operands[1]);
3826 operands[2] = gen_reg_rtx (SImode);
3830 (define_insn "*extendqihi_insn"
3831 [(set (match_operand:HI 0 "s_register_operand" "=r")
3832 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
3833 "TARGET_ARM && arm_arch4"
3835 [(set_attr "type" "load_byte")
3836 (set_attr "predicable" "yes")
3837 (set_attr "pool_range" "256")
3838 (set_attr "neg_pool_range" "244")]
3841 (define_expand "extendqisi2"
3843 (ashift:SI (match_operand:QI 1 "general_operand" "")
3845 (set (match_operand:SI 0 "s_register_operand" "")
3846 (ashiftrt:SI (match_dup 2)
3851 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3853 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3854 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3858 if (!s_register_operand (operands[1], QImode))
3859 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3863 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3864 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3868 operands[1] = gen_lowpart (SImode, operands[1]);
3869 operands[2] = gen_reg_rtx (SImode);
3873 (define_insn "*arm_extendqisi"
3874 [(set (match_operand:SI 0 "s_register_operand" "=r")
3875 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
3876 "TARGET_ARM && arm_arch4 && !arm_arch6"
3878 [(set_attr "type" "load_byte")
3879 (set_attr "predicable" "yes")
3880 (set_attr "pool_range" "256")
3881 (set_attr "neg_pool_range" "244")]
3884 (define_insn "*arm_extendqisi_v6"
3885 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3886 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
3887 "TARGET_ARM && arm_arch6"
3891 [(set_attr "type" "alu_shift,load_byte")
3892 (set_attr "predicable" "yes")
3893 (set_attr "pool_range" "*,256")
3894 (set_attr "neg_pool_range" "*,244")]
3897 (define_insn "*arm_extendqisi2addsi"
3898 [(set (match_operand:SI 0 "s_register_operand" "=r")
3899 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3900 (match_operand:SI 2 "s_register_operand" "r")))]
3901 "TARGET_ARM && arm_arch6"
3902 "sxtab%?\\t%0, %2, %1"
3903 [(set_attr "type" "alu_shift")
3904 (set_attr "predicable" "yes")]
3907 (define_insn "*thumb_extendqisi2"
3908 [(set (match_operand:SI 0 "register_operand" "=l,l")
3909 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
3910 "TARGET_THUMB && !arm_arch6"
3914 rtx mem = XEXP (operands[1], 0);
3916 if (GET_CODE (mem) == CONST)
3917 mem = XEXP (mem, 0);
3919 if (GET_CODE (mem) == LABEL_REF)
3920 return \"ldr\\t%0, %1\";
3922 if (GET_CODE (mem) == PLUS
3923 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3924 return \"ldr\\t%0, %1\";
3926 if (which_alternative == 0)
3927 return \"ldrsb\\t%0, %1\";
3929 ops[0] = operands[0];
3931 if (GET_CODE (mem) == PLUS)
3933 rtx a = XEXP (mem, 0);
3934 rtx b = XEXP (mem, 1);
3939 if (GET_CODE (a) == REG)
3941 if (GET_CODE (b) == REG)
3942 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3943 else if (REGNO (a) == REGNO (ops[0]))
3945 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3946 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3947 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3950 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3952 else if (GET_CODE (b) != REG)
3956 if (REGNO (b) == REGNO (ops[0]))
3958 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3959 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3960 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3963 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3966 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3968 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3969 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3970 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3975 ops[2] = const0_rtx;
3977 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3981 [(set_attr "length" "2,6")
3982 (set_attr "type" "load_byte,load_byte")
3983 (set_attr "pool_range" "32,32")]
3986 (define_insn "*thumb_extendqisi2_v6"
3987 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
3988 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
3989 "TARGET_THUMB && arm_arch6"
3995 if (which_alternative == 0)
3996 return \"sxtb\\t%0, %1\";
3998 mem = XEXP (operands[1], 0);
4000 if (GET_CODE (mem) == CONST)
4001 mem = XEXP (mem, 0);
4003 if (GET_CODE (mem) == LABEL_REF)
4004 return \"ldr\\t%0, %1\";
4006 if (GET_CODE (mem) == PLUS
4007 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
4008 return \"ldr\\t%0, %1\";
4010 if (which_alternative == 0)
4011 return \"ldrsb\\t%0, %1\";
4013 ops[0] = operands[0];
4015 if (GET_CODE (mem) == PLUS)
4017 rtx a = XEXP (mem, 0);
4018 rtx b = XEXP (mem, 1);
4023 if (GET_CODE (a) == REG)
4025 if (GET_CODE (b) == REG)
4026 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
4027 else if (REGNO (a) == REGNO (ops[0]))
4029 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
4030 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4033 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4035 else if (GET_CODE (b) != REG)
4039 if (REGNO (b) == REGNO (ops[0]))
4041 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
4042 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4045 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4048 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
4050 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
4051 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4056 ops[2] = const0_rtx;
4058 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4062 [(set_attr "length" "2,2,4")
4063 (set_attr "type" "alu_shift,load_byte,load_byte")
4064 (set_attr "pool_range" "*,32,32")]
4067 (define_expand "extendsfdf2"
4068 [(set (match_operand:DF 0 "s_register_operand" "")
4069 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
4070 "TARGET_ARM && TARGET_HARD_FLOAT"
4074 ;; Move insns (including loads and stores)
4076 ;; XXX Just some ideas about movti.
4077 ;; I don't think these are a good idea on the arm, there just aren't enough
4079 ;;(define_expand "loadti"
4080 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4081 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4084 ;;(define_expand "storeti"
4085 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4086 ;; (match_operand:TI 1 "s_register_operand" ""))]
4089 ;;(define_expand "movti"
4090 ;; [(set (match_operand:TI 0 "general_operand" "")
4091 ;; (match_operand:TI 1 "general_operand" ""))]
4097 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4098 ;; operands[1] = copy_to_reg (operands[1]);
4099 ;; if (GET_CODE (operands[0]) == MEM)
4100 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4101 ;; else if (GET_CODE (operands[1]) == MEM)
4102 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4106 ;; emit_insn (insn);
4110 ;; Recognize garbage generated above.
4113 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4114 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4118 ;; register mem = (which_alternative < 3);
4119 ;; register const char *template;
4121 ;; operands[mem] = XEXP (operands[mem], 0);
4122 ;; switch (which_alternative)
4124 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4125 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4126 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4127 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4128 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4129 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4131 ;; output_asm_insn (template, operands);
4135 (define_expand "movdi"
4136 [(set (match_operand:DI 0 "general_operand" "")
4137 (match_operand:DI 1 "general_operand" ""))]
4142 if (!no_new_pseudos)
4144 if (GET_CODE (operands[0]) != REG)
4145 operands[1] = force_reg (DImode, operands[1]);
4151 (define_insn "*arm_movdi"
4152 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
4153 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
4155 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4158 switch (which_alternative)
4165 return output_move_double (operands);
4168 [(set_attr "length" "8,12,16,8,8")
4169 (set_attr "type" "*,*,*,load2,store2")
4170 (set_attr "pool_range" "*,*,*,1020,*")
4171 (set_attr "neg_pool_range" "*,*,*,1008,*")]
4175 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4176 (match_operand:ANY64 1 "const_double_operand" ""))]
4179 && (arm_const_double_inline_cost (operands[1])
4180 <= ((optimize_size || arm_ld_sched) ? 3 : 4))"
4183 arm_split_constant (SET, SImode, curr_insn,
4184 INTVAL (gen_lowpart (SImode, operands[1])),
4185 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
4186 arm_split_constant (SET, SImode, curr_insn,
4187 INTVAL (gen_highpart_mode (SImode,
4188 GET_MODE (operands[0]),
4190 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
4195 ; If optimizing for size, or if we have load delay slots, then
4196 ; we want to split the constant into two separate operations.
4197 ; In both cases this may split a trivial part into a single data op
4198 ; leaving a single complex constant to load. We can also get longer
4199 ; offsets in a LDR which means we get better chances of sharing the pool
4200 ; entries. Finally, we can normally do a better job of scheduling
4201 ; LDR instructions than we can with LDM.
4202 ; This pattern will only match if the one above did not.
4204 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4205 (match_operand:ANY64 1 "const_double_operand" ""))]
4206 "TARGET_ARM && reload_completed
4207 && arm_const_double_by_parts (operands[1])"
4208 [(set (match_dup 0) (match_dup 1))
4209 (set (match_dup 2) (match_dup 3))]
4211 operands[2] = gen_highpart (SImode, operands[0]);
4212 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
4214 operands[0] = gen_lowpart (SImode, operands[0]);
4215 operands[1] = gen_lowpart (SImode, operands[1]);
4220 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
4221 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
4222 "TARGET_EITHER && reload_completed"
4223 [(set (match_dup 0) (match_dup 1))
4224 (set (match_dup 2) (match_dup 3))]
4226 operands[2] = gen_highpart (SImode, operands[0]);
4227 operands[3] = gen_highpart (SImode, operands[1]);
4228 operands[0] = gen_lowpart (SImode, operands[0]);
4229 operands[1] = gen_lowpart (SImode, operands[1]);
4231 /* Handle a partial overlap. */
4232 if (rtx_equal_p (operands[0], operands[3]))
4234 rtx tmp0 = operands[0];
4235 rtx tmp1 = operands[1];
4237 operands[0] = operands[2];
4238 operands[1] = operands[3];
4245 ;; We can't actually do base+index doubleword loads if the index and
4246 ;; destination overlap. Split here so that we at least have chance to
4249 [(set (match_operand:DI 0 "s_register_operand" "")
4250 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
4251 (match_operand:SI 2 "s_register_operand" ""))))]
4253 && reg_overlap_mentioned_p (operands[0], operands[1])
4254 && reg_overlap_mentioned_p (operands[0], operands[2])"
4256 (plus:SI (match_dup 1)
4259 (mem:DI (match_dup 4)))]
4261 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
4265 ;;; ??? This should have alternatives for constants.
4266 ;;; ??? This was originally identical to the movdf_insn pattern.
4267 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4268 ;;; thumb_reorg with a memory reference.
4269 (define_insn "*thumb_movdi_insn"
4270 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4271 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4273 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4274 && ( register_operand (operands[0], DImode)
4275 || register_operand (operands[1], DImode))"
4278 switch (which_alternative)
4282 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4283 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4284 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4286 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4288 operands[1] = GEN_INT (- INTVAL (operands[1]));
4289 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4291 return \"ldmia\\t%1, {%0, %H0}\";
4293 return \"stmia\\t%0, {%1, %H1}\";
4295 return thumb_load_double_from_address (operands);
4297 operands[2] = gen_rtx_MEM (SImode,
4298 plus_constant (XEXP (operands[0], 0), 4));
4299 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4302 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4303 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4304 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4307 [(set_attr "length" "4,4,6,2,2,6,4,4")
4308 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4309 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4312 (define_expand "movsi"
4313 [(set (match_operand:SI 0 "general_operand" "")
4314 (match_operand:SI 1 "general_operand" ""))]
4319 /* Everything except mem = const or mem = mem can be done easily. */
4320 if (GET_CODE (operands[0]) == MEM)
4321 operands[1] = force_reg (SImode, operands[1]);
4322 if (arm_general_register_operand (operands[0], SImode)
4323 && GET_CODE (operands[1]) == CONST_INT
4324 && !(const_ok_for_arm (INTVAL (operands[1]))
4325 || const_ok_for_arm (~INTVAL (operands[1]))))
4327 arm_split_constant (SET, SImode, NULL_RTX,
4328 INTVAL (operands[1]), operands[0], NULL_RTX,
4329 optimize && !no_new_pseudos);
4333 else /* TARGET_THUMB.... */
4335 if (!no_new_pseudos)
4337 if (GET_CODE (operands[0]) != REG)
4338 operands[1] = force_reg (SImode, operands[1]);
4343 && (CONSTANT_P (operands[1])
4344 || symbol_mentioned_p (operands[1])
4345 || label_mentioned_p (operands[1])))
4346 operands[1] = legitimize_pic_address (operands[1], SImode,
4347 (no_new_pseudos ? operands[0] : 0));
4351 (define_insn "*arm_movsi_insn"
4352 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4353 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4354 "TARGET_ARM && ! TARGET_IWMMXT
4355 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4356 && ( register_operand (operands[0], SImode)
4357 || register_operand (operands[1], SImode))"
4363 [(set_attr "type" "*,*,load1,store1")
4364 (set_attr "predicable" "yes")
4365 (set_attr "pool_range" "*,*,4096,*")
4366 (set_attr "neg_pool_range" "*,*,4084,*")]
4370 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4371 (match_operand:SI 1 "const_int_operand" ""))]
4373 && (!(const_ok_for_arm (INTVAL (operands[1]))
4374 || const_ok_for_arm (~INTVAL (operands[1]))))"
4375 [(clobber (const_int 0))]
4377 arm_split_constant (SET, SImode, NULL_RTX,
4378 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4383 (define_insn "*thumb_movsi_insn"
4384 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4385 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4387 && ( register_operand (operands[0], SImode)
4388 || register_operand (operands[1], SImode))"
4399 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4400 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4401 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4405 [(set (match_operand:SI 0 "register_operand" "")
4406 (match_operand:SI 1 "const_int_operand" ""))]
4407 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4408 [(set (match_dup 0) (match_dup 1))
4409 (set (match_dup 0) (neg:SI (match_dup 0)))]
4410 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4414 [(set (match_operand:SI 0 "register_operand" "")
4415 (match_operand:SI 1 "const_int_operand" ""))]
4416 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4417 [(set (match_dup 0) (match_dup 1))
4418 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4421 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4422 unsigned HOST_WIDE_INT mask = 0xff;
4425 for (i = 0; i < 25; i++)
4426 if ((val & (mask << i)) == val)
4429 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4433 operands[1] = GEN_INT (val >> i);
4434 operands[2] = GEN_INT (i);
4438 ;; When generating pic, we need to load the symbol offset into a register.
4439 ;; So that the optimizer does not confuse this with a normal symbol load
4440 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4441 ;; since that is the only type of relocation we can use.
4443 ;; The rather odd constraints on the following are to force reload to leave
4444 ;; the insn alone, and to force the minipool generation pass to then move
4445 ;; the GOT symbol to memory.
4447 (define_insn "pic_load_addr_arm"
4448 [(set (match_operand:SI 0 "s_register_operand" "=r")
4449 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4450 "TARGET_ARM && flag_pic"
4452 [(set_attr "type" "load1")
4453 (set (attr "pool_range") (const_int 4096))
4454 (set (attr "neg_pool_range") (const_int 4084))]
4457 (define_insn "pic_load_addr_thumb"
4458 [(set (match_operand:SI 0 "s_register_operand" "=l")
4459 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4460 "TARGET_THUMB && flag_pic"
4462 [(set_attr "type" "load1")
4463 (set (attr "pool_range") (const_int 1024))]
4466 ;; This variant is used for AOF assembly, since it needs to mention the
4467 ;; pic register in the rtl.
4468 (define_expand "pic_load_addr_based"
4469 [(set (match_operand:SI 0 "s_register_operand" "")
4470 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4471 "TARGET_ARM && flag_pic"
4472 "operands[2] = pic_offset_table_rtx;"
4475 (define_insn "*pic_load_addr_based_insn"
4476 [(set (match_operand:SI 0 "s_register_operand" "=r")
4477 (unspec:SI [(match_operand 1 "" "")
4478 (match_operand 2 "s_register_operand" "r")]
4480 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4482 #ifdef AOF_ASSEMBLER
4483 operands[1] = aof_pic_entry (operands[1]);
4485 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4488 [(set_attr "type" "load1")
4489 (set (attr "pool_range")
4490 (if_then_else (eq_attr "is_thumb" "yes")
4493 (set (attr "neg_pool_range")
4494 (if_then_else (eq_attr "is_thumb" "yes")
4499 (define_insn "pic_add_dot_plus_four"
4500 [(set (match_operand:SI 0 "register_operand" "+r")
4501 (unspec:SI [(plus:SI (match_dup 0)
4502 (const (plus:SI (pc) (const_int 4))))]
4504 (use (label_ref (match_operand 1 "" "")))]
4505 "TARGET_THUMB && flag_pic"
4507 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4508 CODE_LABEL_NUMBER (operands[1]));
4509 return \"add\\t%0, %|pc\";
4511 [(set_attr "length" "2")]
4514 (define_insn "pic_add_dot_plus_eight"
4515 [(set (match_operand:SI 0 "register_operand" "+r")
4516 (unspec:SI [(plus:SI (match_dup 0)
4517 (const (plus:SI (pc) (const_int 8))))]
4519 (use (label_ref (match_operand 1 "" "")))]
4520 "TARGET_ARM && flag_pic"
4522 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4523 CODE_LABEL_NUMBER (operands[1]));
4524 return \"add%?\\t%0, %|pc, %0\";
4526 [(set_attr "predicable" "yes")]
4529 (define_expand "builtin_setjmp_receiver"
4530 [(label_ref (match_operand 0 "" ""))]
4534 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
4536 arm_load_pic_register (3);
4540 ;; If copying one reg to another we can set the condition codes according to
4541 ;; its value. Such a move is common after a return from subroutine and the
4542 ;; result is being tested against zero.
4544 (define_insn "*movsi_compare0"
4545 [(set (reg:CC CC_REGNUM)
4546 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4548 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4553 sub%?s\\t%0, %1, #0"
4554 [(set_attr "conds" "set")]
4557 ;; Subroutine to store a half word from a register into memory.
4558 ;; Operand 0 is the source register (HImode)
4559 ;; Operand 1 is the destination address in a register (SImode)
4561 ;; In both this routine and the next, we must be careful not to spill
4562 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4563 ;; can generate unrecognizable rtl.
4565 (define_expand "storehi"
4566 [;; store the low byte
4567 (set (match_operand 1 "" "") (match_dup 3))
4568 ;; extract the high byte
4570 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4571 ;; store the high byte
4572 (set (match_dup 4) (match_dup 5))]
4576 rtx op1 = operands[1];
4577 rtx addr = XEXP (op1, 0);
4578 enum rtx_code code = GET_CODE (addr);
4580 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4582 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4584 operands[4] = adjust_address (op1, QImode, 1);
4585 operands[1] = adjust_address (operands[1], QImode, 0);
4586 operands[3] = gen_lowpart (QImode, operands[0]);
4587 operands[0] = gen_lowpart (SImode, operands[0]);
4588 operands[2] = gen_reg_rtx (SImode);
4589 operands[5] = gen_lowpart (QImode, operands[2]);
4593 (define_expand "storehi_bigend"
4594 [(set (match_dup 4) (match_dup 3))
4596 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4597 (set (match_operand 1 "" "") (match_dup 5))]
4601 rtx op1 = operands[1];
4602 rtx addr = XEXP (op1, 0);
4603 enum rtx_code code = GET_CODE (addr);
4605 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4607 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4609 operands[4] = adjust_address (op1, QImode, 1);
4610 operands[1] = adjust_address (operands[1], QImode, 0);
4611 operands[3] = gen_lowpart (QImode, operands[0]);
4612 operands[0] = gen_lowpart (SImode, operands[0]);
4613 operands[2] = gen_reg_rtx (SImode);
4614 operands[5] = gen_lowpart (QImode, operands[2]);
4618 ;; Subroutine to store a half word integer constant into memory.
4619 (define_expand "storeinthi"
4620 [(set (match_operand 0 "" "")
4621 (match_operand 1 "" ""))
4622 (set (match_dup 3) (match_dup 2))]
4626 HOST_WIDE_INT value = INTVAL (operands[1]);
4627 rtx addr = XEXP (operands[0], 0);
4628 rtx op0 = operands[0];
4629 enum rtx_code code = GET_CODE (addr);
4631 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4633 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4635 operands[1] = gen_reg_rtx (SImode);
4636 if (BYTES_BIG_ENDIAN)
4638 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4639 if ((value & 255) == ((value >> 8) & 255))
4640 operands[2] = operands[1];
4643 operands[2] = gen_reg_rtx (SImode);
4644 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4649 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4650 if ((value & 255) == ((value >> 8) & 255))
4651 operands[2] = operands[1];
4654 operands[2] = gen_reg_rtx (SImode);
4655 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4659 operands[3] = adjust_address (op0, QImode, 1);
4660 operands[0] = adjust_address (operands[0], QImode, 0);
4661 operands[2] = gen_lowpart (QImode, operands[2]);
4662 operands[1] = gen_lowpart (QImode, operands[1]);
4666 (define_expand "storehi_single_op"
4667 [(set (match_operand:HI 0 "memory_operand" "")
4668 (match_operand:HI 1 "general_operand" ""))]
4669 "TARGET_ARM && arm_arch4"
4671 if (!s_register_operand (operands[1], HImode))
4672 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4676 (define_expand "movhi"
4677 [(set (match_operand:HI 0 "general_operand" "")
4678 (match_operand:HI 1 "general_operand" ""))]
4683 if (!no_new_pseudos)
4685 if (GET_CODE (operands[0]) == MEM)
4689 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4692 if (GET_CODE (operands[1]) == CONST_INT)
4693 emit_insn (gen_storeinthi (operands[0], operands[1]));
4696 if (GET_CODE (operands[1]) == MEM)
4697 operands[1] = force_reg (HImode, operands[1]);
4698 if (BYTES_BIG_ENDIAN)
4699 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4701 emit_insn (gen_storehi (operands[1], operands[0]));
4705 /* Sign extend a constant, and keep it in an SImode reg. */
4706 else if (GET_CODE (operands[1]) == CONST_INT)
4708 rtx reg = gen_reg_rtx (SImode);
4709 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4711 /* If the constant is already valid, leave it alone. */
4712 if (!const_ok_for_arm (val))
4714 /* If setting all the top bits will make the constant
4715 loadable in a single instruction, then set them.
4716 Otherwise, sign extend the number. */
4718 if (const_ok_for_arm (~(val | ~0xffff)))
4720 else if (val & 0x8000)
4724 emit_insn (gen_movsi (reg, GEN_INT (val)));
4725 operands[1] = gen_lowpart (HImode, reg);
4727 else if (arm_arch4 && optimize && !no_new_pseudos
4728 && GET_CODE (operands[1]) == MEM)
4730 rtx reg = gen_reg_rtx (SImode);
4732 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4733 operands[1] = gen_lowpart (HImode, reg);
4735 else if (!arm_arch4)
4737 if (GET_CODE (operands[1]) == MEM)
4740 rtx offset = const0_rtx;
4741 rtx reg = gen_reg_rtx (SImode);
4743 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4744 || (GET_CODE (base) == PLUS
4745 && (GET_CODE (offset = XEXP (base, 1))
4747 && ((INTVAL(offset) & 1) != 1)
4748 && GET_CODE (base = XEXP (base, 0)) == REG))
4749 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4751 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4754 new = gen_rtx_MEM (SImode,
4755 plus_constant (base, new_offset));
4756 MEM_COPY_ATTRIBUTES (new, operands[1]);
4757 emit_insn (gen_movsi (reg, new));
4758 if (((INTVAL (offset) & 2) != 0)
4759 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4761 rtx reg2 = gen_reg_rtx (SImode);
4763 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
4768 emit_insn (gen_movhi_bytes (reg, operands[1]));
4770 operands[1] = gen_lowpart (HImode, reg);
4774 /* Handle loading a large integer during reload. */
4775 else if (GET_CODE (operands[1]) == CONST_INT
4776 && !const_ok_for_arm (INTVAL (operands[1]))
4777 && !const_ok_for_arm (~INTVAL (operands[1])))
4779 /* Writing a constant to memory needs a scratch, which should
4780 be handled with SECONDARY_RELOADs. */
4781 if (GET_CODE (operands[0]) != REG)
4784 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4785 emit_insn (gen_movsi (operands[0], operands[1]));
4789 else /* TARGET_THUMB */
4791 if (!no_new_pseudos)
4793 if (GET_CODE (operands[0]) != REG)
4794 operands[1] = force_reg (HImode, operands[1]);
4796 /* ??? We shouldn't really get invalid addresses here, but this can
4797 happen if we are passed a SP (never OK for HImode/QImode) or
4798 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4799 HImode/QImode) relative address. */
4800 /* ??? This should perhaps be fixed elsewhere, for instance, in
4801 fixup_stack_1, by checking for other kinds of invalid addresses,
4802 e.g. a bare reference to a virtual register. This may confuse the
4803 alpha though, which must handle this case differently. */
4804 if (GET_CODE (operands[0]) == MEM
4805 && !memory_address_p (GET_MODE (operands[0]),
4806 XEXP (operands[0], 0)))
4808 = replace_equiv_address (operands[0],
4809 copy_to_reg (XEXP (operands[0], 0)));
4811 if (GET_CODE (operands[1]) == MEM
4812 && !memory_address_p (GET_MODE (operands[1]),
4813 XEXP (operands[1], 0)))
4815 = replace_equiv_address (operands[1],
4816 copy_to_reg (XEXP (operands[1], 0)));
4818 /* Handle loading a large integer during reload. */
4819 else if (GET_CODE (operands[1]) == CONST_INT
4820 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4822 /* Writing a constant to memory needs a scratch, which should
4823 be handled with SECONDARY_RELOADs. */
4824 if (GET_CODE (operands[0]) != REG)
4827 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4828 emit_insn (gen_movsi (operands[0], operands[1]));
4835 (define_insn "*thumb_movhi_insn"
4836 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4837 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4839 && ( register_operand (operands[0], HImode)
4840 || register_operand (operands[1], HImode))"
4842 switch (which_alternative)
4844 case 0: return \"add %0, %1, #0\";
4845 case 2: return \"strh %1, %0\";
4846 case 3: return \"mov %0, %1\";
4847 case 4: return \"mov %0, %1\";
4848 case 5: return \"mov %0, %1\";
4851 /* The stack pointer can end up being taken as an index register.
4852 Catch this case here and deal with it. */
4853 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4854 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4855 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4858 ops[0] = operands[0];
4859 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4861 output_asm_insn (\"mov %0, %1\", ops);
4863 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4866 return \"ldrh %0, %1\";
4868 [(set_attr "length" "2,4,2,2,2,2")
4869 (set_attr "type" "*,load1,store1,*,*,*")]
4873 (define_expand "movhi_bytes"
4874 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4876 (zero_extend:SI (match_dup 6)))
4877 (set (match_operand:SI 0 "" "")
4878 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4883 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4885 mem1 = gen_rtx_MEM (QImode, addr);
4886 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4887 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4888 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4889 operands[0] = gen_lowpart (SImode, operands[0]);
4891 operands[2] = gen_reg_rtx (SImode);
4892 operands[3] = gen_reg_rtx (SImode);
4895 if (BYTES_BIG_ENDIAN)
4897 operands[4] = operands[2];
4898 operands[5] = operands[3];
4902 operands[4] = operands[3];
4903 operands[5] = operands[2];
4908 (define_expand "movhi_bigend"
4910 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4913 (ashiftrt:SI (match_dup 2) (const_int 16)))
4914 (set (match_operand:HI 0 "s_register_operand" "")
4918 operands[2] = gen_reg_rtx (SImode);
4919 operands[3] = gen_reg_rtx (SImode);
4920 operands[4] = gen_lowpart (HImode, operands[3]);
4924 ;; Pattern to recognize insn generated default case above
4925 (define_insn "*movhi_insn_arch4"
4926 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4927 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4930 && (GET_CODE (operands[1]) != CONST_INT
4931 || const_ok_for_arm (INTVAL (operands[1]))
4932 || const_ok_for_arm (~INTVAL (operands[1])))"
4934 mov%?\\t%0, %1\\t%@ movhi
4935 mvn%?\\t%0, #%B1\\t%@ movhi
4936 str%?h\\t%1, %0\\t%@ movhi
4937 ldr%?h\\t%0, %1\\t%@ movhi"
4938 [(set_attr "type" "*,*,store1,load1")
4939 (set_attr "predicable" "yes")
4940 (set_attr "pool_range" "*,*,*,256")
4941 (set_attr "neg_pool_range" "*,*,*,244")]
4944 (define_insn "*movhi_bytes"
4945 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4946 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4949 mov%?\\t%0, %1\\t%@ movhi
4950 mvn%?\\t%0, #%B1\\t%@ movhi"
4951 [(set_attr "predicable" "yes")]
4954 (define_insn "thumb_movhi_clobber"
4955 [(set (match_operand:HI 0 "memory_operand" "=m")
4956 (match_operand:HI 1 "register_operand" "l"))
4957 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4963 ;; We use a DImode scratch because we may occasionally need an additional
4964 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4965 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4966 (define_expand "reload_outhi"
4967 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4968 (match_operand:HI 1 "s_register_operand" "r")
4969 (match_operand:DI 2 "s_register_operand" "=&l")])]
4972 arm_reload_out_hi (operands);
4974 thumb_reload_out_hi (operands);
4979 (define_expand "reload_inhi"
4980 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4981 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4982 (match_operand:DI 2 "s_register_operand" "=&r")])]
4986 arm_reload_in_hi (operands);
4988 thumb_reload_out_hi (operands);
4992 (define_expand "movqi"
4993 [(set (match_operand:QI 0 "general_operand" "")
4994 (match_operand:QI 1 "general_operand" ""))]
4999 /* Everything except mem = const or mem = mem can be done easily */
5001 if (!no_new_pseudos)
5003 if (GET_CODE (operands[1]) == CONST_INT)
5005 rtx reg = gen_reg_rtx (SImode);
5007 emit_insn (gen_movsi (reg, operands[1]));
5008 operands[1] = gen_lowpart (QImode, reg);
5010 if (GET_CODE (operands[1]) == MEM && optimize > 0)
5012 rtx reg = gen_reg_rtx (SImode);
5014 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
5015 operands[1] = gen_lowpart (QImode, reg);
5017 if (GET_CODE (operands[0]) == MEM)
5018 operands[1] = force_reg (QImode, operands[1]);
5021 else /* TARGET_THUMB */
5023 if (!no_new_pseudos)
5025 if (GET_CODE (operands[0]) != REG)
5026 operands[1] = force_reg (QImode, operands[1]);
5028 /* ??? We shouldn't really get invalid addresses here, but this can
5029 happen if we are passed a SP (never OK for HImode/QImode) or
5030 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
5031 HImode/QImode) relative address. */
5032 /* ??? This should perhaps be fixed elsewhere, for instance, in
5033 fixup_stack_1, by checking for other kinds of invalid addresses,
5034 e.g. a bare reference to a virtual register. This may confuse the
5035 alpha though, which must handle this case differently. */
5036 if (GET_CODE (operands[0]) == MEM
5037 && !memory_address_p (GET_MODE (operands[0]),
5038 XEXP (operands[0], 0)))
5040 = replace_equiv_address (operands[0],
5041 copy_to_reg (XEXP (operands[0], 0)));
5042 if (GET_CODE (operands[1]) == MEM
5043 && !memory_address_p (GET_MODE (operands[1]),
5044 XEXP (operands[1], 0)))
5046 = replace_equiv_address (operands[1],
5047 copy_to_reg (XEXP (operands[1], 0)));
5049 /* Handle loading a large integer during reload. */
5050 else if (GET_CODE (operands[1]) == CONST_INT
5051 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
5053 /* Writing a constant to memory needs a scratch, which should
5054 be handled with SECONDARY_RELOADs. */
5055 if (GET_CODE (operands[0]) != REG)
5058 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5059 emit_insn (gen_movsi (operands[0], operands[1]));
5067 (define_insn "*arm_movqi_insn"
5068 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5069 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
5071 && ( register_operand (operands[0], QImode)
5072 || register_operand (operands[1], QImode))"
5078 [(set_attr "type" "*,*,load1,store1")
5079 (set_attr "predicable" "yes")]
5082 (define_insn "*thumb_movqi_insn"
5083 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5084 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5086 && ( register_operand (operands[0], QImode)
5087 || register_operand (operands[1], QImode))"
5095 [(set_attr "length" "2")
5096 (set_attr "type" "*,load1,store1,*,*,*")
5097 (set_attr "pool_range" "*,32,*,*,*,*")]
5100 (define_expand "movsf"
5101 [(set (match_operand:SF 0 "general_operand" "")
5102 (match_operand:SF 1 "general_operand" ""))]
5107 if (GET_CODE (operands[0]) == MEM)
5108 operands[1] = force_reg (SFmode, operands[1]);
5110 else /* TARGET_THUMB */
5112 if (!no_new_pseudos)
5114 if (GET_CODE (operands[0]) != REG)
5115 operands[1] = force_reg (SFmode, operands[1]);
5122 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5123 (match_operand:SF 1 "immediate_operand" ""))]
5125 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5127 && GET_CODE (operands[1]) == CONST_DOUBLE"
5128 [(set (match_dup 2) (match_dup 3))]
5130 operands[2] = gen_lowpart (SImode, operands[0]);
5131 operands[3] = gen_lowpart (SImode, operands[1]);
5132 if (operands[2] == 0 || operands[3] == 0)
5137 (define_insn "*arm_movsf_soft_insn"
5138 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5139 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5141 && TARGET_SOFT_FLOAT
5142 && (GET_CODE (operands[0]) != MEM
5143 || register_operand (operands[1], SFmode))"
5146 ldr%?\\t%0, %1\\t%@ float
5147 str%?\\t%1, %0\\t%@ float"
5148 [(set_attr "length" "4,4,4")
5149 (set_attr "predicable" "yes")
5150 (set_attr "type" "*,load1,store1")
5151 (set_attr "pool_range" "*,4096,*")
5152 (set_attr "neg_pool_range" "*,4084,*")]
5155 ;;; ??? This should have alternatives for constants.
5156 (define_insn "*thumb_movsf_insn"
5157 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5158 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5160 && ( register_operand (operands[0], SFmode)
5161 || register_operand (operands[1], SFmode))"
5170 [(set_attr "length" "2")
5171 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5172 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5175 (define_expand "movdf"
5176 [(set (match_operand:DF 0 "general_operand" "")
5177 (match_operand:DF 1 "general_operand" ""))]
5182 if (GET_CODE (operands[0]) == MEM)
5183 operands[1] = force_reg (DFmode, operands[1]);
5185 else /* TARGET_THUMB */
5187 if (!no_new_pseudos)
5189 if (GET_CODE (operands[0]) != REG)
5190 operands[1] = force_reg (DFmode, operands[1]);
5196 ;; Reloading a df mode value stored in integer regs to memory can require a
5198 (define_expand "reload_outdf"
5199 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5200 (match_operand:DF 1 "s_register_operand" "r")
5201 (match_operand:SI 2 "s_register_operand" "=&r")]
5205 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5208 operands[2] = XEXP (operands[0], 0);
5209 else if (code == POST_INC || code == PRE_DEC)
5211 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5212 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5213 emit_insn (gen_movdi (operands[0], operands[1]));
5216 else if (code == PRE_INC)
5218 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5220 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5223 else if (code == POST_DEC)
5224 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5226 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5227 XEXP (XEXP (operands[0], 0), 1)));
5229 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5232 if (code == POST_DEC)
5233 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5239 (define_insn "*movdf_soft_insn"
5240 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
5241 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
5242 "TARGET_ARM && TARGET_SOFT_FLOAT
5245 switch (which_alternative)
5252 return output_move_double (operands);
5255 [(set_attr "length" "8,12,16,8,8")
5256 (set_attr "type" "*,*,*,load2,store2")
5257 (set_attr "pool_range" "1020")
5258 (set_attr "neg_pool_range" "1008")]
5261 ;;; ??? This should have alternatives for constants.
5262 ;;; ??? This was originally identical to the movdi_insn pattern.
5263 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5264 ;;; thumb_reorg with a memory reference.
5265 (define_insn "*thumb_movdf_insn"
5266 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5267 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5269 && ( register_operand (operands[0], DFmode)
5270 || register_operand (operands[1], DFmode))"
5272 switch (which_alternative)
5276 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5277 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5278 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5280 return \"ldmia\\t%1, {%0, %H0}\";
5282 return \"stmia\\t%0, {%1, %H1}\";
5284 return thumb_load_double_from_address (operands);
5286 operands[2] = gen_rtx_MEM (SImode,
5287 plus_constant (XEXP (operands[0], 0), 4));
5288 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5291 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5292 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5293 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5296 [(set_attr "length" "4,2,2,6,4,4")
5297 (set_attr "type" "*,load2,store2,load2,store2,*")
5298 (set_attr "pool_range" "*,*,*,1020,*,*")]
5301 (define_expand "movxf"
5302 [(set (match_operand:XF 0 "general_operand" "")
5303 (match_operand:XF 1 "general_operand" ""))]
5304 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
5306 if (GET_CODE (operands[0]) == MEM)
5307 operands[1] = force_reg (XFmode, operands[1]);
5312 (define_expand "movv2si"
5313 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5314 (match_operand:V2SI 1 "general_operand" ""))]
5315 "TARGET_REALLY_IWMMXT"
5319 (define_expand "movv4hi"
5320 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5321 (match_operand:V4HI 1 "general_operand" ""))]
5322 "TARGET_REALLY_IWMMXT"
5326 (define_expand "movv8qi"
5327 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5328 (match_operand:V8QI 1 "general_operand" ""))]
5329 "TARGET_REALLY_IWMMXT"
5334 ;; load- and store-multiple insns
5335 ;; The arm can load/store any set of registers, provided that they are in
5336 ;; ascending order; but that is beyond GCC so stick with what it knows.
5338 (define_expand "load_multiple"
5339 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5340 (match_operand:SI 1 "" ""))
5341 (use (match_operand:SI 2 "" ""))])]
5344 HOST_WIDE_INT offset = 0;
5346 /* Support only fixed point registers. */
5347 if (GET_CODE (operands[2]) != CONST_INT
5348 || INTVAL (operands[2]) > 14
5349 || INTVAL (operands[2]) < 2
5350 || GET_CODE (operands[1]) != MEM
5351 || GET_CODE (operands[0]) != REG
5352 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5353 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5357 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5358 force_reg (SImode, XEXP (operands[1], 0)),
5359 TRUE, FALSE, operands[1], &offset);
5362 ;; Load multiple with write-back
5364 (define_insn "*ldmsi_postinc4"
5365 [(match_parallel 0 "load_multiple_operation"
5366 [(set (match_operand:SI 1 "s_register_operand" "=r")
5367 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5369 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5370 (mem:SI (match_dup 2)))
5371 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5372 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5373 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5374 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5375 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5376 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5377 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5378 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5379 [(set_attr "type" "load4")
5380 (set_attr "predicable" "yes")]
5383 (define_insn "*ldmsi_postinc4_thumb"
5384 [(match_parallel 0 "load_multiple_operation"
5385 [(set (match_operand:SI 1 "s_register_operand" "=l")
5386 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5388 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5389 (mem:SI (match_dup 2)))
5390 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5391 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5392 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5393 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5394 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5395 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5396 "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
5397 "ldmia\\t%1!, {%3, %4, %5, %6}"
5398 [(set_attr "type" "load4")]
5401 (define_insn "*ldmsi_postinc3"
5402 [(match_parallel 0 "load_multiple_operation"
5403 [(set (match_operand:SI 1 "s_register_operand" "=r")
5404 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5406 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5407 (mem:SI (match_dup 2)))
5408 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5409 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5410 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5411 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5412 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5413 "ldm%?ia\\t%1!, {%3, %4, %5}"
5414 [(set_attr "type" "load3")
5415 (set_attr "predicable" "yes")]
5418 (define_insn "*ldmsi_postinc2"
5419 [(match_parallel 0 "load_multiple_operation"
5420 [(set (match_operand:SI 1 "s_register_operand" "=r")
5421 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5423 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5424 (mem:SI (match_dup 2)))
5425 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5426 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5427 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5428 "ldm%?ia\\t%1!, {%3, %4}"
5429 [(set_attr "type" "load2")
5430 (set_attr "predicable" "yes")]
5433 ;; Ordinary load multiple
5435 (define_insn "*ldmsi4"
5436 [(match_parallel 0 "load_multiple_operation"
5437 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5438 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5439 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5440 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5441 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5442 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5443 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5444 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5445 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5446 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5447 [(set_attr "type" "load4")
5448 (set_attr "predicable" "yes")]
5451 (define_insn "*ldmsi3"
5452 [(match_parallel 0 "load_multiple_operation"
5453 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5454 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5455 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5456 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5457 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5458 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5459 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5460 "ldm%?ia\\t%1, {%2, %3, %4}"
5461 [(set_attr "type" "load3")
5462 (set_attr "predicable" "yes")]
5465 (define_insn "*ldmsi2"
5466 [(match_parallel 0 "load_multiple_operation"
5467 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5468 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5469 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5470 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5471 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5472 "ldm%?ia\\t%1, {%2, %3}"
5473 [(set_attr "type" "load2")
5474 (set_attr "predicable" "yes")]
5477 (define_expand "store_multiple"
5478 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5479 (match_operand:SI 1 "" ""))
5480 (use (match_operand:SI 2 "" ""))])]
5483 HOST_WIDE_INT offset = 0;
5485 /* Support only fixed point registers. */
5486 if (GET_CODE (operands[2]) != CONST_INT
5487 || INTVAL (operands[2]) > 14
5488 || INTVAL (operands[2]) < 2
5489 || GET_CODE (operands[1]) != REG
5490 || GET_CODE (operands[0]) != MEM
5491 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5492 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5496 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5497 force_reg (SImode, XEXP (operands[0], 0)),
5498 TRUE, FALSE, operands[0], &offset);
5501 ;; Store multiple with write-back
5503 (define_insn "*stmsi_postinc4"
5504 [(match_parallel 0 "store_multiple_operation"
5505 [(set (match_operand:SI 1 "s_register_operand" "=r")
5506 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5508 (set (mem:SI (match_dup 2))
5509 (match_operand:SI 3 "arm_hard_register_operand" ""))
5510 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5511 (match_operand:SI 4 "arm_hard_register_operand" ""))
5512 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5513 (match_operand:SI 5 "arm_hard_register_operand" ""))
5514 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5515 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5516 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5517 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5518 [(set_attr "predicable" "yes")
5519 (set_attr "type" "store4")]
5522 (define_insn "*stmsi_postinc4_thumb"
5523 [(match_parallel 0 "store_multiple_operation"
5524 [(set (match_operand:SI 1 "s_register_operand" "=l")
5525 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5527 (set (mem:SI (match_dup 2))
5528 (match_operand:SI 3 "arm_hard_register_operand" ""))
5529 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5530 (match_operand:SI 4 "arm_hard_register_operand" ""))
5531 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5532 (match_operand:SI 5 "arm_hard_register_operand" ""))
5533 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5534 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5535 "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
5536 "stmia\\t%1!, {%3, %4, %5, %6}"
5537 [(set_attr "type" "store4")]
5540 (define_insn "*stmsi_postinc3"
5541 [(match_parallel 0 "store_multiple_operation"
5542 [(set (match_operand:SI 1 "s_register_operand" "=r")
5543 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5545 (set (mem:SI (match_dup 2))
5546 (match_operand:SI 3 "arm_hard_register_operand" ""))
5547 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5548 (match_operand:SI 4 "arm_hard_register_operand" ""))
5549 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5550 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5551 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5552 "stm%?ia\\t%1!, {%3, %4, %5}"
5553 [(set_attr "predicable" "yes")
5554 (set_attr "type" "store3")]
5557 (define_insn "*stmsi_postinc2"
5558 [(match_parallel 0 "store_multiple_operation"
5559 [(set (match_operand:SI 1 "s_register_operand" "=r")
5560 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5562 (set (mem:SI (match_dup 2))
5563 (match_operand:SI 3 "arm_hard_register_operand" ""))
5564 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5565 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5566 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5567 "stm%?ia\\t%1!, {%3, %4}"
5568 [(set_attr "predicable" "yes")
5569 (set_attr "type" "store2")]
5572 ;; Ordinary store multiple
5574 (define_insn "*stmsi4"
5575 [(match_parallel 0 "store_multiple_operation"
5576 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5577 (match_operand:SI 2 "arm_hard_register_operand" ""))
5578 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5579 (match_operand:SI 3 "arm_hard_register_operand" ""))
5580 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5581 (match_operand:SI 4 "arm_hard_register_operand" ""))
5582 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5583 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5584 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5585 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5586 [(set_attr "predicable" "yes")
5587 (set_attr "type" "store4")]
5590 (define_insn "*stmsi3"
5591 [(match_parallel 0 "store_multiple_operation"
5592 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5593 (match_operand:SI 2 "arm_hard_register_operand" ""))
5594 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5595 (match_operand:SI 3 "arm_hard_register_operand" ""))
5596 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5597 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5598 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5599 "stm%?ia\\t%1, {%2, %3, %4}"
5600 [(set_attr "predicable" "yes")
5601 (set_attr "type" "store3")]
5604 (define_insn "*stmsi2"
5605 [(match_parallel 0 "store_multiple_operation"
5606 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5607 (match_operand:SI 2 "arm_hard_register_operand" ""))
5608 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5609 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5610 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5611 "stm%?ia\\t%1, {%2, %3}"
5612 [(set_attr "predicable" "yes")
5613 (set_attr "type" "store2")]
5616 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5617 ;; We could let this apply for blocks of less than this, but it clobbers so
5618 ;; many registers that there is then probably a better way.
5620 (define_expand "movmemqi"
5621 [(match_operand:BLK 0 "general_operand" "")
5622 (match_operand:BLK 1 "general_operand" "")
5623 (match_operand:SI 2 "const_int_operand" "")
5624 (match_operand:SI 3 "const_int_operand" "")]
5629 if (arm_gen_movmemqi (operands))
5633 else /* TARGET_THUMB */
5635 if ( INTVAL (operands[3]) != 4
5636 || INTVAL (operands[2]) > 48)
5639 thumb_expand_movmemqi (operands);
5645 ;; Thumb block-move insns
5647 (define_insn "movmem12b"
5648 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5649 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5650 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5651 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5652 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5653 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5654 (set (match_operand:SI 0 "register_operand" "=l")
5655 (plus:SI (match_dup 2) (const_int 12)))
5656 (set (match_operand:SI 1 "register_operand" "=l")
5657 (plus:SI (match_dup 3) (const_int 12)))
5658 (clobber (match_scratch:SI 4 "=&l"))
5659 (clobber (match_scratch:SI 5 "=&l"))
5660 (clobber (match_scratch:SI 6 "=&l"))]
5662 "* return thumb_output_move_mem_multiple (3, operands);"
5663 [(set_attr "length" "4")
5664 ; This isn't entirely accurate... It loads as well, but in terms of
5665 ; scheduling the following insn it is better to consider it as a store
5666 (set_attr "type" "store3")]
5669 (define_insn "movmem8b"
5670 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5671 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5672 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5673 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5674 (set (match_operand:SI 0 "register_operand" "=l")
5675 (plus:SI (match_dup 2) (const_int 8)))
5676 (set (match_operand:SI 1 "register_operand" "=l")
5677 (plus:SI (match_dup 3) (const_int 8)))
5678 (clobber (match_scratch:SI 4 "=&l"))
5679 (clobber (match_scratch:SI 5 "=&l"))]
5681 "* return thumb_output_move_mem_multiple (2, operands);"
5682 [(set_attr "length" "4")
5683 ; This isn't entirely accurate... It loads as well, but in terms of
5684 ; scheduling the following insn it is better to consider it as a store
5685 (set_attr "type" "store2")]
5690 ;; Compare & branch insns
5691 ;; The range calculations are based as follows:
5692 ;; For forward branches, the address calculation returns the address of
5693 ;; the next instruction. This is 2 beyond the branch instruction.
5694 ;; For backward branches, the address calculation returns the address of
5695 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5696 ;; instruction for the shortest sequence, and 4 before the branch instruction
5697 ;; if we have to jump around an unconditional branch.
5698 ;; To the basic branch range the PC offset must be added (this is +4).
5699 ;; So for forward branches we have
5700 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5701 ;; And for backward branches we have
5702 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5704 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5705 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5707 (define_expand "cbranchsi4"
5708 [(set (pc) (if_then_else
5709 (match_operator 0 "arm_comparison_operator"
5710 [(match_operand:SI 1 "s_register_operand" "")
5711 (match_operand:SI 2 "nonmemory_operand" "")])
5712 (label_ref (match_operand 3 "" ""))
5716 if (thumb_cmpneg_operand (operands[2], SImode))
5718 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5719 operands[3], operands[0]));
5722 if (!thumb_cmp_operand (operands[2], SImode))
5723 operands[2] = force_reg (SImode, operands[2]);
5726 (define_insn "*cbranchsi4_insn"
5727 [(set (pc) (if_then_else
5728 (match_operator 0 "arm_comparison_operator"
5729 [(match_operand:SI 1 "s_register_operand" "l,*h")
5730 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5731 (label_ref (match_operand 3 "" ""))
5735 output_asm_insn (\"cmp\\t%1, %2\", operands);
5737 switch (get_attr_length (insn))
5739 case 4: return \"b%d0\\t%l3\";
5740 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5741 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5744 [(set (attr "far_jump")
5746 (eq_attr "length" "8")
5747 (const_string "yes")
5748 (const_string "no")))
5749 (set (attr "length")
5751 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5752 (le (minus (match_dup 3) (pc)) (const_int 256)))
5755 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5756 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5761 (define_insn "cbranchsi4_scratch"
5762 [(set (pc) (if_then_else
5763 (match_operator 4 "arm_comparison_operator"
5764 [(match_operand:SI 1 "s_register_operand" "l,0")
5765 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5766 (label_ref (match_operand 3 "" ""))
5768 (clobber (match_scratch:SI 0 "=l,l"))]
5771 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5773 switch (get_attr_length (insn))
5775 case 4: return \"b%d4\\t%l3\";
5776 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5777 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5780 [(set (attr "far_jump")
5782 (eq_attr "length" "8")
5783 (const_string "yes")
5784 (const_string "no")))
5785 (set (attr "length")
5787 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5788 (le (minus (match_dup 3) (pc)) (const_int 256)))
5791 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5792 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5796 (define_insn "*movsi_cbranchsi4"
5799 (match_operator 3 "arm_comparison_operator"
5800 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5802 (label_ref (match_operand 2 "" ""))
5804 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5808 if (which_alternative == 0)
5809 output_asm_insn (\"cmp\t%0, #0\", operands);
5810 else if (which_alternative == 1)
5811 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5814 output_asm_insn (\"cmp\t%1, #0\", operands);
5815 if (which_alternative == 2)
5816 output_asm_insn (\"mov\t%0, %1\", operands);
5818 output_asm_insn (\"str\t%1, %0\", operands);
5820 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5822 case 4: return \"b%d3\\t%l2\";
5823 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5824 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5827 [(set (attr "far_jump")
5829 (ior (and (gt (symbol_ref ("which_alternative"))
5831 (eq_attr "length" "8"))
5832 (eq_attr "length" "10"))
5833 (const_string "yes")
5834 (const_string "no")))
5835 (set (attr "length")
5837 (le (symbol_ref ("which_alternative"))
5840 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5841 (le (minus (match_dup 2) (pc)) (const_int 256)))
5844 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5845 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5849 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5850 (le (minus (match_dup 2) (pc)) (const_int 256)))
5853 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5854 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5859 (define_insn "*negated_cbranchsi4"
5862 (match_operator 0 "equality_operator"
5863 [(match_operand:SI 1 "s_register_operand" "l")
5864 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5865 (label_ref (match_operand 3 "" ""))
5869 output_asm_insn (\"cmn\\t%1, %2\", operands);
5870 switch (get_attr_length (insn))
5872 case 4: return \"b%d0\\t%l3\";
5873 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5874 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5877 [(set (attr "far_jump")
5879 (eq_attr "length" "8")
5880 (const_string "yes")
5881 (const_string "no")))
5882 (set (attr "length")
5884 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5885 (le (minus (match_dup 3) (pc)) (const_int 256)))
5888 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5889 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5894 (define_insn "*tbit_cbranch"
5897 (match_operator 0 "equality_operator"
5898 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5900 (match_operand:SI 2 "const_int_operand" "i"))
5902 (label_ref (match_operand 3 "" ""))
5904 (clobber (match_scratch:SI 4 "=l"))]
5909 op[0] = operands[4];
5910 op[1] = operands[1];
5911 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5913 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5914 switch (get_attr_length (insn))
5916 case 4: return \"b%d0\\t%l3\";
5917 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5918 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5921 [(set (attr "far_jump")
5923 (eq_attr "length" "8")
5924 (const_string "yes")
5925 (const_string "no")))
5926 (set (attr "length")
5928 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5929 (le (minus (match_dup 3) (pc)) (const_int 256)))
5932 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5933 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5938 (define_insn "*tstsi3_cbranch"
5941 (match_operator 3 "equality_operator"
5942 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5943 (match_operand:SI 1 "s_register_operand" "l"))
5945 (label_ref (match_operand 2 "" ""))
5950 output_asm_insn (\"tst\\t%0, %1\", operands);
5951 switch (get_attr_length (insn))
5953 case 4: return \"b%d3\\t%l2\";
5954 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5955 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5958 [(set (attr "far_jump")
5960 (eq_attr "length" "8")
5961 (const_string "yes")
5962 (const_string "no")))
5963 (set (attr "length")
5965 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5966 (le (minus (match_dup 2) (pc)) (const_int 256)))
5969 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5970 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5975 (define_insn "*andsi3_cbranch"
5978 (match_operator 5 "equality_operator"
5979 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5980 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5982 (label_ref (match_operand 4 "" ""))
5984 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5985 (and:SI (match_dup 2) (match_dup 3)))
5986 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5990 if (which_alternative == 0)
5991 output_asm_insn (\"and\\t%0, %3\", operands);
5992 else if (which_alternative == 1)
5994 output_asm_insn (\"and\\t%1, %3\", operands);
5995 output_asm_insn (\"mov\\t%0, %1\", operands);
5999 output_asm_insn (\"and\\t%1, %3\", operands);
6000 output_asm_insn (\"str\\t%1, %0\", operands);
6003 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6005 case 4: return \"b%d5\\t%l4\";
6006 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6007 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6010 [(set (attr "far_jump")
6012 (ior (and (eq (symbol_ref ("which_alternative"))
6014 (eq_attr "length" "8"))
6015 (eq_attr "length" "10"))
6016 (const_string "yes")
6017 (const_string "no")))
6018 (set (attr "length")
6020 (eq (symbol_ref ("which_alternative"))
6023 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6024 (le (minus (match_dup 4) (pc)) (const_int 256)))
6027 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6028 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6032 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6033 (le (minus (match_dup 4) (pc)) (const_int 256)))
6036 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6037 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6042 (define_insn "*orrsi3_cbranch_scratch"
6045 (match_operator 4 "equality_operator"
6046 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
6047 (match_operand:SI 2 "s_register_operand" "l"))
6049 (label_ref (match_operand 3 "" ""))
6051 (clobber (match_scratch:SI 0 "=l"))]
6055 output_asm_insn (\"orr\\t%0, %2\", operands);
6056 switch (get_attr_length (insn))
6058 case 4: return \"b%d4\\t%l3\";
6059 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6060 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6063 [(set (attr "far_jump")
6065 (eq_attr "length" "8")
6066 (const_string "yes")
6067 (const_string "no")))
6068 (set (attr "length")
6070 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6071 (le (minus (match_dup 3) (pc)) (const_int 256)))
6074 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6075 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6080 (define_insn "*orrsi3_cbranch"
6083 (match_operator 5 "equality_operator"
6084 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6085 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6087 (label_ref (match_operand 4 "" ""))
6089 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6090 (ior:SI (match_dup 2) (match_dup 3)))
6091 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6095 if (which_alternative == 0)
6096 output_asm_insn (\"orr\\t%0, %3\", operands);
6097 else if (which_alternative == 1)
6099 output_asm_insn (\"orr\\t%1, %3\", operands);
6100 output_asm_insn (\"mov\\t%0, %1\", operands);
6104 output_asm_insn (\"orr\\t%1, %3\", operands);
6105 output_asm_insn (\"str\\t%1, %0\", operands);
6108 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6110 case 4: return \"b%d5\\t%l4\";
6111 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6112 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6115 [(set (attr "far_jump")
6117 (ior (and (eq (symbol_ref ("which_alternative"))
6119 (eq_attr "length" "8"))
6120 (eq_attr "length" "10"))
6121 (const_string "yes")
6122 (const_string "no")))
6123 (set (attr "length")
6125 (eq (symbol_ref ("which_alternative"))
6128 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6129 (le (minus (match_dup 4) (pc)) (const_int 256)))
6132 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6133 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6137 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6138 (le (minus (match_dup 4) (pc)) (const_int 256)))
6141 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6142 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6147 (define_insn "*xorsi3_cbranch_scratch"
6150 (match_operator 4 "equality_operator"
6151 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6152 (match_operand:SI 2 "s_register_operand" "l"))
6154 (label_ref (match_operand 3 "" ""))
6156 (clobber (match_scratch:SI 0 "=l"))]
6160 output_asm_insn (\"eor\\t%0, %2\", operands);
6161 switch (get_attr_length (insn))
6163 case 4: return \"b%d4\\t%l3\";
6164 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6165 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6168 [(set (attr "far_jump")
6170 (eq_attr "length" "8")
6171 (const_string "yes")
6172 (const_string "no")))
6173 (set (attr "length")
6175 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6176 (le (minus (match_dup 3) (pc)) (const_int 256)))
6179 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6180 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6185 (define_insn "*xorsi3_cbranch"
6188 (match_operator 5 "equality_operator"
6189 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6190 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6192 (label_ref (match_operand 4 "" ""))
6194 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6195 (xor:SI (match_dup 2) (match_dup 3)))
6196 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6200 if (which_alternative == 0)
6201 output_asm_insn (\"eor\\t%0, %3\", operands);
6202 else if (which_alternative == 1)
6204 output_asm_insn (\"eor\\t%1, %3\", operands);
6205 output_asm_insn (\"mov\\t%0, %1\", operands);
6209 output_asm_insn (\"eor\\t%1, %3\", operands);
6210 output_asm_insn (\"str\\t%1, %0\", operands);
6213 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6215 case 4: return \"b%d5\\t%l4\";
6216 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6217 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6220 [(set (attr "far_jump")
6222 (ior (and (eq (symbol_ref ("which_alternative"))
6224 (eq_attr "length" "8"))
6225 (eq_attr "length" "10"))
6226 (const_string "yes")
6227 (const_string "no")))
6228 (set (attr "length")
6230 (eq (symbol_ref ("which_alternative"))
6233 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6234 (le (minus (match_dup 4) (pc)) (const_int 256)))
6237 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6238 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6242 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6243 (le (minus (match_dup 4) (pc)) (const_int 256)))
6246 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6247 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6252 (define_insn "*bicsi3_cbranch_scratch"
6255 (match_operator 4 "equality_operator"
6256 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6257 (match_operand:SI 1 "s_register_operand" "0"))
6259 (label_ref (match_operand 3 "" ""))
6261 (clobber (match_scratch:SI 0 "=l"))]
6265 output_asm_insn (\"bic\\t%0, %2\", operands);
6266 switch (get_attr_length (insn))
6268 case 4: return \"b%d4\\t%l3\";
6269 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6270 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6273 [(set (attr "far_jump")
6275 (eq_attr "length" "8")
6276 (const_string "yes")
6277 (const_string "no")))
6278 (set (attr "length")
6280 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6281 (le (minus (match_dup 3) (pc)) (const_int 256)))
6284 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6285 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6290 (define_insn "*bicsi3_cbranch"
6293 (match_operator 5 "equality_operator"
6294 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
6295 (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
6297 (label_ref (match_operand 4 "" ""))
6299 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
6300 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6301 (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
6305 if (which_alternative == 0)
6306 output_asm_insn (\"bic\\t%0, %3\", operands);
6307 else if (which_alternative <= 2)
6309 output_asm_insn (\"bic\\t%1, %3\", operands);
6310 /* It's ok if OP0 is a lo-reg, even though the mov will set the
6311 conditions again, since we're only testing for equality. */
6312 output_asm_insn (\"mov\\t%0, %1\", operands);
6316 output_asm_insn (\"bic\\t%1, %3\", operands);
6317 output_asm_insn (\"str\\t%1, %0\", operands);
6320 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6322 case 4: return \"b%d5\\t%l4\";
6323 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6324 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6327 [(set (attr "far_jump")
6329 (ior (and (eq (symbol_ref ("which_alternative"))
6331 (eq_attr "length" "8"))
6332 (eq_attr "length" "10"))
6333 (const_string "yes")
6334 (const_string "no")))
6335 (set (attr "length")
6337 (eq (symbol_ref ("which_alternative"))
6340 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6341 (le (minus (match_dup 4) (pc)) (const_int 256)))
6344 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6345 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6349 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6350 (le (minus (match_dup 4) (pc)) (const_int 256)))
6353 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6354 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6359 (define_insn "*cbranchne_decr1"
6361 (if_then_else (match_operator 3 "equality_operator"
6362 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6364 (label_ref (match_operand 4 "" ""))
6366 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6367 (plus:SI (match_dup 2) (const_int -1)))
6368 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6373 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6375 VOIDmode, operands[2], const1_rtx);
6376 cond[1] = operands[4];
6378 if (which_alternative == 0)
6379 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6380 else if (which_alternative == 1)
6382 /* We must provide an alternative for a hi reg because reload
6383 cannot handle output reloads on a jump instruction, but we
6384 can't subtract into that. Fortunately a mov from lo to hi
6385 does not clobber the condition codes. */
6386 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6387 output_asm_insn (\"mov\\t%0, %1\", operands);
6391 /* Similarly, but the target is memory. */
6392 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6393 output_asm_insn (\"str\\t%1, %0\", operands);
6396 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6399 output_asm_insn (\"b%d0\\t%l1\", cond);
6402 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6403 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6405 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6406 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6410 [(set (attr "far_jump")
6412 (ior (and (eq (symbol_ref ("which_alternative"))
6414 (eq_attr "length" "8"))
6415 (eq_attr "length" "10"))
6416 (const_string "yes")
6417 (const_string "no")))
6418 (set_attr_alternative "length"
6422 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6423 (le (minus (match_dup 4) (pc)) (const_int 256)))
6426 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6427 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6432 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6433 (le (minus (match_dup 4) (pc)) (const_int 256)))
6436 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6437 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6442 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6443 (le (minus (match_dup 4) (pc)) (const_int 256)))
6446 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6447 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6452 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6453 (le (minus (match_dup 4) (pc)) (const_int 256)))
6456 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6457 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6462 (define_insn "*addsi3_cbranch"
6465 (match_operator 4 "comparison_operator"
6467 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6468 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6470 (label_ref (match_operand 5 "" ""))
6473 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6474 (plus:SI (match_dup 2) (match_dup 3)))
6475 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6477 && (GET_CODE (operands[4]) == EQ
6478 || GET_CODE (operands[4]) == NE
6479 || GET_CODE (operands[4]) == GE
6480 || GET_CODE (operands[4]) == LT)"
6486 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6487 cond[1] = operands[2];
6488 cond[2] = operands[3];
6490 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6491 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6493 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6495 if (which_alternative >= 3
6496 && which_alternative < 4)
6497 output_asm_insn (\"mov\\t%0, %1\", operands);
6498 else if (which_alternative >= 4)
6499 output_asm_insn (\"str\\t%1, %0\", operands);
6501 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6504 return \"b%d4\\t%l5\";
6506 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6508 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6512 [(set (attr "far_jump")
6514 (ior (and (lt (symbol_ref ("which_alternative"))
6516 (eq_attr "length" "8"))
6517 (eq_attr "length" "10"))
6518 (const_string "yes")
6519 (const_string "no")))
6520 (set (attr "length")
6522 (lt (symbol_ref ("which_alternative"))
6525 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6526 (le (minus (match_dup 5) (pc)) (const_int 256)))
6529 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6530 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6534 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6535 (le (minus (match_dup 5) (pc)) (const_int 256)))
6538 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6539 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6544 (define_insn "*addsi3_cbranch_scratch"
6547 (match_operator 3 "comparison_operator"
6549 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6550 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
6552 (label_ref (match_operand 4 "" ""))
6554 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6556 && (GET_CODE (operands[3]) == EQ
6557 || GET_CODE (operands[3]) == NE
6558 || GET_CODE (operands[3]) == GE
6559 || GET_CODE (operands[3]) == LT)"
6562 switch (which_alternative)
6565 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6568 output_asm_insn (\"cmn\t%1, %2\", operands);
6571 if (INTVAL (operands[2]) < 0)
6572 output_asm_insn (\"sub\t%0, %1, %2\", operands);
6574 output_asm_insn (\"add\t%0, %1, %2\", operands);
6577 if (INTVAL (operands[2]) < 0)
6578 output_asm_insn (\"sub\t%0, %0, %2\", operands);
6580 output_asm_insn (\"add\t%0, %0, %2\", operands);
6584 switch (get_attr_length (insn))
6587 return \"b%d3\\t%l4\";
6589 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6591 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6595 [(set (attr "far_jump")
6597 (eq_attr "length" "8")
6598 (const_string "yes")
6599 (const_string "no")))
6600 (set (attr "length")
6602 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6603 (le (minus (match_dup 4) (pc)) (const_int 256)))
6606 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6607 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6612 (define_insn "*subsi3_cbranch"
6615 (match_operator 4 "comparison_operator"
6617 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6618 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6620 (label_ref (match_operand 5 "" ""))
6622 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6623 (minus:SI (match_dup 2) (match_dup 3)))
6624 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6626 && (GET_CODE (operands[4]) == EQ
6627 || GET_CODE (operands[4]) == NE
6628 || GET_CODE (operands[4]) == GE
6629 || GET_CODE (operands[4]) == LT)"
6632 if (which_alternative == 0)
6633 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6634 else if (which_alternative == 1)
6636 /* We must provide an alternative for a hi reg because reload
6637 cannot handle output reloads on a jump instruction, but we
6638 can't subtract into that. Fortunately a mov from lo to hi
6639 does not clobber the condition codes. */
6640 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6641 output_asm_insn (\"mov\\t%0, %1\", operands);
6645 /* Similarly, but the target is memory. */
6646 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6647 output_asm_insn (\"str\\t%1, %0\", operands);
6650 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6653 return \"b%d4\\t%l5\";
6655 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6657 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6661 [(set (attr "far_jump")
6663 (ior (and (eq (symbol_ref ("which_alternative"))
6665 (eq_attr "length" "8"))
6666 (eq_attr "length" "10"))
6667 (const_string "yes")
6668 (const_string "no")))
6669 (set (attr "length")
6671 (eq (symbol_ref ("which_alternative"))
6674 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6675 (le (minus (match_dup 5) (pc)) (const_int 256)))
6678 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6679 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6683 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6684 (le (minus (match_dup 5) (pc)) (const_int 256)))
6687 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6688 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6693 (define_insn "*subsi3_cbranch_scratch"
6696 (match_operator 0 "arm_comparison_operator"
6697 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6698 (match_operand:SI 2 "nonmemory_operand" "l"))
6700 (label_ref (match_operand 3 "" ""))
6703 && (GET_CODE (operands[0]) == EQ
6704 || GET_CODE (operands[0]) == NE
6705 || GET_CODE (operands[0]) == GE
6706 || GET_CODE (operands[0]) == LT)"
6708 output_asm_insn (\"cmp\\t%1, %2\", operands);
6709 switch (get_attr_length (insn))
6711 case 4: return \"b%d0\\t%l3\";
6712 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6713 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6716 [(set (attr "far_jump")
6718 (eq_attr "length" "8")
6719 (const_string "yes")
6720 (const_string "no")))
6721 (set (attr "length")
6723 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6724 (le (minus (match_dup 3) (pc)) (const_int 256)))
6727 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6728 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6733 ;; Comparison and test insns
6735 (define_expand "cmpsi"
6736 [(match_operand:SI 0 "s_register_operand" "")
6737 (match_operand:SI 1 "arm_add_operand" "")]
6740 arm_compare_op0 = operands[0];
6741 arm_compare_op1 = operands[1];
6746 (define_expand "cmpsf"
6747 [(match_operand:SF 0 "s_register_operand" "")
6748 (match_operand:SF 1 "arm_float_compare_operand" "")]
6749 "TARGET_ARM && TARGET_HARD_FLOAT"
6751 arm_compare_op0 = operands[0];
6752 arm_compare_op1 = operands[1];
6757 (define_expand "cmpdf"
6758 [(match_operand:DF 0 "s_register_operand" "")
6759 (match_operand:DF 1 "arm_float_compare_operand" "")]
6760 "TARGET_ARM && TARGET_HARD_FLOAT"
6762 arm_compare_op0 = operands[0];
6763 arm_compare_op1 = operands[1];
6768 (define_insn "*arm_cmpsi_insn"
6769 [(set (reg:CC CC_REGNUM)
6770 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6771 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6776 [(set_attr "conds" "set")]
6779 (define_insn "*cmpsi_shiftsi"
6780 [(set (reg:CC CC_REGNUM)
6781 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6782 (match_operator:SI 3 "shift_operator"
6783 [(match_operand:SI 1 "s_register_operand" "r")
6784 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6787 [(set_attr "conds" "set")
6788 (set_attr "shift" "1")
6789 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6790 (const_string "alu_shift")
6791 (const_string "alu_shift_reg")))]
6794 (define_insn "*cmpsi_shiftsi_swp"
6795 [(set (reg:CC_SWP CC_REGNUM)
6796 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6797 [(match_operand:SI 1 "s_register_operand" "r")
6798 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6799 (match_operand:SI 0 "s_register_operand" "r")))]
6802 [(set_attr "conds" "set")
6803 (set_attr "shift" "1")
6804 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6805 (const_string "alu_shift")
6806 (const_string "alu_shift_reg")))]
6809 (define_insn "*cmpsi_negshiftsi_si"
6810 [(set (reg:CC_Z CC_REGNUM)
6812 (neg:SI (match_operator:SI 1 "shift_operator"
6813 [(match_operand:SI 2 "s_register_operand" "r")
6814 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6815 (match_operand:SI 0 "s_register_operand" "r")))]
6818 [(set_attr "conds" "set")
6819 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6820 (const_string "alu_shift")
6821 (const_string "alu_shift_reg")))]
6824 ;; Cirrus SF compare instruction
6825 (define_insn "*cirrus_cmpsf"
6826 [(set (reg:CCFP CC_REGNUM)
6827 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6828 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6829 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6830 "cfcmps%?\\tr15, %V0, %V1"
6831 [(set_attr "type" "mav_farith")
6832 (set_attr "cirrus" "compare")]
6835 ;; Cirrus DF compare instruction
6836 (define_insn "*cirrus_cmpdf"
6837 [(set (reg:CCFP CC_REGNUM)
6838 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6839 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6840 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6841 "cfcmpd%?\\tr15, %V0, %V1"
6842 [(set_attr "type" "mav_farith")
6843 (set_attr "cirrus" "compare")]
6846 ;; Cirrus DI compare instruction
6847 (define_expand "cmpdi"
6848 [(match_operand:DI 0 "cirrus_fp_register" "")
6849 (match_operand:DI 1 "cirrus_fp_register" "")]
6850 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6852 arm_compare_op0 = operands[0];
6853 arm_compare_op1 = operands[1];
6857 (define_insn "*cirrus_cmpdi"
6858 [(set (reg:CC CC_REGNUM)
6859 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6860 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6861 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6862 "cfcmp64%?\\tr15, %V0, %V1"
6863 [(set_attr "type" "mav_farith")
6864 (set_attr "cirrus" "compare")]
6867 ; This insn allows redundant compares to be removed by cse, nothing should
6868 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6869 ; is deleted later on. The match_dup will match the mode here, so that
6870 ; mode changes of the condition codes aren't lost by this even though we don't
6871 ; specify what they are.
6873 (define_insn "*deleted_compare"
6874 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6876 "\\t%@ deleted compare"
6877 [(set_attr "conds" "set")
6878 (set_attr "length" "0")]
6882 ;; Conditional branch insns
6884 (define_expand "beq"
6886 (if_then_else (eq (match_dup 1) (const_int 0))
6887 (label_ref (match_operand 0 "" ""))
6890 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6893 (define_expand "bne"
6895 (if_then_else (ne (match_dup 1) (const_int 0))
6896 (label_ref (match_operand 0 "" ""))
6899 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6902 (define_expand "bgt"
6904 (if_then_else (gt (match_dup 1) (const_int 0))
6905 (label_ref (match_operand 0 "" ""))
6908 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6911 (define_expand "ble"
6913 (if_then_else (le (match_dup 1) (const_int 0))
6914 (label_ref (match_operand 0 "" ""))
6917 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6920 (define_expand "bge"
6922 (if_then_else (ge (match_dup 1) (const_int 0))
6923 (label_ref (match_operand 0 "" ""))
6926 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6929 (define_expand "blt"
6931 (if_then_else (lt (match_dup 1) (const_int 0))
6932 (label_ref (match_operand 0 "" ""))
6935 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6938 (define_expand "bgtu"
6940 (if_then_else (gtu (match_dup 1) (const_int 0))
6941 (label_ref (match_operand 0 "" ""))
6944 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6947 (define_expand "bleu"
6949 (if_then_else (leu (match_dup 1) (const_int 0))
6950 (label_ref (match_operand 0 "" ""))
6953 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6956 (define_expand "bgeu"
6958 (if_then_else (geu (match_dup 1) (const_int 0))
6959 (label_ref (match_operand 0 "" ""))
6962 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6965 (define_expand "bltu"
6967 (if_then_else (ltu (match_dup 1) (const_int 0))
6968 (label_ref (match_operand 0 "" ""))
6971 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6974 (define_expand "bunordered"
6976 (if_then_else (unordered (match_dup 1) (const_int 0))
6977 (label_ref (match_operand 0 "" ""))
6979 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6980 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6984 (define_expand "bordered"
6986 (if_then_else (ordered (match_dup 1) (const_int 0))
6987 (label_ref (match_operand 0 "" ""))
6989 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6990 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6994 (define_expand "bungt"
6996 (if_then_else (ungt (match_dup 1) (const_int 0))
6997 (label_ref (match_operand 0 "" ""))
6999 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7000 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
7003 (define_expand "bunlt"
7005 (if_then_else (unlt (match_dup 1) (const_int 0))
7006 (label_ref (match_operand 0 "" ""))
7008 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7009 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
7012 (define_expand "bunge"
7014 (if_then_else (unge (match_dup 1) (const_int 0))
7015 (label_ref (match_operand 0 "" ""))
7017 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7018 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
7021 (define_expand "bunle"
7023 (if_then_else (unle (match_dup 1) (const_int 0))
7024 (label_ref (match_operand 0 "" ""))
7026 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7027 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
7030 ;; The following two patterns need two branch instructions, since there is
7031 ;; no single instruction that will handle all cases.
7032 (define_expand "buneq"
7034 (if_then_else (uneq (match_dup 1) (const_int 0))
7035 (label_ref (match_operand 0 "" ""))
7037 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7038 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
7041 (define_expand "bltgt"
7043 (if_then_else (ltgt (match_dup 1) (const_int 0))
7044 (label_ref (match_operand 0 "" ""))
7046 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7047 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
7051 ;; Patterns to match conditional branch insns.
7054 ; Special pattern to match UNEQ.
7055 (define_insn "*arm_buneq"
7057 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7058 (label_ref (match_operand 0 "" ""))
7060 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7062 if (arm_ccfsm_state != 0)
7065 return \"bvs\\t%l0\;beq\\t%l0\";
7067 [(set_attr "conds" "jump_clob")
7068 (set_attr "length" "8")]
7071 ; Special pattern to match LTGT.
7072 (define_insn "*arm_bltgt"
7074 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7075 (label_ref (match_operand 0 "" ""))
7077 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7079 if (arm_ccfsm_state != 0)
7082 return \"bmi\\t%l0\;bgt\\t%l0\";
7084 [(set_attr "conds" "jump_clob")
7085 (set_attr "length" "8")]
7088 (define_insn "*arm_cond_branch"
7090 (if_then_else (match_operator 1 "arm_comparison_operator"
7091 [(match_operand 2 "cc_register" "") (const_int 0)])
7092 (label_ref (match_operand 0 "" ""))
7096 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7098 arm_ccfsm_state += 2;
7101 return \"b%d1\\t%l0\";
7103 [(set_attr "conds" "use")
7104 (set_attr "type" "branch")]
7107 ; Special pattern to match reversed UNEQ.
7108 (define_insn "*arm_buneq_reversed"
7110 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7112 (label_ref (match_operand 0 "" ""))))]
7113 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7115 if (arm_ccfsm_state != 0)
7118 return \"bmi\\t%l0\;bgt\\t%l0\";
7120 [(set_attr "conds" "jump_clob")
7121 (set_attr "length" "8")]
7124 ; Special pattern to match reversed LTGT.
7125 (define_insn "*arm_bltgt_reversed"
7127 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7129 (label_ref (match_operand 0 "" ""))))]
7130 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7132 if (arm_ccfsm_state != 0)
7135 return \"bvs\\t%l0\;beq\\t%l0\";
7137 [(set_attr "conds" "jump_clob")
7138 (set_attr "length" "8")]
7141 (define_insn "*arm_cond_branch_reversed"
7143 (if_then_else (match_operator 1 "arm_comparison_operator"
7144 [(match_operand 2 "cc_register" "") (const_int 0)])
7146 (label_ref (match_operand 0 "" ""))))]
7149 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7151 arm_ccfsm_state += 2;
7154 return \"b%D1\\t%l0\";
7156 [(set_attr "conds" "use")
7157 (set_attr "type" "branch")]
7164 (define_expand "seq"
7165 [(set (match_operand:SI 0 "s_register_operand" "")
7166 (eq:SI (match_dup 1) (const_int 0)))]
7168 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7171 (define_expand "sne"
7172 [(set (match_operand:SI 0 "s_register_operand" "")
7173 (ne:SI (match_dup 1) (const_int 0)))]
7175 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7178 (define_expand "sgt"
7179 [(set (match_operand:SI 0 "s_register_operand" "")
7180 (gt:SI (match_dup 1) (const_int 0)))]
7182 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7185 (define_expand "sle"
7186 [(set (match_operand:SI 0 "s_register_operand" "")
7187 (le:SI (match_dup 1) (const_int 0)))]
7189 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7192 (define_expand "sge"
7193 [(set (match_operand:SI 0 "s_register_operand" "")
7194 (ge:SI (match_dup 1) (const_int 0)))]
7196 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7199 (define_expand "slt"
7200 [(set (match_operand:SI 0 "s_register_operand" "")
7201 (lt:SI (match_dup 1) (const_int 0)))]
7203 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7206 (define_expand "sgtu"
7207 [(set (match_operand:SI 0 "s_register_operand" "")
7208 (gtu:SI (match_dup 1) (const_int 0)))]
7210 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7213 (define_expand "sleu"
7214 [(set (match_operand:SI 0 "s_register_operand" "")
7215 (leu:SI (match_dup 1) (const_int 0)))]
7217 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7220 (define_expand "sgeu"
7221 [(set (match_operand:SI 0 "s_register_operand" "")
7222 (geu:SI (match_dup 1) (const_int 0)))]
7224 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7227 (define_expand "sltu"
7228 [(set (match_operand:SI 0 "s_register_operand" "")
7229 (ltu:SI (match_dup 1) (const_int 0)))]
7231 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7234 (define_expand "sunordered"
7235 [(set (match_operand:SI 0 "s_register_operand" "")
7236 (unordered:SI (match_dup 1) (const_int 0)))]
7237 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7238 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7242 (define_expand "sordered"
7243 [(set (match_operand:SI 0 "s_register_operand" "")
7244 (ordered:SI (match_dup 1) (const_int 0)))]
7245 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7246 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7250 (define_expand "sungt"
7251 [(set (match_operand:SI 0 "s_register_operand" "")
7252 (ungt:SI (match_dup 1) (const_int 0)))]
7253 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7254 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7258 (define_expand "sunge"
7259 [(set (match_operand:SI 0 "s_register_operand" "")
7260 (unge:SI (match_dup 1) (const_int 0)))]
7261 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7262 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7266 (define_expand "sunlt"
7267 [(set (match_operand:SI 0 "s_register_operand" "")
7268 (unlt:SI (match_dup 1) (const_int 0)))]
7269 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7270 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7274 (define_expand "sunle"
7275 [(set (match_operand:SI 0 "s_register_operand" "")
7276 (unle:SI (match_dup 1) (const_int 0)))]
7277 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7278 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7282 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7283 ;;; simple ARM instructions.
7285 ; (define_expand "suneq"
7286 ; [(set (match_operand:SI 0 "s_register_operand" "")
7287 ; (uneq:SI (match_dup 1) (const_int 0)))]
7288 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7292 ; (define_expand "sltgt"
7293 ; [(set (match_operand:SI 0 "s_register_operand" "")
7294 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7295 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7299 (define_insn "*mov_scc"
7300 [(set (match_operand:SI 0 "s_register_operand" "=r")
7301 (match_operator:SI 1 "arm_comparison_operator"
7302 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7304 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7305 [(set_attr "conds" "use")
7306 (set_attr "length" "8")]
7309 (define_insn "*mov_negscc"
7310 [(set (match_operand:SI 0 "s_register_operand" "=r")
7311 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7312 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7314 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7315 [(set_attr "conds" "use")
7316 (set_attr "length" "8")]
7319 (define_insn "*mov_notscc"
7320 [(set (match_operand:SI 0 "s_register_operand" "=r")
7321 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7322 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7324 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7325 [(set_attr "conds" "use")
7326 (set_attr "length" "8")]
7330 ;; Conditional move insns
7332 (define_expand "movsicc"
7333 [(set (match_operand:SI 0 "s_register_operand" "")
7334 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7335 (match_operand:SI 2 "arm_not_operand" "")
7336 (match_operand:SI 3 "arm_not_operand" "")))]
7340 enum rtx_code code = GET_CODE (operands[1]);
7343 if (code == UNEQ || code == LTGT)
7346 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7347 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7351 (define_expand "movsfcc"
7352 [(set (match_operand:SF 0 "s_register_operand" "")
7353 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7354 (match_operand:SF 2 "s_register_operand" "")
7355 (match_operand:SF 3 "nonmemory_operand" "")))]
7359 enum rtx_code code = GET_CODE (operands[1]);
7362 if (code == UNEQ || code == LTGT)
7365 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7366 Otherwise, ensure it is a valid FP add operand */
7367 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7368 || (!arm_float_add_operand (operands[3], SFmode)))
7369 operands[3] = force_reg (SFmode, operands[3]);
7371 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7372 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7376 (define_expand "movdfcc"
7377 [(set (match_operand:DF 0 "s_register_operand" "")
7378 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7379 (match_operand:DF 2 "s_register_operand" "")
7380 (match_operand:DF 3 "arm_float_add_operand" "")))]
7381 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7384 enum rtx_code code = GET_CODE (operands[1]);
7387 if (code == UNEQ || code == LTGT)
7390 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7391 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7395 (define_insn "*movsicc_insn"
7396 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7398 (match_operator 3 "arm_comparison_operator"
7399 [(match_operand 4 "cc_register" "") (const_int 0)])
7400 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7401 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7408 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7409 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7410 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7411 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7412 [(set_attr "length" "4,4,4,4,8,8,8,8")
7413 (set_attr "conds" "use")]
7416 (define_insn "*movsfcc_soft_insn"
7417 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7418 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7419 [(match_operand 4 "cc_register" "") (const_int 0)])
7420 (match_operand:SF 1 "s_register_operand" "0,r")
7421 (match_operand:SF 2 "s_register_operand" "r,0")))]
7422 "TARGET_ARM && TARGET_SOFT_FLOAT"
7426 [(set_attr "conds" "use")]
7430 ;; Jump and linkage insns
7432 (define_expand "jump"
7434 (label_ref (match_operand 0 "" "")))]
7439 (define_insn "*arm_jump"
7441 (label_ref (match_operand 0 "" "")))]
7445 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7447 arm_ccfsm_state += 2;
7450 return \"b%?\\t%l0\";
7453 [(set_attr "predicable" "yes")]
7456 (define_insn "*thumb_jump"
7458 (label_ref (match_operand 0 "" "")))]
7461 if (get_attr_length (insn) == 2)
7463 return \"bl\\t%l0\\t%@ far jump\";
7465 [(set (attr "far_jump")
7467 (eq_attr "length" "4")
7468 (const_string "yes")
7469 (const_string "no")))
7470 (set (attr "length")
7472 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7473 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7478 (define_expand "call"
7479 [(parallel [(call (match_operand 0 "memory_operand" "")
7480 (match_operand 1 "general_operand" ""))
7481 (use (match_operand 2 "" ""))
7482 (clobber (reg:SI LR_REGNUM))])]
7488 /* In an untyped call, we can get NULL for operand 2. */
7489 if (operands[2] == NULL_RTX)
7490 operands[2] = const0_rtx;
7492 /* This is to decide if we should generate indirect calls by loading the
7493 32 bit address of the callee into a register before performing the
7494 branch and link. operand[2] encodes the long_call/short_call
7495 attribute of the function being called. This attribute is set whenever
7496 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7497 is used, and the short_call attribute can also be set if function is
7498 declared as static or if it has already been defined in the current
7499 compilation unit. See arm.c and arm.h for info about this. The third
7500 parameter to arm_is_longcall_p is used to tell it which pattern
7502 callee = XEXP (operands[0], 0);
7504 if (GET_CODE (callee) != REG
7505 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7506 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7510 (define_insn "*call_reg_armv5"
7511 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7512 (match_operand 1 "" ""))
7513 (use (match_operand 2 "" ""))
7514 (clobber (reg:SI LR_REGNUM))]
7515 "TARGET_ARM && arm_arch5"
7517 [(set_attr "type" "call")]
7520 (define_insn "*call_reg_arm"
7521 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7522 (match_operand 1 "" ""))
7523 (use (match_operand 2 "" ""))
7524 (clobber (reg:SI LR_REGNUM))]
7525 "TARGET_ARM && !arm_arch5"
7527 return output_call (operands);
7529 ;; length is worst case, normally it is only two
7530 [(set_attr "length" "12")
7531 (set_attr "type" "call")]
7534 (define_insn "*call_mem"
7535 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7536 (match_operand 1 "" ""))
7537 (use (match_operand 2 "" ""))
7538 (clobber (reg:SI LR_REGNUM))]
7541 return output_call_mem (operands);
7543 [(set_attr "length" "12")
7544 (set_attr "type" "call")]
7547 (define_insn "*call_reg_thumb_v5"
7548 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7549 (match_operand 1 "" ""))
7550 (use (match_operand 2 "" ""))
7551 (clobber (reg:SI LR_REGNUM))]
7552 "TARGET_THUMB && arm_arch5"
7554 [(set_attr "length" "2")
7555 (set_attr "type" "call")]
7558 (define_insn "*call_reg_thumb"
7559 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7560 (match_operand 1 "" ""))
7561 (use (match_operand 2 "" ""))
7562 (clobber (reg:SI LR_REGNUM))]
7563 "TARGET_THUMB && !arm_arch5"
7566 if (!TARGET_CALLER_INTERWORKING)
7567 return thumb_call_via_reg (operands[0]);
7568 else if (operands[1] == const0_rtx)
7569 return \"bl\\t%__interwork_call_via_%0\";
7570 else if (frame_pointer_needed)
7571 return \"bl\\t%__interwork_r7_call_via_%0\";
7573 return \"bl\\t%__interwork_r11_call_via_%0\";
7575 [(set_attr "type" "call")]
7578 (define_expand "call_value"
7579 [(parallel [(set (match_operand 0 "" "")
7580 (call (match_operand 1 "memory_operand" "")
7581 (match_operand 2 "general_operand" "")))
7582 (use (match_operand 3 "" ""))
7583 (clobber (reg:SI LR_REGNUM))])]
7587 rtx callee = XEXP (operands[1], 0);
7589 /* In an untyped call, we can get NULL for operand 2. */
7590 if (operands[3] == 0)
7591 operands[3] = const0_rtx;
7593 /* See the comment in define_expand \"call\". */
7594 if (GET_CODE (callee) != REG
7595 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7596 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7600 (define_insn "*call_value_reg_armv5"
7601 [(set (match_operand 0 "" "")
7602 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7603 (match_operand 2 "" "")))
7604 (use (match_operand 3 "" ""))
7605 (clobber (reg:SI LR_REGNUM))]
7606 "TARGET_ARM && arm_arch5"
7608 [(set_attr "type" "call")]
7611 (define_insn "*call_value_reg_arm"
7612 [(set (match_operand 0 "" "")
7613 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7614 (match_operand 2 "" "")))
7615 (use (match_operand 3 "" ""))
7616 (clobber (reg:SI LR_REGNUM))]
7617 "TARGET_ARM && !arm_arch5"
7619 return output_call (&operands[1]);
7621 [(set_attr "length" "12")
7622 (set_attr "type" "call")]
7625 (define_insn "*call_value_mem"
7626 [(set (match_operand 0 "" "")
7627 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7628 (match_operand 2 "" "")))
7629 (use (match_operand 3 "" ""))
7630 (clobber (reg:SI LR_REGNUM))]
7631 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7633 return output_call_mem (&operands[1]);
7635 [(set_attr "length" "12")
7636 (set_attr "type" "call")]
7639 (define_insn "*call_value_reg_thumb_v5"
7640 [(set (match_operand 0 "" "")
7641 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7642 (match_operand 2 "" "")))
7643 (use (match_operand 3 "" ""))
7644 (clobber (reg:SI LR_REGNUM))]
7645 "TARGET_THUMB && arm_arch5"
7647 [(set_attr "length" "2")
7648 (set_attr "type" "call")]
7651 (define_insn "*call_value_reg_thumb"
7652 [(set (match_operand 0 "" "")
7653 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7654 (match_operand 2 "" "")))
7655 (use (match_operand 3 "" ""))
7656 (clobber (reg:SI LR_REGNUM))]
7657 "TARGET_THUMB && !arm_arch5"
7660 if (!TARGET_CALLER_INTERWORKING)
7661 return thumb_call_via_reg (operands[1]);
7662 else if (operands[2] == const0_rtx)
7663 return \"bl\\t%__interwork_call_via_%1\";
7664 else if (frame_pointer_needed)
7665 return \"bl\\t%__interwork_r7_call_via_%1\";
7667 return \"bl\\t%__interwork_r11_call_via_%1\";
7669 [(set_attr "type" "call")]
7672 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7673 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7675 (define_insn "*call_symbol"
7676 [(call (mem:SI (match_operand:SI 0 "" ""))
7677 (match_operand 1 "" ""))
7678 (use (match_operand 2 "" ""))
7679 (clobber (reg:SI LR_REGNUM))]
7681 && (GET_CODE (operands[0]) == SYMBOL_REF)
7682 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7685 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7687 [(set_attr "type" "call")]
7690 (define_insn "*call_value_symbol"
7691 [(set (match_operand 0 "" "")
7692 (call (mem:SI (match_operand:SI 1 "" ""))
7693 (match_operand:SI 2 "" "")))
7694 (use (match_operand 3 "" ""))
7695 (clobber (reg:SI LR_REGNUM))]
7697 && (GET_CODE (operands[1]) == SYMBOL_REF)
7698 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7701 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7703 [(set_attr "type" "call")]
7706 (define_insn "*call_insn"
7707 [(call (mem:SI (match_operand:SI 0 "" ""))
7708 (match_operand:SI 1 "" ""))
7709 (use (match_operand 2 "" ""))
7710 (clobber (reg:SI LR_REGNUM))]
7712 && GET_CODE (operands[0]) == SYMBOL_REF
7713 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7715 [(set_attr "length" "4")
7716 (set_attr "type" "call")]
7719 (define_insn "*call_value_insn"
7720 [(set (match_operand 0 "" "")
7721 (call (mem:SI (match_operand 1 "" ""))
7722 (match_operand 2 "" "")))
7723 (use (match_operand 3 "" ""))
7724 (clobber (reg:SI LR_REGNUM))]
7726 && GET_CODE (operands[1]) == SYMBOL_REF
7727 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7729 [(set_attr "length" "4")
7730 (set_attr "type" "call")]
7733 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7734 (define_expand "sibcall"
7735 [(parallel [(call (match_operand 0 "memory_operand" "")
7736 (match_operand 1 "general_operand" ""))
7738 (use (match_operand 2 "" ""))])]
7742 if (operands[2] == NULL_RTX)
7743 operands[2] = const0_rtx;
7747 (define_expand "sibcall_value"
7748 [(parallel [(set (match_operand 0 "" "")
7749 (call (match_operand 1 "memory_operand" "")
7750 (match_operand 2 "general_operand" "")))
7752 (use (match_operand 3 "" ""))])]
7756 if (operands[3] == NULL_RTX)
7757 operands[3] = const0_rtx;
7761 (define_insn "*sibcall_insn"
7762 [(call (mem:SI (match_operand:SI 0 "" "X"))
7763 (match_operand 1 "" ""))
7765 (use (match_operand 2 "" ""))]
7766 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7768 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7770 [(set_attr "type" "call")]
7773 (define_insn "*sibcall_value_insn"
7774 [(set (match_operand 0 "" "")
7775 (call (mem:SI (match_operand:SI 1 "" "X"))
7776 (match_operand 2 "" "")))
7778 (use (match_operand 3 "" ""))]
7779 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7781 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7783 [(set_attr "type" "call")]
7786 ;; Often the return insn will be the same as loading from memory, so set attr
7787 (define_insn "return"
7789 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7792 if (arm_ccfsm_state == 2)
7794 arm_ccfsm_state += 2;
7797 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7799 [(set_attr "type" "load1")
7800 (set_attr "length" "12")
7801 (set_attr "predicable" "yes")]
7804 (define_insn "*cond_return"
7806 (if_then_else (match_operator 0 "arm_comparison_operator"
7807 [(match_operand 1 "cc_register" "") (const_int 0)])
7810 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7813 if (arm_ccfsm_state == 2)
7815 arm_ccfsm_state += 2;
7818 return output_return_instruction (operands[0], TRUE, FALSE);
7820 [(set_attr "conds" "use")
7821 (set_attr "length" "12")
7822 (set_attr "type" "load1")]
7825 (define_insn "*cond_return_inverted"
7827 (if_then_else (match_operator 0 "arm_comparison_operator"
7828 [(match_operand 1 "cc_register" "") (const_int 0)])
7831 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7834 if (arm_ccfsm_state == 2)
7836 arm_ccfsm_state += 2;
7839 return output_return_instruction (operands[0], TRUE, TRUE);
7841 [(set_attr "conds" "use")
7842 (set_attr "length" "12")
7843 (set_attr "type" "load1")]
7846 ;; Generate a sequence of instructions to determine if the processor is
7847 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7850 (define_expand "return_addr_mask"
7852 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7854 (set (match_operand:SI 0 "s_register_operand" "")
7855 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7857 (const_int 67108860)))] ; 0x03fffffc
7860 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7863 (define_insn "*check_arch2"
7864 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7865 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7868 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7869 [(set_attr "length" "8")
7870 (set_attr "conds" "set")]
7873 ;; Call subroutine returning any type.
7875 (define_expand "untyped_call"
7876 [(parallel [(call (match_operand 0 "" "")
7878 (match_operand 1 "" "")
7879 (match_operand 2 "" "")])]
7884 rtx par = gen_rtx_PARALLEL (VOIDmode,
7885 rtvec_alloc (XVECLEN (operands[2], 0)));
7886 rtx addr = gen_reg_rtx (Pmode);
7890 emit_move_insn (addr, XEXP (operands[1], 0));
7891 mem = change_address (operands[1], BLKmode, addr);
7893 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7895 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7897 /* Default code only uses r0 as a return value, but we could
7898 be using anything up to 4 registers. */
7899 if (REGNO (src) == R0_REGNUM)
7900 src = gen_rtx_REG (TImode, R0_REGNUM);
7902 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7904 size += GET_MODE_SIZE (GET_MODE (src));
7907 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7912 for (i = 0; i < XVECLEN (par, 0); i++)
7914 HOST_WIDE_INT offset = 0;
7915 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
7918 emit_move_insn (addr, plus_constant (addr, size));
7920 mem = change_address (mem, GET_MODE (reg), NULL);
7921 if (REGNO (reg) == R0_REGNUM)
7923 /* On thumb we have to use a write-back instruction. */
7924 emit_insn (arm_gen_store_multiple (R0_REGNUM, 4, addr, TRUE,
7925 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
7926 size = TARGET_ARM ? 16 : 0;
7930 emit_move_insn (mem, reg);
7931 size = GET_MODE_SIZE (GET_MODE (reg));
7935 /* The optimizer does not know that the call sets the function value
7936 registers we stored in the result block. We avoid problems by
7937 claiming that all hard registers are used and clobbered at this
7939 emit_insn (gen_blockage ());
7945 (define_expand "untyped_return"
7946 [(match_operand:BLK 0 "memory_operand" "")
7947 (match_operand 1 "" "")]
7952 rtx addr = gen_reg_rtx (Pmode);
7956 emit_move_insn (addr, XEXP (operands[0], 0));
7957 mem = change_address (operands[0], BLKmode, addr);
7959 for (i = 0; i < XVECLEN (operands[1], 0); i++)
7961 HOST_WIDE_INT offset = 0;
7962 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
7965 emit_move_insn (addr, plus_constant (addr, size));
7967 mem = change_address (mem, GET_MODE (reg), NULL);
7968 if (REGNO (reg) == R0_REGNUM)
7970 /* On thumb we have to use a write-back instruction. */
7971 emit_insn (arm_gen_load_multiple (R0_REGNUM, 4, addr, TRUE,
7972 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
7973 size = TARGET_ARM ? 16 : 0;
7977 emit_move_insn (reg, mem);
7978 size = GET_MODE_SIZE (GET_MODE (reg));
7982 /* Emit USE insns before the return. */
7983 for (i = 0; i < XVECLEN (operands[1], 0); i++)
7984 emit_insn (gen_rtx_USE (VOIDmode,
7985 SET_DEST (XVECEXP (operands[1], 0, i))));
7987 /* Construct the return. */
7988 expand_naked_return ();
7994 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7995 ;; all of memory. This blocks insns from being moved across this point.
7997 (define_insn "blockage"
7998 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8001 [(set_attr "length" "0")
8002 (set_attr "type" "block")]
8005 (define_expand "casesi"
8006 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8007 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8008 (match_operand:SI 2 "const_int_operand" "") ; total range
8009 (match_operand:SI 3 "" "") ; table label
8010 (match_operand:SI 4 "" "")] ; Out of range label
8015 if (operands[1] != const0_rtx)
8017 reg = gen_reg_rtx (SImode);
8019 emit_insn (gen_addsi3 (reg, operands[0],
8020 GEN_INT (-INTVAL (operands[1]))));
8024 if (!const_ok_for_arm (INTVAL (operands[2])))
8025 operands[2] = force_reg (SImode, operands[2]);
8027 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
8033 ;; The USE in this pattern is needed to tell flow analysis that this is
8034 ;; a CASESI insn. It has no other purpose.
8035 (define_insn "casesi_internal"
8036 [(parallel [(set (pc)
8038 (leu (match_operand:SI 0 "s_register_operand" "r")
8039 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8040 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8041 (label_ref (match_operand 2 "" ""))))
8042 (label_ref (match_operand 3 "" ""))))
8043 (clobber (reg:CC CC_REGNUM))
8044 (use (label_ref (match_dup 2)))])]
8048 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8049 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8051 [(set_attr "conds" "clob")
8052 (set_attr "length" "12")]
8055 (define_expand "indirect_jump"
8057 (match_operand:SI 0 "s_register_operand" ""))]
8062 ;; NB Never uses BX.
8063 (define_insn "*arm_indirect_jump"
8065 (match_operand:SI 0 "s_register_operand" "r"))]
8067 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8068 [(set_attr "predicable" "yes")]
8071 (define_insn "*load_indirect_jump"
8073 (match_operand:SI 0 "memory_operand" "m"))]
8075 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8076 [(set_attr "type" "load1")
8077 (set_attr "pool_range" "4096")
8078 (set_attr "neg_pool_range" "4084")
8079 (set_attr "predicable" "yes")]
8082 ;; NB Never uses BX.
8083 (define_insn "*thumb_indirect_jump"
8085 (match_operand:SI 0 "register_operand" "l*r"))]
8088 [(set_attr "conds" "clob")
8089 (set_attr "length" "2")]
8100 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8101 return \"mov\\tr8, r8\";
8103 [(set (attr "length")
8104 (if_then_else (eq_attr "is_thumb" "yes")
8110 ;; Patterns to allow combination of arithmetic, cond code and shifts
8112 (define_insn "*arith_shiftsi"
8113 [(set (match_operand:SI 0 "s_register_operand" "=r")
8114 (match_operator:SI 1 "shiftable_operator"
8115 [(match_operator:SI 3 "shift_operator"
8116 [(match_operand:SI 4 "s_register_operand" "r")
8117 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8118 (match_operand:SI 2 "s_register_operand" "r")]))]
8120 "%i1%?\\t%0, %2, %4%S3"
8121 [(set_attr "predicable" "yes")
8122 (set_attr "shift" "4")
8123 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8124 (const_string "alu_shift")
8125 (const_string "alu_shift_reg")))]
8129 [(set (match_operand:SI 0 "s_register_operand" "")
8130 (match_operator:SI 1 "shiftable_operator"
8131 [(match_operator:SI 2 "shiftable_operator"
8132 [(match_operator:SI 3 "shift_operator"
8133 [(match_operand:SI 4 "s_register_operand" "")
8134 (match_operand:SI 5 "reg_or_int_operand" "")])
8135 (match_operand:SI 6 "s_register_operand" "")])
8136 (match_operand:SI 7 "arm_rhs_operand" "")]))
8137 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8140 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8143 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8146 (define_insn "*arith_shiftsi_compare0"
8147 [(set (reg:CC_NOOV CC_REGNUM)
8148 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8149 [(match_operator:SI 3 "shift_operator"
8150 [(match_operand:SI 4 "s_register_operand" "r")
8151 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8152 (match_operand:SI 2 "s_register_operand" "r")])
8154 (set (match_operand:SI 0 "s_register_operand" "=r")
8155 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8158 "%i1%?s\\t%0, %2, %4%S3"
8159 [(set_attr "conds" "set")
8160 (set_attr "shift" "4")
8161 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8162 (const_string "alu_shift")
8163 (const_string "alu_shift_reg")))]
8166 (define_insn "*arith_shiftsi_compare0_scratch"
8167 [(set (reg:CC_NOOV CC_REGNUM)
8168 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
8169 [(match_operator:SI 3 "shift_operator"
8170 [(match_operand:SI 4 "s_register_operand" "r")
8171 (match_operand:SI 5 "reg_or_int_operand" "rI")])
8172 (match_operand:SI 2 "s_register_operand" "r")])
8174 (clobber (match_scratch:SI 0 "=r"))]
8176 "%i1%?s\\t%0, %2, %4%S3"
8177 [(set_attr "conds" "set")
8178 (set_attr "shift" "4")
8179 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
8180 (const_string "alu_shift")
8181 (const_string "alu_shift_reg")))]
8184 (define_insn "*sub_shiftsi"
8185 [(set (match_operand:SI 0 "s_register_operand" "=r")
8186 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8187 (match_operator:SI 2 "shift_operator"
8188 [(match_operand:SI 3 "s_register_operand" "r")
8189 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
8191 "sub%?\\t%0, %1, %3%S2"
8192 [(set_attr "predicable" "yes")
8193 (set_attr "shift" "3")
8194 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8195 (const_string "alu_shift")
8196 (const_string "alu_shift_reg")))]
8199 (define_insn "*sub_shiftsi_compare0"
8200 [(set (reg:CC_NOOV CC_REGNUM)
8202 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8203 (match_operator:SI 2 "shift_operator"
8204 [(match_operand:SI 3 "s_register_operand" "r")
8205 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8207 (set (match_operand:SI 0 "s_register_operand" "=r")
8208 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
8211 "sub%?s\\t%0, %1, %3%S2"
8212 [(set_attr "conds" "set")
8213 (set_attr "shift" "3")
8214 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8215 (const_string "alu_shift")
8216 (const_string "alu_shift_reg")))]
8219 (define_insn "*sub_shiftsi_compare0_scratch"
8220 [(set (reg:CC_NOOV CC_REGNUM)
8222 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
8223 (match_operator:SI 2 "shift_operator"
8224 [(match_operand:SI 3 "s_register_operand" "r")
8225 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
8227 (clobber (match_scratch:SI 0 "=r"))]
8229 "sub%?s\\t%0, %1, %3%S2"
8230 [(set_attr "conds" "set")
8231 (set_attr "shift" "3")
8232 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
8233 (const_string "alu_shift")
8234 (const_string "alu_shift_reg")))]
8239 (define_insn "*and_scc"
8240 [(set (match_operand:SI 0 "s_register_operand" "=r")
8241 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8242 [(match_operand 3 "cc_register" "") (const_int 0)])
8243 (match_operand:SI 2 "s_register_operand" "r")))]
8245 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8246 [(set_attr "conds" "use")
8247 (set_attr "length" "8")]
8250 (define_insn "*ior_scc"
8251 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8252 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8253 [(match_operand 3 "cc_register" "") (const_int 0)])
8254 (match_operand:SI 1 "s_register_operand" "0,?r")))]
8258 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8259 [(set_attr "conds" "use")
8260 (set_attr "length" "4,8")]
8263 (define_insn "*compare_scc"
8264 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8265 (match_operator:SI 1 "arm_comparison_operator"
8266 [(match_operand:SI 2 "s_register_operand" "r,r")
8267 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8268 (clobber (reg:CC CC_REGNUM))]
8271 if (operands[3] == const0_rtx)
8273 if (GET_CODE (operands[1]) == LT)
8274 return \"mov\\t%0, %2, lsr #31\";
8276 if (GET_CODE (operands[1]) == GE)
8277 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8279 if (GET_CODE (operands[1]) == EQ)
8280 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8283 if (GET_CODE (operands[1]) == NE)
8285 if (which_alternative == 1)
8286 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8287 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8289 if (which_alternative == 1)
8290 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8292 output_asm_insn (\"cmp\\t%2, %3\", operands);
8293 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8295 [(set_attr "conds" "clob")
8296 (set_attr "length" "12")]
8299 (define_insn "*cond_move"
8300 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8301 (if_then_else:SI (match_operator 3 "equality_operator"
8302 [(match_operator 4 "arm_comparison_operator"
8303 [(match_operand 5 "cc_register" "") (const_int 0)])
8305 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8306 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8309 if (GET_CODE (operands[3]) == NE)
8311 if (which_alternative != 1)
8312 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8313 if (which_alternative != 0)
8314 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8317 if (which_alternative != 0)
8318 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8319 if (which_alternative != 1)
8320 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8323 [(set_attr "conds" "use")
8324 (set_attr "length" "4,4,8")]
8327 (define_insn "*cond_arith"
8328 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8329 (match_operator:SI 5 "shiftable_operator"
8330 [(match_operator:SI 4 "arm_comparison_operator"
8331 [(match_operand:SI 2 "s_register_operand" "r,r")
8332 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8333 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8334 (clobber (reg:CC CC_REGNUM))]
8337 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8338 return \"%i5\\t%0, %1, %2, lsr #31\";
8340 output_asm_insn (\"cmp\\t%2, %3\", operands);
8341 if (GET_CODE (operands[5]) == AND)
8342 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8343 else if (GET_CODE (operands[5]) == MINUS)
8344 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8345 else if (which_alternative != 0)
8346 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8347 return \"%i5%d4\\t%0, %1, #1\";
8349 [(set_attr "conds" "clob")
8350 (set_attr "length" "12")]
8353 (define_insn "*cond_sub"
8354 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8355 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8356 (match_operator:SI 4 "arm_comparison_operator"
8357 [(match_operand:SI 2 "s_register_operand" "r,r")
8358 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8359 (clobber (reg:CC CC_REGNUM))]
8362 output_asm_insn (\"cmp\\t%2, %3\", operands);
8363 if (which_alternative != 0)
8364 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8365 return \"sub%d4\\t%0, %1, #1\";
8367 [(set_attr "conds" "clob")
8368 (set_attr "length" "8,12")]
8371 (define_insn "*cmp_ite0"
8372 [(set (match_operand 6 "dominant_cc_register" "")
8375 (match_operator 4 "arm_comparison_operator"
8376 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8377 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8378 (match_operator:SI 5 "arm_comparison_operator"
8379 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8380 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8386 static const char * const opcodes[4][2] =
8388 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8389 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8390 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8391 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8392 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8393 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8394 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8395 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8398 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8400 return opcodes[which_alternative][swap];
8402 [(set_attr "conds" "set")
8403 (set_attr "length" "8")]
8406 (define_insn "*cmp_ite1"
8407 [(set (match_operand 6 "dominant_cc_register" "")
8410 (match_operator 4 "arm_comparison_operator"
8411 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8412 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8413 (match_operator:SI 5 "arm_comparison_operator"
8414 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8415 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8421 static const char * const opcodes[4][2] =
8423 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8424 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8425 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8426 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8427 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8428 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8429 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8430 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8433 comparison_dominates_p (GET_CODE (operands[5]),
8434 reverse_condition (GET_CODE (operands[4])));
8436 return opcodes[which_alternative][swap];
8438 [(set_attr "conds" "set")
8439 (set_attr "length" "8")]
8442 (define_insn "*cmp_and"
8443 [(set (match_operand 6 "dominant_cc_register" "")
8446 (match_operator 4 "arm_comparison_operator"
8447 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8448 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8449 (match_operator:SI 5 "arm_comparison_operator"
8450 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8451 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8456 static const char *const opcodes[4][2] =
8458 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8459 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8460 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8461 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8462 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8463 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8464 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8465 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8468 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8470 return opcodes[which_alternative][swap];
8472 [(set_attr "conds" "set")
8473 (set_attr "predicable" "no")
8474 (set_attr "length" "8")]
8477 (define_insn "*cmp_ior"
8478 [(set (match_operand 6 "dominant_cc_register" "")
8481 (match_operator 4 "arm_comparison_operator"
8482 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8483 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8484 (match_operator:SI 5 "arm_comparison_operator"
8485 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8486 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8491 static const char *const opcodes[4][2] =
8493 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8494 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8495 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8496 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8497 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8498 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8499 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8500 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8503 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8505 return opcodes[which_alternative][swap];
8508 [(set_attr "conds" "set")
8509 (set_attr "length" "8")]
8512 (define_insn_and_split "*ior_scc_scc"
8513 [(set (match_operand:SI 0 "s_register_operand" "=r")
8514 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8515 [(match_operand:SI 1 "s_register_operand" "r")
8516 (match_operand:SI 2 "arm_add_operand" "rIL")])
8517 (match_operator:SI 6 "arm_comparison_operator"
8518 [(match_operand:SI 4 "s_register_operand" "r")
8519 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8520 (clobber (reg:CC CC_REGNUM))]
8522 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8525 "TARGET_ARM && reload_completed"
8529 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8530 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8532 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8534 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8537 [(set_attr "conds" "clob")
8538 (set_attr "length" "16")])
8540 ; If the above pattern is followed by a CMP insn, then the compare is
8541 ; redundant, since we can rework the conditional instruction that follows.
8542 (define_insn_and_split "*ior_scc_scc_cmp"
8543 [(set (match_operand 0 "dominant_cc_register" "")
8544 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8545 [(match_operand:SI 1 "s_register_operand" "r")
8546 (match_operand:SI 2 "arm_add_operand" "rIL")])
8547 (match_operator:SI 6 "arm_comparison_operator"
8548 [(match_operand:SI 4 "s_register_operand" "r")
8549 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8551 (set (match_operand:SI 7 "s_register_operand" "=r")
8552 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8553 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8556 "TARGET_ARM && reload_completed"
8560 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8561 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8563 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8565 [(set_attr "conds" "set")
8566 (set_attr "length" "16")])
8568 (define_insn_and_split "*and_scc_scc"
8569 [(set (match_operand:SI 0 "s_register_operand" "=r")
8570 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8571 [(match_operand:SI 1 "s_register_operand" "r")
8572 (match_operand:SI 2 "arm_add_operand" "rIL")])
8573 (match_operator:SI 6 "arm_comparison_operator"
8574 [(match_operand:SI 4 "s_register_operand" "r")
8575 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8576 (clobber (reg:CC CC_REGNUM))]
8578 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8581 "TARGET_ARM && reload_completed
8582 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8587 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8588 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8590 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8592 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8595 [(set_attr "conds" "clob")
8596 (set_attr "length" "16")])
8598 ; If the above pattern is followed by a CMP insn, then the compare is
8599 ; redundant, since we can rework the conditional instruction that follows.
8600 (define_insn_and_split "*and_scc_scc_cmp"
8601 [(set (match_operand 0 "dominant_cc_register" "")
8602 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8603 [(match_operand:SI 1 "s_register_operand" "r")
8604 (match_operand:SI 2 "arm_add_operand" "rIL")])
8605 (match_operator:SI 6 "arm_comparison_operator"
8606 [(match_operand:SI 4 "s_register_operand" "r")
8607 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8609 (set (match_operand:SI 7 "s_register_operand" "=r")
8610 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8611 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8614 "TARGET_ARM && reload_completed"
8618 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8619 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8621 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8623 [(set_attr "conds" "set")
8624 (set_attr "length" "16")])
8626 ;; If there is no dominance in the comparison, then we can still save an
8627 ;; instruction in the AND case, since we can know that the second compare
8628 ;; need only zero the value if false (if true, then the value is already
8630 (define_insn_and_split "*and_scc_scc_nodom"
8631 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8632 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8633 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8634 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8635 (match_operator:SI 6 "arm_comparison_operator"
8636 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8637 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8638 (clobber (reg:CC CC_REGNUM))]
8640 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8643 "TARGET_ARM && reload_completed"
8644 [(parallel [(set (match_dup 0)
8645 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8646 (clobber (reg:CC CC_REGNUM))])
8647 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8649 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8652 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8653 operands[4], operands[5]),
8655 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8657 [(set_attr "conds" "clob")
8658 (set_attr "length" "20")])
8661 [(set (reg:CC_NOOV CC_REGNUM)
8662 (compare:CC_NOOV (ior:SI
8663 (and:SI (match_operand:SI 0 "s_register_operand" "")
8665 (match_operator:SI 1 "comparison_operator"
8666 [(match_operand:SI 2 "s_register_operand" "")
8667 (match_operand:SI 3 "arm_add_operand" "")]))
8669 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8672 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8674 (set (reg:CC_NOOV CC_REGNUM)
8675 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8680 [(set (reg:CC_NOOV CC_REGNUM)
8681 (compare:CC_NOOV (ior:SI
8682 (match_operator:SI 1 "comparison_operator"
8683 [(match_operand:SI 2 "s_register_operand" "")
8684 (match_operand:SI 3 "arm_add_operand" "")])
8685 (and:SI (match_operand:SI 0 "s_register_operand" "")
8688 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8691 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8693 (set (reg:CC_NOOV CC_REGNUM)
8694 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8698 (define_insn "*negscc"
8699 [(set (match_operand:SI 0 "s_register_operand" "=r")
8700 (neg:SI (match_operator 3 "arm_comparison_operator"
8701 [(match_operand:SI 1 "s_register_operand" "r")
8702 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8703 (clobber (reg:CC CC_REGNUM))]
8706 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8707 return \"mov\\t%0, %1, asr #31\";
8709 if (GET_CODE (operands[3]) == NE)
8710 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8712 if (GET_CODE (operands[3]) == GT)
8713 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8715 output_asm_insn (\"cmp\\t%1, %2\", operands);
8716 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8717 return \"mvn%d3\\t%0, #0\";
8719 [(set_attr "conds" "clob")
8720 (set_attr "length" "12")]
8723 (define_insn "movcond"
8724 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8726 (match_operator 5 "arm_comparison_operator"
8727 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8728 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8729 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8730 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8731 (clobber (reg:CC CC_REGNUM))]
8734 if (GET_CODE (operands[5]) == LT
8735 && (operands[4] == const0_rtx))
8737 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8739 if (operands[2] == const0_rtx)
8740 return \"and\\t%0, %1, %3, asr #31\";
8741 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8743 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8745 if (operands[1] == const0_rtx)
8746 return \"bic\\t%0, %2, %3, asr #31\";
8747 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8749 /* The only case that falls through to here is when both ops 1 & 2
8753 if (GET_CODE (operands[5]) == GE
8754 && (operands[4] == const0_rtx))
8756 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8758 if (operands[2] == const0_rtx)
8759 return \"bic\\t%0, %1, %3, asr #31\";
8760 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8762 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8764 if (operands[1] == const0_rtx)
8765 return \"and\\t%0, %2, %3, asr #31\";
8766 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8768 /* The only case that falls through to here is when both ops 1 & 2
8771 if (GET_CODE (operands[4]) == CONST_INT
8772 && !const_ok_for_arm (INTVAL (operands[4])))
8773 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8775 output_asm_insn (\"cmp\\t%3, %4\", operands);
8776 if (which_alternative != 0)
8777 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8778 if (which_alternative != 1)
8779 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8782 [(set_attr "conds" "clob")
8783 (set_attr "length" "8,8,12")]
8786 (define_insn "*ifcompare_plus_move"
8787 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8788 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8789 [(match_operand:SI 4 "s_register_operand" "r,r")
8790 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8792 (match_operand:SI 2 "s_register_operand" "r,r")
8793 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8794 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8795 (clobber (reg:CC CC_REGNUM))]
8798 [(set_attr "conds" "clob")
8799 (set_attr "length" "8,12")]
8802 (define_insn "*if_plus_move"
8803 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8805 (match_operator 4 "arm_comparison_operator"
8806 [(match_operand 5 "cc_register" "") (const_int 0)])
8808 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8809 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8810 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8814 sub%d4\\t%0, %2, #%n3
8815 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8816 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8817 [(set_attr "conds" "use")
8818 (set_attr "length" "4,4,8,8")
8819 (set_attr "type" "*,*,*,*")]
8822 (define_insn "*ifcompare_move_plus"
8823 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8824 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8825 [(match_operand:SI 4 "s_register_operand" "r,r")
8826 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8827 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8829 (match_operand:SI 2 "s_register_operand" "r,r")
8830 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8831 (clobber (reg:CC CC_REGNUM))]
8834 [(set_attr "conds" "clob")
8835 (set_attr "length" "8,12")]
8838 (define_insn "*if_move_plus"
8839 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8841 (match_operator 4 "arm_comparison_operator"
8842 [(match_operand 5 "cc_register" "") (const_int 0)])
8843 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8845 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8846 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8850 sub%D4\\t%0, %2, #%n3
8851 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8852 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8853 [(set_attr "conds" "use")
8854 (set_attr "length" "4,4,8,8")
8855 (set_attr "type" "*,*,*,*")]
8858 (define_insn "*ifcompare_arith_arith"
8859 [(set (match_operand:SI 0 "s_register_operand" "=r")
8860 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8861 [(match_operand:SI 5 "s_register_operand" "r")
8862 (match_operand:SI 6 "arm_add_operand" "rIL")])
8863 (match_operator:SI 8 "shiftable_operator"
8864 [(match_operand:SI 1 "s_register_operand" "r")
8865 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8866 (match_operator:SI 7 "shiftable_operator"
8867 [(match_operand:SI 3 "s_register_operand" "r")
8868 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8869 (clobber (reg:CC CC_REGNUM))]
8872 [(set_attr "conds" "clob")
8873 (set_attr "length" "12")]
8876 (define_insn "*if_arith_arith"
8877 [(set (match_operand:SI 0 "s_register_operand" "=r")
8878 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8879 [(match_operand 8 "cc_register" "") (const_int 0)])
8880 (match_operator:SI 6 "shiftable_operator"
8881 [(match_operand:SI 1 "s_register_operand" "r")
8882 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8883 (match_operator:SI 7 "shiftable_operator"
8884 [(match_operand:SI 3 "s_register_operand" "r")
8885 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8887 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8888 [(set_attr "conds" "use")
8889 (set_attr "length" "8")]
8892 (define_insn "*ifcompare_arith_move"
8893 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8894 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8895 [(match_operand:SI 2 "s_register_operand" "r,r")
8896 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8897 (match_operator:SI 7 "shiftable_operator"
8898 [(match_operand:SI 4 "s_register_operand" "r,r")
8899 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8900 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8901 (clobber (reg:CC CC_REGNUM))]
8904 /* If we have an operation where (op x 0) is the identity operation and
8905 the conditional operator is LT or GE and we are comparing against zero and
8906 everything is in registers then we can do this in two instructions. */
8907 if (operands[3] == const0_rtx
8908 && GET_CODE (operands[7]) != AND
8909 && GET_CODE (operands[5]) == REG
8910 && GET_CODE (operands[1]) == REG
8911 && REGNO (operands[1]) == REGNO (operands[4])
8912 && REGNO (operands[4]) != REGNO (operands[0]))
8914 if (GET_CODE (operands[6]) == LT)
8915 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8916 else if (GET_CODE (operands[6]) == GE)
8917 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8919 if (GET_CODE (operands[3]) == CONST_INT
8920 && !const_ok_for_arm (INTVAL (operands[3])))
8921 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8923 output_asm_insn (\"cmp\\t%2, %3\", operands);
8924 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8925 if (which_alternative != 0)
8926 return \"mov%D6\\t%0, %1\";
8929 [(set_attr "conds" "clob")
8930 (set_attr "length" "8,12")]
8933 (define_insn "*if_arith_move"
8934 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8935 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8936 [(match_operand 6 "cc_register" "") (const_int 0)])
8937 (match_operator:SI 5 "shiftable_operator"
8938 [(match_operand:SI 2 "s_register_operand" "r,r")
8939 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8940 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8944 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8945 [(set_attr "conds" "use")
8946 (set_attr "length" "4,8")
8947 (set_attr "type" "*,*")]
8950 (define_insn "*ifcompare_move_arith"
8951 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8952 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8953 [(match_operand:SI 4 "s_register_operand" "r,r")
8954 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8955 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8956 (match_operator:SI 7 "shiftable_operator"
8957 [(match_operand:SI 2 "s_register_operand" "r,r")
8958 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8959 (clobber (reg:CC CC_REGNUM))]
8962 /* If we have an operation where (op x 0) is the identity operation and
8963 the conditional operator is LT or GE and we are comparing against zero and
8964 everything is in registers then we can do this in two instructions */
8965 if (operands[5] == const0_rtx
8966 && GET_CODE (operands[7]) != AND
8967 && GET_CODE (operands[3]) == REG
8968 && GET_CODE (operands[1]) == REG
8969 && REGNO (operands[1]) == REGNO (operands[2])
8970 && REGNO (operands[2]) != REGNO (operands[0]))
8972 if (GET_CODE (operands[6]) == GE)
8973 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8974 else if (GET_CODE (operands[6]) == LT)
8975 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8978 if (GET_CODE (operands[5]) == CONST_INT
8979 && !const_ok_for_arm (INTVAL (operands[5])))
8980 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8982 output_asm_insn (\"cmp\\t%4, %5\", operands);
8984 if (which_alternative != 0)
8985 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8986 return \"%I7%D6\\t%0, %2, %3\";
8988 [(set_attr "conds" "clob")
8989 (set_attr "length" "8,12")]
8992 (define_insn "*if_move_arith"
8993 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8995 (match_operator 4 "arm_comparison_operator"
8996 [(match_operand 6 "cc_register" "") (const_int 0)])
8997 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8998 (match_operator:SI 5 "shiftable_operator"
8999 [(match_operand:SI 2 "s_register_operand" "r,r")
9000 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9004 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9005 [(set_attr "conds" "use")
9006 (set_attr "length" "4,8")
9007 (set_attr "type" "*,*")]
9010 (define_insn "*ifcompare_move_not"
9011 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9013 (match_operator 5 "arm_comparison_operator"
9014 [(match_operand:SI 3 "s_register_operand" "r,r")
9015 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9016 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9018 (match_operand:SI 2 "s_register_operand" "r,r"))))
9019 (clobber (reg:CC CC_REGNUM))]
9022 [(set_attr "conds" "clob")
9023 (set_attr "length" "8,12")]
9026 (define_insn "*if_move_not"
9027 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9029 (match_operator 4 "arm_comparison_operator"
9030 [(match_operand 3 "cc_register" "") (const_int 0)])
9031 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9032 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9036 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9037 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9038 [(set_attr "conds" "use")
9039 (set_attr "length" "4,8,8")]
9042 (define_insn "*ifcompare_not_move"
9043 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9045 (match_operator 5 "arm_comparison_operator"
9046 [(match_operand:SI 3 "s_register_operand" "r,r")
9047 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9049 (match_operand:SI 2 "s_register_operand" "r,r"))
9050 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9051 (clobber (reg:CC CC_REGNUM))]
9054 [(set_attr "conds" "clob")
9055 (set_attr "length" "8,12")]
9058 (define_insn "*if_not_move"
9059 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9061 (match_operator 4 "arm_comparison_operator"
9062 [(match_operand 3 "cc_register" "") (const_int 0)])
9063 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9064 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9068 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9069 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9070 [(set_attr "conds" "use")
9071 (set_attr "length" "4,8,8")]
9074 (define_insn "*ifcompare_shift_move"
9075 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9077 (match_operator 6 "arm_comparison_operator"
9078 [(match_operand:SI 4 "s_register_operand" "r,r")
9079 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9080 (match_operator:SI 7 "shift_operator"
9081 [(match_operand:SI 2 "s_register_operand" "r,r")
9082 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9083 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9084 (clobber (reg:CC CC_REGNUM))]
9087 [(set_attr "conds" "clob")
9088 (set_attr "length" "8,12")]
9091 (define_insn "*if_shift_move"
9092 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9094 (match_operator 5 "arm_comparison_operator"
9095 [(match_operand 6 "cc_register" "") (const_int 0)])
9096 (match_operator:SI 4 "shift_operator"
9097 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9098 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9099 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9103 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9104 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9105 [(set_attr "conds" "use")
9106 (set_attr "shift" "2")
9107 (set_attr "length" "4,8,8")
9108 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9109 (const_string "alu_shift")
9110 (const_string "alu_shift_reg")))]
9113 (define_insn "*ifcompare_move_shift"
9114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9116 (match_operator 6 "arm_comparison_operator"
9117 [(match_operand:SI 4 "s_register_operand" "r,r")
9118 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9119 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9120 (match_operator:SI 7 "shift_operator"
9121 [(match_operand:SI 2 "s_register_operand" "r,r")
9122 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9123 (clobber (reg:CC CC_REGNUM))]
9126 [(set_attr "conds" "clob")
9127 (set_attr "length" "8,12")]
9130 (define_insn "*if_move_shift"
9131 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9133 (match_operator 5 "arm_comparison_operator"
9134 [(match_operand 6 "cc_register" "") (const_int 0)])
9135 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9136 (match_operator:SI 4 "shift_operator"
9137 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9138 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9142 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9143 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9144 [(set_attr "conds" "use")
9145 (set_attr "shift" "2")
9146 (set_attr "length" "4,8,8")
9147 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
9148 (const_string "alu_shift")
9149 (const_string "alu_shift_reg")))]
9152 (define_insn "*ifcompare_shift_shift"
9153 [(set (match_operand:SI 0 "s_register_operand" "=r")
9155 (match_operator 7 "arm_comparison_operator"
9156 [(match_operand:SI 5 "s_register_operand" "r")
9157 (match_operand:SI 6 "arm_add_operand" "rIL")])
9158 (match_operator:SI 8 "shift_operator"
9159 [(match_operand:SI 1 "s_register_operand" "r")
9160 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9161 (match_operator:SI 9 "shift_operator"
9162 [(match_operand:SI 3 "s_register_operand" "r")
9163 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9164 (clobber (reg:CC CC_REGNUM))]
9167 [(set_attr "conds" "clob")
9168 (set_attr "length" "12")]
9171 (define_insn "*if_shift_shift"
9172 [(set (match_operand:SI 0 "s_register_operand" "=r")
9174 (match_operator 5 "arm_comparison_operator"
9175 [(match_operand 8 "cc_register" "") (const_int 0)])
9176 (match_operator:SI 6 "shift_operator"
9177 [(match_operand:SI 1 "s_register_operand" "r")
9178 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9179 (match_operator:SI 7 "shift_operator"
9180 [(match_operand:SI 3 "s_register_operand" "r")
9181 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9183 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9184 [(set_attr "conds" "use")
9185 (set_attr "shift" "1")
9186 (set_attr "length" "8")
9187 (set (attr "type") (if_then_else
9188 (and (match_operand 2 "const_int_operand" "")
9189 (match_operand 4 "const_int_operand" ""))
9190 (const_string "alu_shift")
9191 (const_string "alu_shift_reg")))]
9194 (define_insn "*ifcompare_not_arith"
9195 [(set (match_operand:SI 0 "s_register_operand" "=r")
9197 (match_operator 6 "arm_comparison_operator"
9198 [(match_operand:SI 4 "s_register_operand" "r")
9199 (match_operand:SI 5 "arm_add_operand" "rIL")])
9200 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9201 (match_operator:SI 7 "shiftable_operator"
9202 [(match_operand:SI 2 "s_register_operand" "r")
9203 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9204 (clobber (reg:CC CC_REGNUM))]
9207 [(set_attr "conds" "clob")
9208 (set_attr "length" "12")]
9211 (define_insn "*if_not_arith"
9212 [(set (match_operand:SI 0 "s_register_operand" "=r")
9214 (match_operator 5 "arm_comparison_operator"
9215 [(match_operand 4 "cc_register" "") (const_int 0)])
9216 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9217 (match_operator:SI 6 "shiftable_operator"
9218 [(match_operand:SI 2 "s_register_operand" "r")
9219 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9221 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9222 [(set_attr "conds" "use")
9223 (set_attr "length" "8")]
9226 (define_insn "*ifcompare_arith_not"
9227 [(set (match_operand:SI 0 "s_register_operand" "=r")
9229 (match_operator 6 "arm_comparison_operator"
9230 [(match_operand:SI 4 "s_register_operand" "r")
9231 (match_operand:SI 5 "arm_add_operand" "rIL")])
9232 (match_operator:SI 7 "shiftable_operator"
9233 [(match_operand:SI 2 "s_register_operand" "r")
9234 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9235 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9236 (clobber (reg:CC CC_REGNUM))]
9239 [(set_attr "conds" "clob")
9240 (set_attr "length" "12")]
9243 (define_insn "*if_arith_not"
9244 [(set (match_operand:SI 0 "s_register_operand" "=r")
9246 (match_operator 5 "arm_comparison_operator"
9247 [(match_operand 4 "cc_register" "") (const_int 0)])
9248 (match_operator:SI 6 "shiftable_operator"
9249 [(match_operand:SI 2 "s_register_operand" "r")
9250 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9251 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9253 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9254 [(set_attr "conds" "use")
9255 (set_attr "length" "8")]
9258 (define_insn "*ifcompare_neg_move"
9259 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9261 (match_operator 5 "arm_comparison_operator"
9262 [(match_operand:SI 3 "s_register_operand" "r,r")
9263 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9264 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9265 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9266 (clobber (reg:CC CC_REGNUM))]
9269 [(set_attr "conds" "clob")
9270 (set_attr "length" "8,12")]
9273 (define_insn "*if_neg_move"
9274 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9276 (match_operator 4 "arm_comparison_operator"
9277 [(match_operand 3 "cc_register" "") (const_int 0)])
9278 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9279 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9283 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9284 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9285 [(set_attr "conds" "use")
9286 (set_attr "length" "4,8,8")]
9289 (define_insn "*ifcompare_move_neg"
9290 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9292 (match_operator 5 "arm_comparison_operator"
9293 [(match_operand:SI 3 "s_register_operand" "r,r")
9294 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9295 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9296 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9297 (clobber (reg:CC CC_REGNUM))]
9300 [(set_attr "conds" "clob")
9301 (set_attr "length" "8,12")]
9304 (define_insn "*if_move_neg"
9305 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9307 (match_operator 4 "arm_comparison_operator"
9308 [(match_operand 3 "cc_register" "") (const_int 0)])
9309 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9310 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9314 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9315 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9316 [(set_attr "conds" "use")
9317 (set_attr "length" "4,8,8")]
9320 (define_insn "*arith_adjacentmem"
9321 [(set (match_operand:SI 0 "s_register_operand" "=r")
9322 (match_operator:SI 1 "shiftable_operator"
9323 [(match_operand:SI 2 "memory_operand" "m")
9324 (match_operand:SI 3 "memory_operand" "m")]))
9325 (clobber (match_scratch:SI 4 "=r"))]
9326 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9332 HOST_WIDE_INT val1 = 0, val2 = 0;
9334 if (REGNO (operands[0]) > REGNO (operands[4]))
9336 ldm[1] = operands[4];
9337 ldm[2] = operands[0];
9341 ldm[1] = operands[0];
9342 ldm[2] = operands[4];
9345 base_reg = XEXP (operands[2], 0);
9347 if (!REG_P (base_reg))
9349 val1 = INTVAL (XEXP (base_reg, 1));
9350 base_reg = XEXP (base_reg, 0);
9353 if (!REG_P (XEXP (operands[3], 0)))
9354 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9356 arith[0] = operands[0];
9357 arith[3] = operands[1];
9371 if (val1 !=0 && val2 != 0)
9373 if (val1 == 4 || val2 == 4)
9374 /* Other val must be 8, since we know they are adjacent and neither
9376 output_asm_insn (\"ldm%?ib\\t%0, {%1, %2}\", ldm);
9381 ldm[0] = ops[0] = operands[4];
9383 ops[2] = GEN_INT (val1);
9384 output_add_immediate (ops);
9386 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9388 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9394 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9396 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9401 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9403 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9405 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9408 [(set_attr "length" "12")
9409 (set_attr "predicable" "yes")
9410 (set_attr "type" "load1")]
9413 ;; the arm can support extended pre-inc instructions
9415 ;; In all these cases, we use operands 0 and 1 for the register being
9416 ;; incremented because those are the operands that local-alloc will
9417 ;; tie and these are the pair most likely to be tieable (and the ones
9418 ;; that will benefit the most).
9420 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9421 ;; elimination will cause too many headaches.
9423 (define_insn "*strqi_preinc"
9424 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9425 (match_operand:SI 2 "index_operand" "rJ")))
9426 (match_operand:QI 3 "s_register_operand" "r"))
9427 (set (match_operand:SI 0 "s_register_operand" "=r")
9428 (plus:SI (match_dup 1) (match_dup 2)))]
9430 && !arm_eliminable_register (operands[0])
9431 && !arm_eliminable_register (operands[1])
9432 && !arm_eliminable_register (operands[2])"
9433 "str%?b\\t%3, [%0, %2]!"
9434 [(set_attr "type" "store1")
9435 (set_attr "predicable" "yes")]
9438 (define_insn "*strqi_predec"
9439 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9440 (match_operand:SI 2 "s_register_operand" "r")))
9441 (match_operand:QI 3 "s_register_operand" "r"))
9442 (set (match_operand:SI 0 "s_register_operand" "=r")
9443 (minus:SI (match_dup 1) (match_dup 2)))]
9445 && !arm_eliminable_register (operands[0])
9446 && !arm_eliminable_register (operands[1])
9447 && !arm_eliminable_register (operands[2])"
9448 "str%?b\\t%3, [%0, -%2]!"
9449 [(set_attr "type" "store1")
9450 (set_attr "predicable" "yes")]
9453 (define_insn "*loadqi_preinc"
9454 [(set (match_operand:QI 3 "s_register_operand" "=r")
9455 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9456 (match_operand:SI 2 "index_operand" "rJ"))))
9457 (set (match_operand:SI 0 "s_register_operand" "=r")
9458 (plus:SI (match_dup 1) (match_dup 2)))]
9460 && !arm_eliminable_register (operands[0])
9461 && !arm_eliminable_register (operands[1])
9462 && !arm_eliminable_register (operands[2])"
9463 "ldr%?b\\t%3, [%0, %2]!"
9464 [(set_attr "type" "load_byte")
9465 (set_attr "predicable" "yes")]
9468 (define_insn "*loadqi_predec"
9469 [(set (match_operand:QI 3 "s_register_operand" "=r")
9470 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9471 (match_operand:SI 2 "s_register_operand" "r"))))
9472 (set (match_operand:SI 0 "s_register_operand" "=r")
9473 (minus:SI (match_dup 1) (match_dup 2)))]
9475 && !arm_eliminable_register (operands[0])
9476 && !arm_eliminable_register (operands[1])
9477 && !arm_eliminable_register (operands[2])"
9478 "ldr%?b\\t%3, [%0, -%2]!"
9479 [(set_attr "type" "load_byte")
9480 (set_attr "predicable" "yes")]
9483 (define_insn "*loadqisi_preinc"
9484 [(set (match_operand:SI 3 "s_register_operand" "=r")
9486 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9487 (match_operand:SI 2 "index_operand" "rJ")))))
9488 (set (match_operand:SI 0 "s_register_operand" "=r")
9489 (plus:SI (match_dup 1) (match_dup 2)))]
9491 && !arm_eliminable_register (operands[0])
9492 && !arm_eliminable_register (operands[1])
9493 && !arm_eliminable_register (operands[2])"
9494 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9495 [(set_attr "type" "load_byte")
9496 (set_attr "predicable" "yes")]
9499 (define_insn "*loadqisi_predec"
9500 [(set (match_operand:SI 3 "s_register_operand" "=r")
9502 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9503 (match_operand:SI 2 "s_register_operand" "r")))))
9504 (set (match_operand:SI 0 "s_register_operand" "=r")
9505 (minus:SI (match_dup 1) (match_dup 2)))]
9507 && !arm_eliminable_register (operands[0])
9508 && !arm_eliminable_register (operands[1])
9509 && !arm_eliminable_register (operands[2])"
9510 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9511 [(set_attr "type" "load_byte")
9512 (set_attr "predicable" "yes")]
9515 (define_insn "*strsi_preinc"
9516 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9517 (match_operand:SI 2 "index_operand" "rJ")))
9518 (match_operand:SI 3 "s_register_operand" "r"))
9519 (set (match_operand:SI 0 "s_register_operand" "=r")
9520 (plus:SI (match_dup 1) (match_dup 2)))]
9522 && !arm_eliminable_register (operands[0])
9523 && !arm_eliminable_register (operands[1])
9524 && !arm_eliminable_register (operands[2])"
9525 "str%?\\t%3, [%0, %2]!"
9526 [(set_attr "type" "store1")
9527 (set_attr "predicable" "yes")]
9530 (define_insn "*strsi_predec"
9531 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9532 (match_operand:SI 2 "s_register_operand" "r")))
9533 (match_operand:SI 3 "s_register_operand" "r"))
9534 (set (match_operand:SI 0 "s_register_operand" "=r")
9535 (minus:SI (match_dup 1) (match_dup 2)))]
9537 && !arm_eliminable_register (operands[0])
9538 && !arm_eliminable_register (operands[1])
9539 && !arm_eliminable_register (operands[2])"
9540 "str%?\\t%3, [%0, -%2]!"
9541 [(set_attr "type" "store1")
9542 (set_attr "predicable" "yes")]
9545 (define_insn "*loadsi_preinc"
9546 [(set (match_operand:SI 3 "s_register_operand" "=r")
9547 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9548 (match_operand:SI 2 "index_operand" "rJ"))))
9549 (set (match_operand:SI 0 "s_register_operand" "=r")
9550 (plus:SI (match_dup 1) (match_dup 2)))]
9552 && !arm_eliminable_register (operands[0])
9553 && !arm_eliminable_register (operands[1])
9554 && !arm_eliminable_register (operands[2])"
9555 "ldr%?\\t%3, [%0, %2]!"
9556 [(set_attr "type" "load1")
9557 (set_attr "predicable" "yes")]
9560 (define_insn "*loadsi_predec"
9561 [(set (match_operand:SI 3 "s_register_operand" "=r")
9562 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9563 (match_operand:SI 2 "s_register_operand" "r"))))
9564 (set (match_operand:SI 0 "s_register_operand" "=r")
9565 (minus:SI (match_dup 1) (match_dup 2)))]
9567 && !arm_eliminable_register (operands[0])
9568 && !arm_eliminable_register (operands[1])
9569 && !arm_eliminable_register (operands[2])"
9570 "ldr%?\\t%3, [%0, -%2]!"
9571 [(set_attr "type" "load1")
9572 (set_attr "predicable" "yes")]
9575 (define_insn "*strqi_shiftpreinc"
9576 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9577 [(match_operand:SI 3 "s_register_operand" "r")
9578 (match_operand:SI 4 "const_shift_operand" "n")])
9579 (match_operand:SI 1 "s_register_operand" "0")))
9580 (match_operand:QI 5 "s_register_operand" "r"))
9581 (set (match_operand:SI 0 "s_register_operand" "=r")
9582 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9585 && !arm_eliminable_register (operands[0])
9586 && !arm_eliminable_register (operands[1])
9587 && !arm_eliminable_register (operands[3])"
9588 "str%?b\\t%5, [%0, %3%S2]!"
9589 [(set_attr "type" "store1")
9590 (set_attr "predicable" "yes")]
9593 (define_insn "*strqi_shiftpredec"
9594 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9595 (match_operator:SI 2 "shift_operator"
9596 [(match_operand:SI 3 "s_register_operand" "r")
9597 (match_operand:SI 4 "const_shift_operand" "n")])))
9598 (match_operand:QI 5 "s_register_operand" "r"))
9599 (set (match_operand:SI 0 "s_register_operand" "=r")
9600 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9603 && !arm_eliminable_register (operands[0])
9604 && !arm_eliminable_register (operands[1])
9605 && !arm_eliminable_register (operands[3])"
9606 "str%?b\\t%5, [%0, -%3%S2]!"
9607 [(set_attr "type" "store1")
9608 (set_attr "predicable" "yes")]
9611 (define_insn "*loadqi_shiftpreinc"
9612 [(set (match_operand:QI 5 "s_register_operand" "=r")
9613 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9614 [(match_operand:SI 3 "s_register_operand" "r")
9615 (match_operand:SI 4 "const_shift_operand" "n")])
9616 (match_operand:SI 1 "s_register_operand" "0"))))
9617 (set (match_operand:SI 0 "s_register_operand" "=r")
9618 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9621 && !arm_eliminable_register (operands[0])
9622 && !arm_eliminable_register (operands[1])
9623 && !arm_eliminable_register (operands[3])"
9624 "ldr%?b\\t%5, [%0, %3%S2]!"
9625 [(set_attr "type" "load_byte")
9626 (set_attr "predicable" "yes")]
9629 (define_insn "*loadqi_shiftpredec"
9630 [(set (match_operand:QI 5 "s_register_operand" "=r")
9631 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9632 (match_operator:SI 2 "shift_operator"
9633 [(match_operand:SI 3 "s_register_operand" "r")
9634 (match_operand:SI 4 "const_shift_operand" "n")]))))
9635 (set (match_operand:SI 0 "s_register_operand" "=r")
9636 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9639 && !arm_eliminable_register (operands[0])
9640 && !arm_eliminable_register (operands[1])
9641 && !arm_eliminable_register (operands[3])"
9642 "ldr%?b\\t%5, [%0, -%3%S2]!"
9643 [(set_attr "type" "load_byte")
9644 (set_attr "predicable" "yes")]
9647 (define_insn "*strsi_shiftpreinc"
9648 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9649 [(match_operand:SI 3 "s_register_operand" "r")
9650 (match_operand:SI 4 "const_shift_operand" "n")])
9651 (match_operand:SI 1 "s_register_operand" "0")))
9652 (match_operand:SI 5 "s_register_operand" "r"))
9653 (set (match_operand:SI 0 "s_register_operand" "=r")
9654 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9657 && !arm_eliminable_register (operands[0])
9658 && !arm_eliminable_register (operands[1])
9659 && !arm_eliminable_register (operands[3])"
9660 "str%?\\t%5, [%0, %3%S2]!"
9661 [(set_attr "type" "store1")
9662 (set_attr "predicable" "yes")]
9665 (define_insn "*strsi_shiftpredec"
9666 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9667 (match_operator:SI 2 "shift_operator"
9668 [(match_operand:SI 3 "s_register_operand" "r")
9669 (match_operand:SI 4 "const_shift_operand" "n")])))
9670 (match_operand:SI 5 "s_register_operand" "r"))
9671 (set (match_operand:SI 0 "s_register_operand" "=r")
9672 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9675 && !arm_eliminable_register (operands[0])
9676 && !arm_eliminable_register (operands[1])
9677 && !arm_eliminable_register (operands[3])"
9678 "str%?\\t%5, [%0, -%3%S2]!"
9679 [(set_attr "type" "store1")
9680 (set_attr "predicable" "yes")]
9683 (define_insn "*loadsi_shiftpreinc"
9684 [(set (match_operand:SI 5 "s_register_operand" "=r")
9685 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9686 [(match_operand:SI 3 "s_register_operand" "r")
9687 (match_operand:SI 4 "const_shift_operand" "n")])
9688 (match_operand:SI 1 "s_register_operand" "0"))))
9689 (set (match_operand:SI 0 "s_register_operand" "=r")
9690 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9693 && !arm_eliminable_register (operands[0])
9694 && !arm_eliminable_register (operands[1])
9695 && !arm_eliminable_register (operands[3])"
9696 "ldr%?\\t%5, [%0, %3%S2]!"
9697 [(set_attr "type" "load1")
9698 (set_attr "predicable" "yes")]
9701 (define_insn "*loadsi_shiftpredec"
9702 [(set (match_operand:SI 5 "s_register_operand" "=r")
9703 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9704 (match_operator:SI 2 "shift_operator"
9705 [(match_operand:SI 3 "s_register_operand" "r")
9706 (match_operand:SI 4 "const_shift_operand" "n")]))))
9707 (set (match_operand:SI 0 "s_register_operand" "=r")
9708 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9711 && !arm_eliminable_register (operands[0])
9712 && !arm_eliminable_register (operands[1])
9713 && !arm_eliminable_register (operands[3])"
9714 "ldr%?\\t%5, [%0, -%3%S2]!"
9715 [(set_attr "type" "load1")
9716 (set_attr "predicable" "yes")])
9718 ; It can also support extended post-inc expressions, but combine doesn't
9720 ; It doesn't seem worth adding peepholes for anything but the most common
9721 ; cases since, unlike combine, the increment must immediately follow the load
9722 ; for this pattern to match.
9723 ; We must watch to see that the source/destination register isn't also the
9724 ; same as the base address register, and that if the index is a register,
9725 ; that it is not the same as the base address register. In such cases the
9726 ; instruction that we would generate would have UNPREDICTABLE behavior so
9730 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9731 (match_operand:QI 2 "s_register_operand" "r"))
9733 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9735 && (REGNO (operands[2]) != REGNO (operands[0]))
9736 && (GET_CODE (operands[1]) != REG
9737 || (REGNO (operands[1]) != REGNO (operands[0])))"
9738 "str%?b\\t%2, [%0], %1"
9742 [(set (match_operand:QI 0 "s_register_operand" "=r")
9743 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9745 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9747 && REGNO (operands[0]) != REGNO(operands[1])
9748 && (GET_CODE (operands[2]) != REG
9749 || REGNO(operands[0]) != REGNO (operands[2]))"
9750 "ldr%?b\\t%0, [%1], %2"
9754 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9755 (match_operand:SI 2 "s_register_operand" "r"))
9757 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9759 && (REGNO (operands[2]) != REGNO (operands[0]))
9760 && (GET_CODE (operands[1]) != REG
9761 || (REGNO (operands[1]) != REGNO (operands[0])))"
9762 "str%?\\t%2, [%0], %1"
9766 [(set (match_operand:SI 0 "s_register_operand" "=r")
9767 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9769 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9771 && REGNO (operands[0]) != REGNO(operands[1])
9772 && (GET_CODE (operands[2]) != REG
9773 || REGNO(operands[0]) != REGNO (operands[2]))"
9774 "ldr%?\\t%0, [%1], %2"
9778 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9779 (match_operand:SI 1 "index_operand" "rJ")))
9780 (match_operand:QI 2 "s_register_operand" "r"))
9781 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9783 && (REGNO (operands[2]) != REGNO (operands[0]))
9784 && (GET_CODE (operands[1]) != REG
9785 || (REGNO (operands[1]) != REGNO (operands[0])))"
9786 "str%?b\\t%2, [%0, %1]!"
9790 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9791 [(match_operand:SI 0 "s_register_operand" "r")
9792 (match_operand:SI 1 "const_int_operand" "n")])
9793 (match_operand:SI 2 "s_register_operand" "+r")))
9794 (match_operand:QI 3 "s_register_operand" "r"))
9795 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9798 && (REGNO (operands[3]) != REGNO (operands[2]))
9799 && (REGNO (operands[0]) != REGNO (operands[2]))"
9800 "str%?b\\t%3, [%2, %0%S4]!"
9803 ; This pattern is never tried by combine, so do it as a peephole
9806 [(set (match_operand:SI 0 "arm_general_register_operand" "")
9807 (match_operand:SI 1 "arm_general_register_operand" ""))
9808 (set (reg:CC CC_REGNUM)
9809 (compare:CC (match_dup 1) (const_int 0)))]
9811 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9812 (set (match_dup 0) (match_dup 1))])]
9816 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9817 ; reversed, check that the memory references aren't volatile.
9820 [(set (match_operand:SI 0 "s_register_operand" "=r")
9821 (match_operand:SI 4 "memory_operand" "m"))
9822 (set (match_operand:SI 1 "s_register_operand" "=r")
9823 (match_operand:SI 5 "memory_operand" "m"))
9824 (set (match_operand:SI 2 "s_register_operand" "=r")
9825 (match_operand:SI 6 "memory_operand" "m"))
9826 (set (match_operand:SI 3 "s_register_operand" "=r")
9827 (match_operand:SI 7 "memory_operand" "m"))]
9828 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9830 return emit_ldm_seq (operands, 4);
9835 [(set (match_operand:SI 0 "s_register_operand" "=r")
9836 (match_operand:SI 3 "memory_operand" "m"))
9837 (set (match_operand:SI 1 "s_register_operand" "=r")
9838 (match_operand:SI 4 "memory_operand" "m"))
9839 (set (match_operand:SI 2 "s_register_operand" "=r")
9840 (match_operand:SI 5 "memory_operand" "m"))]
9841 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9843 return emit_ldm_seq (operands, 3);
9848 [(set (match_operand:SI 0 "s_register_operand" "=r")
9849 (match_operand:SI 2 "memory_operand" "m"))
9850 (set (match_operand:SI 1 "s_register_operand" "=r")
9851 (match_operand:SI 3 "memory_operand" "m"))]
9852 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9854 return emit_ldm_seq (operands, 2);
9859 [(set (match_operand:SI 4 "memory_operand" "=m")
9860 (match_operand:SI 0 "s_register_operand" "r"))
9861 (set (match_operand:SI 5 "memory_operand" "=m")
9862 (match_operand:SI 1 "s_register_operand" "r"))
9863 (set (match_operand:SI 6 "memory_operand" "=m")
9864 (match_operand:SI 2 "s_register_operand" "r"))
9865 (set (match_operand:SI 7 "memory_operand" "=m")
9866 (match_operand:SI 3 "s_register_operand" "r"))]
9867 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9869 return emit_stm_seq (operands, 4);
9874 [(set (match_operand:SI 3 "memory_operand" "=m")
9875 (match_operand:SI 0 "s_register_operand" "r"))
9876 (set (match_operand:SI 4 "memory_operand" "=m")
9877 (match_operand:SI 1 "s_register_operand" "r"))
9878 (set (match_operand:SI 5 "memory_operand" "=m")
9879 (match_operand:SI 2 "s_register_operand" "r"))]
9880 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9882 return emit_stm_seq (operands, 3);
9887 [(set (match_operand:SI 2 "memory_operand" "=m")
9888 (match_operand:SI 0 "s_register_operand" "r"))
9889 (set (match_operand:SI 3 "memory_operand" "=m")
9890 (match_operand:SI 1 "s_register_operand" "r"))]
9891 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9893 return emit_stm_seq (operands, 2);
9898 [(set (match_operand:SI 0 "s_register_operand" "")
9899 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9901 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9902 [(match_operand:SI 3 "s_register_operand" "")
9903 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9904 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9906 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9907 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9912 ;; This split can be used because CC_Z mode implies that the following
9913 ;; branch will be an equality, or an unsigned inequality, so the sign
9914 ;; extension is not needed.
9917 [(set (reg:CC_Z CC_REGNUM)
9919 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9921 (match_operand 1 "const_int_operand" "")))
9922 (clobber (match_scratch:SI 2 ""))]
9924 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9925 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9926 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9927 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9929 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9933 (define_expand "prologue"
9934 [(clobber (const_int 0))]
9937 arm_expand_prologue ();
9939 thumb_expand_prologue ();
9944 (define_expand "epilogue"
9945 [(clobber (const_int 0))]
9948 if (current_function_calls_eh_return)
9949 emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
9951 thumb_expand_epilogue ();
9952 else if (USE_RETURN_INSN (FALSE))
9954 emit_jump_insn (gen_return ());
9957 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9959 gen_rtx_RETURN (VOIDmode)),
9965 ;; Note - although unspec_volatile's USE all hard registers,
9966 ;; USEs are ignored after relaod has completed. Thus we need
9967 ;; to add an unspec of the link register to ensure that flow
9968 ;; does not think that it is unused by the sibcall branch that
9969 ;; will replace the standard function epilogue.
9970 (define_insn "sibcall_epilogue"
9971 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9972 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9975 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9976 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9977 return arm_output_epilogue (next_nonnote_insn (insn));
9979 ;; Length is absolute worst case
9980 [(set_attr "length" "44")
9981 (set_attr "type" "block")
9982 ;; We don't clobber the conditions, but the potential length of this
9983 ;; operation is sufficient to make conditionalizing the sequence
9984 ;; unlikely to be profitable.
9985 (set_attr "conds" "clob")]
9988 (define_insn "*epilogue_insns"
9989 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9993 return arm_output_epilogue (NULL);
9994 else /* TARGET_THUMB */
9995 return thumb_unexpanded_epilogue ();
9997 ; Length is absolute worst case
9998 [(set_attr "length" "44")
9999 (set_attr "type" "block")
10000 ;; We don't clobber the conditions, but the potential length of this
10001 ;; operation is sufficient to make conditionalizing the sequence
10002 ;; unlikely to be profitable.
10003 (set_attr "conds" "clob")]
10006 (define_expand "eh_epilogue"
10007 [(use (match_operand:SI 0 "register_operand" ""))
10008 (use (match_operand:SI 1 "register_operand" ""))
10009 (use (match_operand:SI 2 "register_operand" ""))]
10013 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10014 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
10016 rtx ra = gen_rtx_REG (Pmode, 2);
10018 emit_move_insn (ra, operands[2]);
10021 /* This is a hack -- we may have crystalized the function type too
10023 cfun->machine->func_type = 0;
10027 ;; This split is only used during output to reduce the number of patterns
10028 ;; that need assembler instructions adding to them. We allowed the setting
10029 ;; of the conditions to be implicit during rtl generation so that
10030 ;; the conditional compare patterns would work. However this conflicts to
10031 ;; some extent with the conditional data operations, so we have to split them
10035 [(set (match_operand:SI 0 "s_register_operand" "")
10036 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10037 [(match_operand 2 "" "") (match_operand 3 "" "")])
10039 (match_operand 4 "" "")))
10040 (clobber (reg:CC CC_REGNUM))]
10041 "TARGET_ARM && reload_completed"
10042 [(set (match_dup 5) (match_dup 6))
10043 (cond_exec (match_dup 7)
10044 (set (match_dup 0) (match_dup 4)))]
10047 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10048 operands[2], operands[3]);
10049 enum rtx_code rc = GET_CODE (operands[1]);
10051 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10052 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10053 if (mode == CCFPmode || mode == CCFPEmode)
10054 rc = reverse_condition_maybe_unordered (rc);
10056 rc = reverse_condition (rc);
10058 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10063 [(set (match_operand:SI 0 "s_register_operand" "")
10064 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10065 [(match_operand 2 "" "") (match_operand 3 "" "")])
10066 (match_operand 4 "" "")
10068 (clobber (reg:CC CC_REGNUM))]
10069 "TARGET_ARM && reload_completed"
10070 [(set (match_dup 5) (match_dup 6))
10071 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10072 (set (match_dup 0) (match_dup 4)))]
10075 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10076 operands[2], operands[3]);
10078 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10079 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10084 [(set (match_operand:SI 0 "s_register_operand" "")
10085 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10086 [(match_operand 2 "" "") (match_operand 3 "" "")])
10087 (match_operand 4 "" "")
10088 (match_operand 5 "" "")))
10089 (clobber (reg:CC CC_REGNUM))]
10090 "TARGET_ARM && reload_completed"
10091 [(set (match_dup 6) (match_dup 7))
10092 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10093 (set (match_dup 0) (match_dup 4)))
10094 (cond_exec (match_dup 8)
10095 (set (match_dup 0) (match_dup 5)))]
10098 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10099 operands[2], operands[3]);
10100 enum rtx_code rc = GET_CODE (operands[1]);
10102 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10103 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10104 if (mode == CCFPmode || mode == CCFPEmode)
10105 rc = reverse_condition_maybe_unordered (rc);
10107 rc = reverse_condition (rc);
10109 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10114 [(set (match_operand:SI 0 "s_register_operand" "")
10115 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10116 [(match_operand:SI 2 "s_register_operand" "")
10117 (match_operand:SI 3 "arm_add_operand" "")])
10118 (match_operand:SI 4 "arm_rhs_operand" "")
10120 (match_operand:SI 5 "s_register_operand" ""))))
10121 (clobber (reg:CC CC_REGNUM))]
10122 "TARGET_ARM && reload_completed"
10123 [(set (match_dup 6) (match_dup 7))
10124 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10125 (set (match_dup 0) (match_dup 4)))
10126 (cond_exec (match_dup 8)
10127 (set (match_dup 0) (not:SI (match_dup 5))))]
10130 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10131 operands[2], operands[3]);
10132 enum rtx_code rc = GET_CODE (operands[1]);
10134 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10135 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10136 if (mode == CCFPmode || mode == CCFPEmode)
10137 rc = reverse_condition_maybe_unordered (rc);
10139 rc = reverse_condition (rc);
10141 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10145 (define_insn "*cond_move_not"
10146 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10147 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10148 [(match_operand 3 "cc_register" "") (const_int 0)])
10149 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10151 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10155 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10156 [(set_attr "conds" "use")
10157 (set_attr "length" "4,8")]
10160 ;; The next two patterns occur when an AND operation is followed by a
10161 ;; scc insn sequence
10163 (define_insn "*sign_extract_onebit"
10164 [(set (match_operand:SI 0 "s_register_operand" "=r")
10165 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10167 (match_operand:SI 2 "const_int_operand" "n")))
10168 (clobber (reg:CC CC_REGNUM))]
10171 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10172 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10173 return \"mvnne\\t%0, #0\";
10175 [(set_attr "conds" "clob")
10176 (set_attr "length" "8")]
10179 (define_insn "*not_signextract_onebit"
10180 [(set (match_operand:SI 0 "s_register_operand" "=r")
10182 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10184 (match_operand:SI 2 "const_int_operand" "n"))))
10185 (clobber (reg:CC CC_REGNUM))]
10188 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10189 output_asm_insn (\"tst\\t%1, %2\", operands);
10190 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10191 return \"movne\\t%0, #0\";
10193 [(set_attr "conds" "clob")
10194 (set_attr "length" "12")]
10197 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10198 ;; expressions. For simplicity, the first register is also in the unspec
10200 (define_insn "*push_multi"
10201 [(match_parallel 2 "multi_register_push"
10202 [(set (match_operand:BLK 0 "memory_operand" "=m")
10203 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10204 UNSPEC_PUSH_MULT))])]
10208 int num_saves = XVECLEN (operands[2], 0);
10210 /* For the StrongARM at least it is faster to
10211 use STR to store only a single register. */
10212 if (num_saves == 1)
10213 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10219 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10221 for (i = 1; i < num_saves; i++)
10223 strcat (pattern, \", %|\");
10225 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10228 strcat (pattern, \"}\");
10229 output_asm_insn (pattern, operands);
10234 [(set_attr "type" "store4")]
10237 (define_insn "stack_tie"
10238 [(set (mem:BLK (scratch))
10239 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10240 (match_operand:SI 1 "s_register_operand" "r")]
10244 [(set_attr "length" "0")]
10247 ;; Similarly for the floating point registers
10248 (define_insn "*push_fp_multi"
10249 [(match_parallel 2 "multi_register_push"
10250 [(set (match_operand:BLK 0 "memory_operand" "=m")
10251 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10252 UNSPEC_PUSH_MULT))])]
10253 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10258 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10259 output_asm_insn (pattern, operands);
10262 [(set_attr "type" "f_store")]
10265 ;; Special patterns for dealing with the constant pool
10267 (define_insn "align_4"
10268 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10271 assemble_align (32);
10276 (define_insn "align_8"
10277 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10280 assemble_align (64);
10285 (define_insn "consttable_end"
10286 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10289 making_const_table = FALSE;
10294 (define_insn "consttable_1"
10295 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10298 making_const_table = TRUE;
10299 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10300 assemble_zeros (3);
10303 [(set_attr "length" "4")]
10306 (define_insn "consttable_2"
10307 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10310 making_const_table = TRUE;
10311 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10312 assemble_zeros (2);
10315 [(set_attr "length" "4")]
10318 (define_insn "consttable_4"
10319 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10323 making_const_table = TRUE;
10324 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10329 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10330 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10334 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10339 [(set_attr "length" "4")]
10342 (define_insn "consttable_8"
10343 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10347 making_const_table = TRUE;
10348 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10353 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10354 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10358 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10363 [(set_attr "length" "8")]
10366 ;; Miscellaneous Thumb patterns
10368 (define_expand "tablejump"
10369 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10370 (use (label_ref (match_operand 1 "" "")))])]
10375 /* Hopefully, CSE will eliminate this copy. */
10376 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10377 rtx reg2 = gen_reg_rtx (SImode);
10379 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10380 operands[0] = reg2;
10385 ;; NB never uses BX.
10386 (define_insn "*thumb_tablejump"
10387 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10388 (use (label_ref (match_operand 1 "" "")))]
10391 [(set_attr "length" "2")]
10394 ;; V5 Instructions,
10396 (define_insn "clzsi2"
10397 [(set (match_operand:SI 0 "s_register_operand" "=r")
10398 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10399 "TARGET_ARM && arm_arch5"
10401 [(set_attr "predicable" "yes")])
10403 (define_expand "ffssi2"
10404 [(set (match_operand:SI 0 "s_register_operand" "")
10405 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10406 "TARGET_ARM && arm_arch5"
10411 t1 = gen_reg_rtx (SImode);
10412 t2 = gen_reg_rtx (SImode);
10413 t3 = gen_reg_rtx (SImode);
10415 emit_insn (gen_negsi2 (t1, operands[1]));
10416 emit_insn (gen_andsi3 (t2, operands[1], t1));
10417 emit_insn (gen_clzsi2 (t3, t2));
10418 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10423 (define_expand "ctzsi2"
10424 [(set (match_operand:SI 0 "s_register_operand" "")
10425 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10426 "TARGET_ARM && arm_arch5"
10431 t1 = gen_reg_rtx (SImode);
10432 t2 = gen_reg_rtx (SImode);
10433 t3 = gen_reg_rtx (SImode);
10435 emit_insn (gen_negsi2 (t1, operands[1]));
10436 emit_insn (gen_andsi3 (t2, operands[1], t1));
10437 emit_insn (gen_clzsi2 (t3, t2));
10438 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10443 ;; V5E instructions.
10445 (define_insn "prefetch"
10446 [(prefetch (match_operand:SI 0 "address_operand" "p")
10447 (match_operand:SI 1 "" "")
10448 (match_operand:SI 2 "" ""))]
10449 "TARGET_ARM && arm_arch5e"
10452 ;; General predication pattern
10455 [(match_operator 0 "arm_comparison_operator"
10456 [(match_operand 1 "cc_register" "")
10462 (define_insn "prologue_use"
10463 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10465 "%@ %0 needed for prologue"
10469 ;; Patterns for exception handling
10471 (define_expand "eh_return"
10472 [(use (match_operand 0 "general_operand" ""))]
10477 emit_insn (gen_arm_eh_return (operands[0]));
10479 emit_insn (gen_thumb_eh_return (operands[0]));
10484 ;; We can't expand this before we know where the link register is stored.
10485 (define_insn_and_split "arm_eh_return"
10486 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10488 (clobber (match_scratch:SI 1 "=&r"))]
10491 "&& reload_completed"
10495 arm_set_return_address (operands[0], operands[1]);
10500 (define_insn_and_split "thumb_eh_return"
10501 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
10503 (clobber (match_scratch:SI 1 "=&l"))]
10506 "&& reload_completed"
10510 thumb_set_return_address (operands[0], operands[1]);
10515 ;; Load the FPA co-processor patterns
10517 ;; Load the Maverick co-processor patterns
10518 (include "cirrus.md")
10519 ;; Load the Intel Wireless Multimedia Extension patterns
10520 (include "iwmmxt.md")
10521 ;; Load the VFP co-processor patterns