1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003 2004 Free Software Foundation, Inc.
4 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
5 ;; and Martin Simmons (@harleqn.co.uk).
6 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published
12 ;; by the Free Software Foundation; either version 2, or (at your
13 ;; option) any later version.
15 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 ;; License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;---------------------------------------------------------------------------
33 [(IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (CC_REGNUM 24) ; Condition code pseudo register
41 ;; 3rd operand to select_dominance_cc_mode
50 ;; Note: sin and cos are no-longer used.
53 [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT):
54 ; operand 0 is the result,
55 ; operand 1 the parameter.
56 (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT):
57 ; operand 0 is the result,
58 ; operand 1 the parameter.
59 (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
60 ; operand 0 is the first register,
61 ; subsequent registers are in parallel (use ...)
63 (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
64 ; usage, that is, we will add the pic_register
65 ; value to it before trying to dereference it.
66 (UNSPEC_PIC_BASE 4) ; Adding the PC value to the offset to the
67 ; GLOBAL_OFFSET_TABLE. The operation is fully
68 ; described by the RTL but must be wrapped to
69 ; prevent combine from trying to rip it apart.
70 (UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
71 ; being scheduled before the stack adjustment insn.
72 (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
73 ; this unspec is used to prevent the deletion of
74 ; instructions setting registers for EH handling
75 ; and stack frame generation. Operand 0 is the
77 (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
78 (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
79 (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
80 (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
81 (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
82 (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
83 (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
84 (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
85 (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
86 (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
87 (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
88 (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
89 (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
93 ;; UNSPEC_VOLATILE Usage:
96 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
98 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
99 ; instruction epilogue sequence that isn't expanded
100 ; into normal RTL. Used for both normal and sibcall
102 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
103 ; for inlined constants.
104 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
106 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
108 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
110 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
112 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
114 (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
115 (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
116 (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
117 (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
118 (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
119 (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
123 ;;---------------------------------------------------------------------------
126 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
127 ; generating ARM code. This is used to control the length of some insn
128 ; patterns that share the same RTL in both ARM and Thumb code.
129 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
131 ; PROG_MODE attribute is used to determine whether condition codes are
132 ; clobbered by a call insn: they are if in prog32 mode. This is controlled
133 ; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
134 (define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
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 (if_then_else (eq_attr "prog_mode" "prog32")
258 (const_string "clob") (const_string "nocond"))
259 (const_string "nocond")))
261 ; Predicable means that the insn can be conditionally executed based on
262 ; an automatically added predicate (additional patterns are generated by
263 ; gen...). We default to 'no' because no Thumb patterns match this rule
264 ; and not all ARM patterns do.
265 (define_attr "predicable" "no,yes" (const_string "no"))
267 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
268 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
269 ; suffer blockages enough to warrant modelling this (and it can adversely
270 ; affect the schedule).
271 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
273 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
274 ; to stall the processor. Used with model_wbuf above.
275 (define_attr "write_conflict" "no,yes"
276 (if_then_else (eq_attr "type"
277 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
279 (const_string "no")))
281 ; Classify the insns into those that take one cycle and those that take more
282 ; than one on the main cpu execution unit.
283 (define_attr "core_cycles" "single,multi"
284 (if_then_else (eq_attr "type"
285 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
286 (const_string "single")
287 (const_string "multi")))
289 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
290 ;; distant label. Only applicable to Thumb code.
291 (define_attr "far_jump" "yes,no" (const_string "no"))
293 ;;---------------------------------------------------------------------------
294 ;; Pipeline descriptions
296 ;; Processor type. This attribute must exactly match the table in
299 "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7m,arm7d,arm7dm,arm7di,arm7dmi,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7tdmi,arm710t,arm720t,arm740t,arm8,arm810,arm9,arm920,arm920t,arm940t,arm9tdmi,arm9e,ep9312,strongarm,strongarm110,strongarm1100,strongarm1110,arm10tdmi,arm1020t,arm926ejs,arm1026ejs,xscale,iwmmxt,arm1136js,arm1136jfs"
300 (const (symbol_ref "arm_tune")))
302 ;; True if the generic scheduling description should be used.
304 (define_attr "generic_sched" "yes,no"
306 (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
308 (const_string "yes")))
310 (include "arm-generic.md")
311 (include "arm926ejs.md")
312 (include "arm1026ejs.md")
313 (include "arm1136jfs.md")
316 ;;---------------------------------------------------------------------------
321 ;; Note: For DImode insns, there is normally no reason why operands should
322 ;; not be in the same register, what we don't want is for something being
323 ;; written to partially overlap something that is an input.
324 ;; Cirrus 64bit additions should not be split because we have a native
325 ;; 64bit addition instructions.
327 (define_expand "adddi3"
329 [(set (match_operand:DI 0 "s_register_operand" "")
330 (plus:DI (match_operand:DI 1 "s_register_operand" "")
331 (match_operand:DI 2 "s_register_operand" "")))
332 (clobber (reg:CC CC_REGNUM))])]
335 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
337 if (!cirrus_fp_register (operands[0], DImode))
338 operands[0] = force_reg (DImode, operands[0]);
339 if (!cirrus_fp_register (operands[1], DImode))
340 operands[1] = force_reg (DImode, operands[1]);
341 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
347 if (GET_CODE (operands[1]) != REG)
348 operands[1] = force_reg (SImode, operands[1]);
349 if (GET_CODE (operands[2]) != REG)
350 operands[2] = force_reg (SImode, operands[2]);
355 (define_insn "*thumb_adddi3"
356 [(set (match_operand:DI 0 "register_operand" "=l")
357 (plus:DI (match_operand:DI 1 "register_operand" "%0")
358 (match_operand:DI 2 "register_operand" "l")))
359 (clobber (reg:CC CC_REGNUM))
362 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
363 [(set_attr "length" "4")]
366 (define_insn_and_split "*arm_adddi3"
367 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
368 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
369 (match_operand:DI 2 "s_register_operand" "r, 0")))
370 (clobber (reg:CC CC_REGNUM))]
371 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
373 "TARGET_ARM && reload_completed"
374 [(parallel [(set (reg:CC_C CC_REGNUM)
375 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
377 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
378 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
379 (plus:SI (match_dup 4) (match_dup 5))))]
382 operands[3] = gen_highpart (SImode, operands[0]);
383 operands[0] = gen_lowpart (SImode, operands[0]);
384 operands[4] = gen_highpart (SImode, operands[1]);
385 operands[1] = gen_lowpart (SImode, operands[1]);
386 operands[5] = gen_highpart (SImode, operands[2]);
387 operands[2] = gen_lowpart (SImode, operands[2]);
389 [(set_attr "conds" "clob")
390 (set_attr "length" "8")]
393 (define_insn_and_split "*adddi_sesidi_di"
394 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
395 (plus:DI (sign_extend:DI
396 (match_operand:SI 2 "s_register_operand" "r,r"))
397 (match_operand:DI 1 "s_register_operand" "r,0")))
398 (clobber (reg:CC CC_REGNUM))]
399 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
401 "TARGET_ARM && reload_completed"
402 [(parallel [(set (reg:CC_C CC_REGNUM)
403 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
405 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
406 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
407 (plus:SI (ashiftrt:SI (match_dup 2)
412 operands[3] = gen_highpart (SImode, operands[0]);
413 operands[0] = gen_lowpart (SImode, operands[0]);
414 operands[4] = gen_highpart (SImode, operands[1]);
415 operands[1] = gen_lowpart (SImode, operands[1]);
416 operands[2] = gen_lowpart (SImode, operands[2]);
418 [(set_attr "conds" "clob")
419 (set_attr "length" "8")]
422 (define_insn_and_split "*adddi_zesidi_di"
423 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
424 (plus:DI (zero_extend:DI
425 (match_operand:SI 2 "s_register_operand" "r,r"))
426 (match_operand:DI 1 "s_register_operand" "r,0")))
427 (clobber (reg:CC CC_REGNUM))]
428 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
430 "TARGET_ARM && reload_completed"
431 [(parallel [(set (reg:CC_C CC_REGNUM)
432 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
434 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
435 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
436 (plus:SI (match_dup 4) (const_int 0))))]
439 operands[3] = gen_highpart (SImode, operands[0]);
440 operands[0] = gen_lowpart (SImode, operands[0]);
441 operands[4] = gen_highpart (SImode, operands[1]);
442 operands[1] = gen_lowpart (SImode, operands[1]);
443 operands[2] = gen_lowpart (SImode, operands[2]);
445 [(set_attr "conds" "clob")
446 (set_attr "length" "8")]
449 (define_expand "addsi3"
450 [(set (match_operand:SI 0 "s_register_operand" "")
451 (plus:SI (match_operand:SI 1 "s_register_operand" "")
452 (match_operand:SI 2 "reg_or_int_operand" "")))]
455 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
457 arm_split_constant (PLUS, SImode, NULL_RTX,
458 INTVAL (operands[2]), operands[0], operands[1],
459 (no_new_pseudos ? 0 : preserve_subexpressions_p ()));
465 ; If there is a scratch available, this will be faster than synthesizing the
468 [(match_scratch:SI 3 "r")
469 (set (match_operand:SI 0 "s_register_operand" "")
470 (plus:SI (match_operand:SI 1 "s_register_operand" "")
471 (match_operand:SI 2 "const_int_operand" "")))]
473 !(const_ok_for_arm (INTVAL (operands[2]))
474 || const_ok_for_arm (-INTVAL (operands[2])))
475 && const_ok_for_arm (~INTVAL (operands[2]))"
476 [(set (match_dup 3) (match_dup 2))
477 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
481 (define_insn_and_split "*arm_addsi3"
482 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
483 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
484 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
491 GET_CODE (operands[2]) == CONST_INT
492 && !(const_ok_for_arm (INTVAL (operands[2]))
493 || const_ok_for_arm (-INTVAL (operands[2])))"
494 [(clobber (const_int 0))]
496 arm_split_constant (PLUS, SImode, curr_insn,
497 INTVAL (operands[2]), operands[0],
501 [(set_attr "length" "4,4,16")
502 (set_attr "predicable" "yes")]
505 ;; Register group 'k' is a single register group containing only the stack
506 ;; register. Trying to reload it will always fail catastrophically,
507 ;; so never allow those alternatives to match if reloading is needed.
509 (define_insn "*thumb_addsi3"
510 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
511 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
512 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
515 static const char * const asms[] =
517 \"add\\t%0, %0, %2\",
518 \"sub\\t%0, %0, #%n2\",
519 \"add\\t%0, %1, %2\",
520 \"add\\t%0, %0, %2\",
521 \"add\\t%0, %0, %2\",
522 \"add\\t%0, %1, %2\",
525 if ((which_alternative == 2 || which_alternative == 6)
526 && GET_CODE (operands[2]) == CONST_INT
527 && INTVAL (operands[2]) < 0)
528 return \"sub\\t%0, %1, #%n2\";
529 return asms[which_alternative];
531 [(set_attr "length" "2")]
534 ;; Reloading and elimination of the frame pointer can
535 ;; sometimes cause this optimization to be missed.
537 [(set (match_operand:SI 0 "register_operand" "")
538 (match_operand:SI 1 "const_int_operand" ""))
540 (plus:SI (match_dup 0) (match_operand:SI 2 "register_operand" "")))]
542 && REGNO (operands[2]) == STACK_POINTER_REGNUM
543 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
544 && (INTVAL (operands[1]) & 3) == 0"
545 [(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
549 (define_insn "*addsi3_compare0"
550 [(set (reg:CC_NOOV CC_REGNUM)
552 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
553 (match_operand:SI 2 "arm_add_operand" "rI,L"))
555 (set (match_operand:SI 0 "s_register_operand" "=r,r")
556 (plus:SI (match_dup 1) (match_dup 2)))]
560 sub%?s\\t%0, %1, #%n2"
561 [(set_attr "conds" "set")]
564 (define_insn "*addsi3_compare0_scratch"
565 [(set (reg:CC_NOOV CC_REGNUM)
567 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
568 (match_operand:SI 1 "arm_add_operand" "rI,L"))
574 [(set_attr "conds" "set")]
577 ;; These patterns are the same ones as the two regular addsi3_compare0
578 ;; patterns, except we write them slightly different - the combiner
579 ;; tends to generate them this way.
580 (define_insn "*addsi3_compare0_for_combiner"
581 [(set (reg:CC CC_REGNUM)
583 (match_operand:SI 1 "s_register_operand" "r,r")
584 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
585 (set (match_operand:SI 0 "s_register_operand" "=r,r")
586 (plus:SI (match_dup 1) (match_dup 2)))]
590 sub%?s\\t%0, %1, #%n2"
591 [(set_attr "conds" "set")]
594 (define_insn "*addsi3_compare0_scratch_for_combiner"
595 [(set (reg:CC CC_REGNUM)
597 (match_operand:SI 0 "s_register_operand" "r,r")
598 (neg:SI (match_operand:SI 1 "arm_add_operand" "rI,L"))))]
603 [(set_attr "conds" "set")]
606 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
607 ;; addend is a constant.
608 (define_insn "*cmpsi2_addneg"
609 [(set (reg:CC CC_REGNUM)
611 (match_operand:SI 1 "s_register_operand" "r,r")
612 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
613 (set (match_operand:SI 0 "s_register_operand" "=r,r")
614 (plus:SI (match_dup 1)
615 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
616 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
619 add%?s\\t%0, %1, #%n2"
620 [(set_attr "conds" "set")]
623 ;; Convert the sequence
625 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
629 ;; bcs dest ((unsigned)rn >= 1)
630 ;; similarly for the beq variant using bcc.
631 ;; This is a common looping idiom (while (n--))
633 [(set (match_operand:SI 0 "s_register_operand" "")
634 (plus:SI (match_operand:SI 1 "s_register_operand" "")
636 (set (match_operand 2 "cc_register" "")
637 (compare (match_dup 0) (const_int -1)))
639 (if_then_else (match_operator 3 "equality_operator"
640 [(match_dup 2) (const_int 0)])
641 (match_operand 4 "" "")
642 (match_operand 5 "" "")))]
643 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
647 (match_dup 1) (const_int 1)))
648 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
650 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
653 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
654 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
657 operands[2], const0_rtx);"
660 ;; The next four insns work because they compare the result with one of
661 ;; the operands, and we know that the use of the condition code is
662 ;; either GEU or LTU, so we can use the carry flag from the addition
663 ;; instead of doing the compare a second time.
664 (define_insn "*addsi3_compare_op1"
665 [(set (reg:CC_C CC_REGNUM)
667 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
668 (match_operand:SI 2 "arm_add_operand" "rI,L"))
670 (set (match_operand:SI 0 "s_register_operand" "=r,r")
671 (plus:SI (match_dup 1) (match_dup 2)))]
675 sub%?s\\t%0, %1, #%n2"
676 [(set_attr "conds" "set")]
679 (define_insn "*addsi3_compare_op2"
680 [(set (reg:CC_C CC_REGNUM)
682 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
683 (match_operand:SI 2 "arm_add_operand" "rI,L"))
685 (set (match_operand:SI 0 "s_register_operand" "=r,r")
686 (plus:SI (match_dup 1) (match_dup 2)))]
690 sub%?s\\t%0, %1, #%n2"
691 [(set_attr "conds" "set")]
694 (define_insn "*compare_addsi2_op0"
695 [(set (reg:CC_C CC_REGNUM)
697 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
698 (match_operand:SI 1 "arm_add_operand" "rI,L"))
704 [(set_attr "conds" "set")]
707 (define_insn "*compare_addsi2_op1"
708 [(set (reg:CC_C CC_REGNUM)
710 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
711 (match_operand:SI 1 "arm_add_operand" "rI,L"))
717 [(set_attr "conds" "set")]
720 (define_insn "*addsi3_carryin"
721 [(set (match_operand:SI 0 "s_register_operand" "=r")
722 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
723 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
724 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
727 [(set_attr "conds" "use")]
730 (define_insn "*addsi3_carryin_shift"
731 [(set (match_operand:SI 0 "s_register_operand" "=r")
732 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
734 (match_operator:SI 2 "shift_operator"
735 [(match_operand:SI 3 "s_register_operand" "r")
736 (match_operand:SI 4 "reg_or_int_operand" "rM")])
737 (match_operand:SI 1 "s_register_operand" "r"))))]
739 "adc%?\\t%0, %1, %3%S2"
740 [(set_attr "conds" "use")
741 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
742 (const_string "alu_shift")
743 (const_string "alu_shift_reg")))]
746 (define_insn "*addsi3_carryin_alt1"
747 [(set (match_operand:SI 0 "s_register_operand" "=r")
748 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
749 (match_operand:SI 2 "arm_rhs_operand" "rI"))
750 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
753 [(set_attr "conds" "use")]
756 (define_insn "*addsi3_carryin_alt2"
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 1 "s_register_operand" "r"))
760 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
763 [(set_attr "conds" "use")]
766 (define_insn "*addsi3_carryin_alt3"
767 [(set (match_operand:SI 0 "s_register_operand" "=r")
768 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
769 (match_operand:SI 2 "arm_rhs_operand" "rI"))
770 (match_operand:SI 1 "s_register_operand" "r")))]
773 [(set_attr "conds" "use")]
776 (define_insn "incscc"
777 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
778 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
779 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
780 (match_operand:SI 1 "s_register_operand" "0,?r")))]
784 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
785 [(set_attr "conds" "use")
786 (set_attr "length" "4,8")]
789 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
791 [(set (match_operand:SI 0 "s_register_operand" "")
792 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
793 (match_operand:SI 2 "s_register_operand" ""))
795 (clobber (match_operand:SI 3 "s_register_operand" ""))]
797 [(set (match_dup 3) (match_dup 1))
798 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
800 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
803 (define_expand "addsf3"
804 [(set (match_operand:SF 0 "s_register_operand" "")
805 (plus:SF (match_operand:SF 1 "s_register_operand" "")
806 (match_operand:SF 2 "arm_float_add_operand" "")))]
807 "TARGET_ARM && TARGET_HARD_FLOAT"
810 && !cirrus_fp_register (operands[2], SFmode))
811 operands[2] = force_reg (SFmode, operands[2]);
814 (define_expand "adddf3"
815 [(set (match_operand:DF 0 "s_register_operand" "")
816 (plus:DF (match_operand:DF 1 "s_register_operand" "")
817 (match_operand:DF 2 "arm_float_add_operand" "")))]
818 "TARGET_ARM && TARGET_HARD_FLOAT"
821 && !cirrus_fp_register (operands[2], DFmode))
822 operands[2] = force_reg (DFmode, operands[2]);
825 (define_expand "subdi3"
827 [(set (match_operand:DI 0 "s_register_operand" "")
828 (minus:DI (match_operand:DI 1 "s_register_operand" "")
829 (match_operand:DI 2 "s_register_operand" "")))
830 (clobber (reg:CC CC_REGNUM))])]
833 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
835 && cirrus_fp_register (operands[0], DImode)
836 && cirrus_fp_register (operands[1], DImode))
838 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
844 if (GET_CODE (operands[1]) != REG)
845 operands[1] = force_reg (SImode, operands[1]);
846 if (GET_CODE (operands[2]) != REG)
847 operands[2] = force_reg (SImode, operands[2]);
852 (define_insn "*arm_subdi3"
853 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
854 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
855 (match_operand:DI 2 "s_register_operand" "r,0,0")))
856 (clobber (reg:CC CC_REGNUM))]
858 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
859 [(set_attr "conds" "clob")
860 (set_attr "length" "8")]
863 (define_insn "*thumb_subdi3"
864 [(set (match_operand:DI 0 "register_operand" "=l")
865 (minus:DI (match_operand:DI 1 "register_operand" "0")
866 (match_operand:DI 2 "register_operand" "l")))
867 (clobber (reg:CC CC_REGNUM))]
869 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
870 [(set_attr "length" "4")]
873 (define_insn "*subdi_di_zesidi"
874 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
875 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
877 (match_operand:SI 2 "s_register_operand" "r,r"))))
878 (clobber (reg:CC CC_REGNUM))]
880 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
881 [(set_attr "conds" "clob")
882 (set_attr "length" "8")]
885 (define_insn "*subdi_di_sesidi"
886 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
887 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
889 (match_operand:SI 2 "s_register_operand" "r,r"))))
890 (clobber (reg:CC CC_REGNUM))]
892 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
893 [(set_attr "conds" "clob")
894 (set_attr "length" "8")]
897 (define_insn "*subdi_zesidi_di"
898 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
899 (minus:DI (zero_extend:DI
900 (match_operand:SI 2 "s_register_operand" "r,r"))
901 (match_operand:DI 1 "s_register_operand" "?r,0")))
902 (clobber (reg:CC CC_REGNUM))]
904 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
905 [(set_attr "conds" "clob")
906 (set_attr "length" "8")]
909 (define_insn "*subdi_sesidi_di"
910 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
911 (minus:DI (sign_extend:DI
912 (match_operand:SI 2 "s_register_operand" "r,r"))
913 (match_operand:DI 1 "s_register_operand" "?r,0")))
914 (clobber (reg:CC CC_REGNUM))]
916 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
917 [(set_attr "conds" "clob")
918 (set_attr "length" "8")]
921 (define_insn "*subdi_zesidi_zesidi"
922 [(set (match_operand:DI 0 "s_register_operand" "=r")
923 (minus:DI (zero_extend:DI
924 (match_operand:SI 1 "s_register_operand" "r"))
926 (match_operand:SI 2 "s_register_operand" "r"))))
927 (clobber (reg:CC CC_REGNUM))]
929 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
930 [(set_attr "conds" "clob")
931 (set_attr "length" "8")]
934 (define_expand "subsi3"
935 [(set (match_operand:SI 0 "s_register_operand" "")
936 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
937 (match_operand:SI 2 "s_register_operand" "")))]
940 if (GET_CODE (operands[1]) == CONST_INT)
944 arm_split_constant (MINUS, SImode, NULL_RTX,
945 INTVAL (operands[1]), operands[0],
948 : preserve_subexpressions_p ()));
951 else /* TARGET_THUMB */
952 operands[1] = force_reg (SImode, operands[1]);
957 (define_insn "*thumb_subsi3_insn"
958 [(set (match_operand:SI 0 "register_operand" "=l")
959 (minus:SI (match_operand:SI 1 "register_operand" "l")
960 (match_operand:SI 2 "register_operand" "l")))]
963 [(set_attr "length" "2")]
966 (define_insn_and_split "*arm_subsi3_insn"
967 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
968 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
969 (match_operand:SI 2 "s_register_operand" "r,r")))]
975 && GET_CODE (operands[1]) == CONST_INT
976 && !const_ok_for_arm (INTVAL (operands[1]))"
977 [(clobber (const_int 0))]
979 arm_split_constant (MINUS, SImode, curr_insn,
980 INTVAL (operands[1]), operands[0], operands[2], 0);
983 [(set_attr "length" "4,16")
984 (set_attr "predicable" "yes")]
988 [(match_scratch:SI 3 "r")
989 (set (match_operand:SI 0 "s_register_operand" "")
990 (minus:SI (match_operand:SI 1 "const_int_operand" "")
991 (match_operand:SI 2 "s_register_operand" "")))]
993 && !const_ok_for_arm (INTVAL (operands[1]))
994 && const_ok_for_arm (~INTVAL (operands[1]))"
995 [(set (match_dup 3) (match_dup 1))
996 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1000 (define_insn "*subsi3_compare0"
1001 [(set (reg:CC_NOOV CC_REGNUM)
1003 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1004 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1006 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1007 (minus:SI (match_dup 1) (match_dup 2)))]
1011 rsb%?s\\t%0, %2, %1"
1012 [(set_attr "conds" "set")]
1015 (define_insn "decscc"
1016 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1017 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1018 (match_operator:SI 2 "arm_comparison_operator"
1019 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1023 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1024 [(set_attr "conds" "use")
1025 (set_attr "length" "*,8")]
1028 (define_expand "subsf3"
1029 [(set (match_operand:SF 0 "s_register_operand" "")
1030 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1031 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1032 "TARGET_ARM && TARGET_HARD_FLOAT"
1034 if (TARGET_MAVERICK)
1036 if (!cirrus_fp_register (operands[1], SFmode))
1037 operands[1] = force_reg (SFmode, operands[1]);
1038 if (!cirrus_fp_register (operands[2], SFmode))
1039 operands[2] = force_reg (SFmode, operands[2]);
1043 (define_expand "subdf3"
1044 [(set (match_operand:DF 0 "s_register_operand" "")
1045 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1046 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1047 "TARGET_ARM && TARGET_HARD_FLOAT"
1049 if (TARGET_MAVERICK)
1051 if (!cirrus_fp_register (operands[1], DFmode))
1052 operands[1] = force_reg (DFmode, operands[1]);
1053 if (!cirrus_fp_register (operands[2], DFmode))
1054 operands[2] = force_reg (DFmode, operands[2]);
1059 ;; Multiplication insns
1061 (define_expand "mulsi3"
1062 [(set (match_operand:SI 0 "s_register_operand" "")
1063 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1064 (match_operand:SI 1 "s_register_operand" "")))]
1069 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1070 (define_insn "*arm_mulsi3"
1071 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1072 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1073 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1075 "mul%?\\t%0, %2, %1"
1076 [(set_attr "insn" "mul")
1077 (set_attr "predicable" "yes")]
1080 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1081 ; 1 and 2; are the same, because reload will make operand 0 match
1082 ; operand 1 without realizing that this conflicts with operand 2. We fix
1083 ; this by adding another alternative to match this case, and then `reload'
1084 ; it ourselves. This alternative must come first.
1085 (define_insn "*thumb_mulsi3"
1086 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1087 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1088 (match_operand:SI 2 "register_operand" "l,l,l")))]
1091 if (which_alternative < 2)
1092 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1094 return \"mul\\t%0, %0, %2\";
1096 [(set_attr "length" "4,4,2")
1097 (set_attr "insn" "mul")]
1100 (define_insn "*mulsi3_compare0"
1101 [(set (reg:CC_NOOV CC_REGNUM)
1102 (compare:CC_NOOV (mult:SI
1103 (match_operand:SI 2 "s_register_operand" "r,r")
1104 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1106 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1107 (mult:SI (match_dup 2) (match_dup 1)))]
1108 "TARGET_ARM && !arm_arch_xscale"
1109 "mul%?s\\t%0, %2, %1"
1110 [(set_attr "conds" "set")
1111 (set_attr "insn" "muls")]
1114 (define_insn "*mulsi_compare0_scratch"
1115 [(set (reg:CC_NOOV CC_REGNUM)
1116 (compare:CC_NOOV (mult:SI
1117 (match_operand:SI 2 "s_register_operand" "r,r")
1118 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1120 (clobber (match_scratch:SI 0 "=&r,&r"))]
1121 "TARGET_ARM && !arm_arch_xscale"
1122 "mul%?s\\t%0, %2, %1"
1123 [(set_attr "conds" "set")
1124 (set_attr "insn" "muls")]
1127 ;; Unnamed templates to match MLA instruction.
1129 (define_insn "*mulsi3addsi"
1130 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1132 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1133 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1134 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1136 "mla%?\\t%0, %2, %1, %3"
1137 [(set_attr "insn" "mla")
1138 (set_attr "predicable" "yes")]
1141 (define_insn "*mulsi3addsi_compare0"
1142 [(set (reg:CC_NOOV CC_REGNUM)
1145 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1146 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1147 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1149 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1150 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1152 "TARGET_ARM && !arm_arch_xscale"
1153 "mla%?s\\t%0, %2, %1, %3"
1154 [(set_attr "conds" "set")
1155 (set_attr "insn" "mlas")]
1158 (define_insn "*mulsi3addsi_compare0_scratch"
1159 [(set (reg:CC_NOOV CC_REGNUM)
1162 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1163 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1164 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1166 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1167 "TARGET_ARM && !arm_arch_xscale"
1168 "mla%?s\\t%0, %2, %1, %3"
1169 [(set_attr "conds" "set")
1170 (set_attr "insn" "mlas")]
1173 ;; Unnamed template to match long long multiply-accumulate (smlal)
1175 (define_insn "*mulsidi3adddi"
1176 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1179 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1180 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1181 (match_operand:DI 1 "s_register_operand" "0")))]
1182 "TARGET_ARM && arm_arch3m"
1183 "smlal%?\\t%Q0, %R0, %3, %2"
1184 [(set_attr "insn" "smlal")
1185 (set_attr "predicable" "yes")]
1188 (define_insn "mulsidi3"
1189 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1191 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1192 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1193 "TARGET_ARM && arm_arch3m"
1194 "smull%?\\t%Q0, %R0, %1, %2"
1195 [(set_attr "insn" "smull")
1196 (set_attr "predicable" "yes")]
1199 (define_insn "umulsidi3"
1200 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1202 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1203 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1204 "TARGET_ARM && arm_arch3m"
1205 "umull%?\\t%Q0, %R0, %1, %2"
1206 [(set_attr "insn" "umull")
1207 (set_attr "predicable" "yes")]
1210 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1212 (define_insn "*umulsidi3adddi"
1213 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1216 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1217 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1218 (match_operand:DI 1 "s_register_operand" "0")))]
1219 "TARGET_ARM && arm_arch3m"
1220 "umlal%?\\t%Q0, %R0, %3, %2"
1221 [(set_attr "insn" "umlal")
1222 (set_attr "predicable" "yes")]
1225 (define_insn "smulsi3_highpart"
1226 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1230 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1231 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1233 (clobber (match_scratch:SI 3 "=&r,&r"))]
1234 "TARGET_ARM && arm_arch3m"
1235 "smull%?\\t%3, %0, %2, %1"
1236 [(set_attr "insn" "smull")
1237 (set_attr "predicable" "yes")]
1240 (define_insn "umulsi3_highpart"
1241 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1245 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1246 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1248 (clobber (match_scratch:SI 3 "=&r,&r"))]
1249 "TARGET_ARM && arm_arch3m"
1250 "umull%?\\t%3, %0, %2, %1"
1251 [(set_attr "insn" "umull")
1252 (set_attr "predicable" "yes")]
1255 (define_insn "mulhisi3"
1256 [(set (match_operand:SI 0 "s_register_operand" "=r")
1257 (mult:SI (sign_extend:SI
1258 (match_operand:HI 1 "s_register_operand" "%r"))
1260 (match_operand:HI 2 "s_register_operand" "r"))))]
1261 "TARGET_ARM && arm_arch5e"
1262 "smulbb%?\\t%0, %1, %2"
1263 [(set_attr "insn" "smulxy")
1264 (set_attr "predicable" "yes")]
1267 (define_insn "*mulhisi3tb"
1268 [(set (match_operand:SI 0 "s_register_operand" "=r")
1269 (mult:SI (ashiftrt:SI
1270 (match_operand:SI 1 "s_register_operand" "r")
1273 (match_operand:HI 2 "s_register_operand" "r"))))]
1274 "TARGET_ARM && arm_arch5e"
1275 "smultb%?\\t%0, %1, %2"
1276 [(set_attr "insn" "smulxy")
1277 (set_attr "predicable" "yes")]
1280 (define_insn "*mulhisi3bt"
1281 [(set (match_operand:SI 0 "s_register_operand" "=r")
1282 (mult:SI (sign_extend:SI
1283 (match_operand:HI 1 "s_register_operand" "r"))
1285 (match_operand:SI 2 "s_register_operand" "r")
1287 "TARGET_ARM && arm_arch5e"
1288 "smulbt%?\\t%0, %1, %2"
1289 [(set_attr "insn" "smulxy")
1290 (set_attr "predicable" "yes")]
1293 (define_insn "*mulhisi3tt"
1294 [(set (match_operand:SI 0 "s_register_operand" "=r")
1295 (mult:SI (ashiftrt:SI
1296 (match_operand:SI 1 "s_register_operand" "r")
1299 (match_operand:SI 2 "s_register_operand" "r")
1301 "TARGET_ARM && arm_arch5e"
1302 "smultt%?\\t%0, %1, %2"
1303 [(set_attr "insn" "smulxy")
1304 (set_attr "predicable" "yes")]
1307 (define_insn "*mulhisi3addsi"
1308 [(set (match_operand:SI 0 "s_register_operand" "=r")
1309 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1310 (mult:SI (sign_extend:SI
1311 (match_operand:HI 2 "s_register_operand" "%r"))
1313 (match_operand:HI 3 "s_register_operand" "r")))))]
1314 "TARGET_ARM && arm_arch5e"
1315 "smlabb%?\\t%0, %2, %3, %1"
1316 [(set_attr "insn" "smlaxy")
1317 (set_attr "predicable" "yes")]
1320 (define_insn "*mulhidi3adddi"
1321 [(set (match_operand:DI 0 "s_register_operand" "=r")
1323 (match_operand:DI 1 "s_register_operand" "0")
1324 (mult:DI (sign_extend:DI
1325 (match_operand:HI 2 "s_register_operand" "%r"))
1327 (match_operand:HI 3 "s_register_operand" "r")))))]
1328 "TARGET_ARM && arm_arch5e"
1329 "smlalbb%?\\t%Q0, %R0, %2, %3"
1330 [(set_attr "insn" "smlalxy")
1331 (set_attr "predicable" "yes")])
1333 (define_expand "mulsf3"
1334 [(set (match_operand:SF 0 "s_register_operand" "")
1335 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1336 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1337 "TARGET_ARM && TARGET_HARD_FLOAT"
1340 && !cirrus_fp_register (operands[2], SFmode))
1341 operands[2] = force_reg (SFmode, operands[2]);
1344 (define_expand "muldf3"
1345 [(set (match_operand:DF 0 "s_register_operand" "")
1346 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1347 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1348 "TARGET_ARM && TARGET_HARD_FLOAT"
1351 && !cirrus_fp_register (operands[2], DFmode))
1352 operands[2] = force_reg (DFmode, operands[2]);
1357 (define_expand "divsf3"
1358 [(set (match_operand:SF 0 "s_register_operand" "")
1359 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1360 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1361 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1364 (define_expand "divdf3"
1365 [(set (match_operand:DF 0 "s_register_operand" "")
1366 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1367 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1368 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1373 (define_expand "modsf3"
1374 [(set (match_operand:SF 0 "s_register_operand" "")
1375 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1376 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1377 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1380 (define_expand "moddf3"
1381 [(set (match_operand:DF 0 "s_register_operand" "")
1382 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1383 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1384 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1387 ;; Boolean and,ior,xor insns
1389 ;; Split up double word logical operations
1391 ;; Split up simple DImode logical operations. Simply perform the logical
1392 ;; operation on the upper and lower halves of the registers.
1394 [(set (match_operand:DI 0 "s_register_operand" "")
1395 (match_operator:DI 6 "logical_binary_operator"
1396 [(match_operand:DI 1 "s_register_operand" "")
1397 (match_operand:DI 2 "s_register_operand" "")]))]
1398 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1399 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1400 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1403 operands[3] = gen_highpart (SImode, operands[0]);
1404 operands[0] = gen_lowpart (SImode, operands[0]);
1405 operands[4] = gen_highpart (SImode, operands[1]);
1406 operands[1] = gen_lowpart (SImode, operands[1]);
1407 operands[5] = gen_highpart (SImode, operands[2]);
1408 operands[2] = gen_lowpart (SImode, operands[2]);
1413 [(set (match_operand:DI 0 "s_register_operand" "")
1414 (match_operator:DI 6 "logical_binary_operator"
1415 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1416 (match_operand:DI 1 "s_register_operand" "")]))]
1417 "TARGET_ARM && reload_completed"
1418 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1419 (set (match_dup 3) (match_op_dup:SI 6
1420 [(ashiftrt:SI (match_dup 2) (const_int 31))
1424 operands[3] = gen_highpart (SImode, operands[0]);
1425 operands[0] = gen_lowpart (SImode, operands[0]);
1426 operands[4] = gen_highpart (SImode, operands[1]);
1427 operands[1] = gen_lowpart (SImode, operands[1]);
1428 operands[5] = gen_highpart (SImode, operands[2]);
1429 operands[2] = gen_lowpart (SImode, operands[2]);
1433 ;; The zero extend of operand 2 means we can just copy the high part of
1434 ;; operand1 into operand0.
1436 [(set (match_operand:DI 0 "s_register_operand" "")
1438 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1439 (match_operand:DI 1 "s_register_operand" "")))]
1440 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1441 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1442 (set (match_dup 3) (match_dup 4))]
1445 operands[4] = gen_highpart (SImode, operands[1]);
1446 operands[3] = gen_highpart (SImode, operands[0]);
1447 operands[0] = gen_lowpart (SImode, operands[0]);
1448 operands[1] = gen_lowpart (SImode, operands[1]);
1452 ;; The zero extend of operand 2 means we can just copy the high part of
1453 ;; operand1 into operand0.
1455 [(set (match_operand:DI 0 "s_register_operand" "")
1457 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1458 (match_operand:DI 1 "s_register_operand" "")))]
1459 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1460 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1461 (set (match_dup 3) (match_dup 4))]
1464 operands[4] = gen_highpart (SImode, operands[1]);
1465 operands[3] = gen_highpart (SImode, operands[0]);
1466 operands[0] = gen_lowpart (SImode, operands[0]);
1467 operands[1] = gen_lowpart (SImode, operands[1]);
1471 (define_insn "anddi3"
1472 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1473 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1474 (match_operand:DI 2 "s_register_operand" "r,r")))]
1475 "TARGET_ARM && ! TARGET_IWMMXT"
1477 [(set_attr "length" "8")]
1480 (define_insn_and_split "*anddi_zesidi_di"
1481 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1482 (and:DI (zero_extend:DI
1483 (match_operand:SI 2 "s_register_operand" "r,r"))
1484 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1487 "TARGET_ARM && reload_completed"
1488 ; The zero extend of operand 2 clears the high word of the output
1490 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1491 (set (match_dup 3) (const_int 0))]
1494 operands[3] = gen_highpart (SImode, operands[0]);
1495 operands[0] = gen_lowpart (SImode, operands[0]);
1496 operands[1] = gen_lowpart (SImode, operands[1]);
1498 [(set_attr "length" "8")]
1501 (define_insn "*anddi_sesdi_di"
1502 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1503 (and:DI (sign_extend:DI
1504 (match_operand:SI 2 "s_register_operand" "r,r"))
1505 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1508 [(set_attr "length" "8")]
1511 (define_expand "andsi3"
1512 [(set (match_operand:SI 0 "s_register_operand" "")
1513 (and:SI (match_operand:SI 1 "s_register_operand" "")
1514 (match_operand:SI 2 "reg_or_int_operand" "")))]
1519 if (GET_CODE (operands[2]) == CONST_INT)
1521 arm_split_constant (AND, SImode, NULL_RTX,
1522 INTVAL (operands[2]), operands[0],
1525 ? 0 : preserve_subexpressions_p ()));
1529 else /* TARGET_THUMB */
1531 if (GET_CODE (operands[2]) != CONST_INT)
1532 operands[2] = force_reg (SImode, operands[2]);
1537 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1539 operands[2] = force_reg (SImode,
1540 GEN_INT (~INTVAL (operands[2])));
1542 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1547 for (i = 9; i <= 31; i++)
1549 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1551 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1555 else if ((((HOST_WIDE_INT) 1) << i) - 1
1556 == ~INTVAL (operands[2]))
1558 rtx shift = GEN_INT (i);
1559 rtx reg = gen_reg_rtx (SImode);
1561 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1562 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1568 operands[2] = force_reg (SImode, operands[2]);
1574 (define_insn_and_split "*arm_andsi3_insn"
1575 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1576 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1577 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1581 bic%?\\t%0, %1, #%B2
1584 && GET_CODE (operands[2]) == CONST_INT
1585 && !(const_ok_for_arm (INTVAL (operands[2]))
1586 || const_ok_for_arm (~INTVAL (operands[2])))"
1587 [(clobber (const_int 0))]
1589 arm_split_constant (AND, SImode, curr_insn,
1590 INTVAL (operands[2]), operands[0], operands[1], 0);
1593 [(set_attr "length" "4,4,16")
1594 (set_attr "predicable" "yes")]
1597 (define_insn "*thumb_andsi3_insn"
1598 [(set (match_operand:SI 0 "register_operand" "=l")
1599 (and:SI (match_operand:SI 1 "register_operand" "%0")
1600 (match_operand:SI 2 "register_operand" "l")))]
1603 [(set_attr "length" "2")]
1606 (define_insn "*andsi3_compare0"
1607 [(set (reg:CC_NOOV CC_REGNUM)
1609 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1610 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1612 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1613 (and:SI (match_dup 1) (match_dup 2)))]
1617 bic%?s\\t%0, %1, #%B2"
1618 [(set_attr "conds" "set")]
1621 (define_insn "*andsi3_compare0_scratch"
1622 [(set (reg:CC_NOOV CC_REGNUM)
1624 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1625 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1627 (clobber (match_scratch:SI 2 "=X,r"))]
1631 bic%?s\\t%2, %0, #%B1"
1632 [(set_attr "conds" "set")]
1635 (define_insn "*zeroextractsi_compare0_scratch"
1636 [(set (reg:CC_NOOV CC_REGNUM)
1637 (compare:CC_NOOV (zero_extract:SI
1638 (match_operand:SI 0 "s_register_operand" "r")
1639 (match_operand 1 "const_int_operand" "n")
1640 (match_operand 2 "const_int_operand" "n"))
1643 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1644 && INTVAL (operands[1]) > 0
1645 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1646 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1648 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1649 << INTVAL (operands[2]));
1650 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1653 [(set_attr "conds" "set")]
1656 (define_insn "*ne_zeroextractsi"
1657 [(set (match_operand:SI 0 "s_register_operand" "=r")
1658 (ne:SI (zero_extract:SI
1659 (match_operand:SI 1 "s_register_operand" "r")
1660 (match_operand:SI 2 "const_int_operand" "n")
1661 (match_operand:SI 3 "const_int_operand" "n"))
1663 (clobber (reg:CC CC_REGNUM))]
1665 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1666 && INTVAL (operands[2]) > 0
1667 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1668 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1670 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1671 << INTVAL (operands[3]));
1672 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
1673 return \"movne\\t%0, #1\";
1675 [(set_attr "conds" "clob")
1676 (set_attr "length" "8")]
1680 [(set (match_operand:SI 0 "s_register_operand" "")
1681 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1682 (match_operand:SI 2 "const_int_operand" "")
1683 (match_operand:SI 3 "const_int_operand" "")))
1684 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1686 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1687 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1689 HOST_WIDE_INT temp = INTVAL (operands[2]);
1691 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1692 operands[3] = GEN_INT (32 - temp);
1697 [(set (match_operand:SI 0 "s_register_operand" "")
1698 (match_operator:SI 1 "shiftable_operator"
1699 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1700 (match_operand:SI 3 "const_int_operand" "")
1701 (match_operand:SI 4 "const_int_operand" ""))
1702 (match_operand:SI 5 "s_register_operand" "")]))
1703 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1705 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1708 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1711 HOST_WIDE_INT temp = INTVAL (operands[3]);
1713 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1714 operands[4] = GEN_INT (32 - temp);
1719 [(set (match_operand:SI 0 "s_register_operand" "")
1720 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1721 (match_operand:SI 2 "const_int_operand" "")
1722 (match_operand:SI 3 "const_int_operand" "")))]
1724 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1725 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1727 HOST_WIDE_INT temp = INTVAL (operands[2]);
1729 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1730 operands[3] = GEN_INT (32 - temp);
1735 [(set (match_operand:SI 0 "s_register_operand" "")
1736 (match_operator:SI 1 "shiftable_operator"
1737 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1738 (match_operand:SI 3 "const_int_operand" "")
1739 (match_operand:SI 4 "const_int_operand" ""))
1740 (match_operand:SI 5 "s_register_operand" "")]))
1741 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1743 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1746 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1749 HOST_WIDE_INT temp = INTVAL (operands[3]);
1751 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1752 operands[4] = GEN_INT (32 - temp);
1756 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1757 ;;; represented by the bitfield, then this will produce incorrect results.
1758 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1759 ;;; which have a real bit-field insert instruction, the truncation happens
1760 ;;; in the bit-field insert instruction itself. Since arm does not have a
1761 ;;; bit-field insert instruction, we would have to emit code here to truncate
1762 ;;; the value before we insert. This loses some of the advantage of having
1763 ;;; this insv pattern, so this pattern needs to be reevalutated.
1765 (define_expand "insv"
1766 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1767 (match_operand:SI 1 "general_operand" "")
1768 (match_operand:SI 2 "general_operand" ""))
1769 (match_operand:SI 3 "reg_or_int_operand" ""))]
1773 int start_bit = INTVAL (operands[2]);
1774 int width = INTVAL (operands[1]);
1775 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1776 rtx target, subtarget;
1778 target = operands[0];
1779 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1780 subreg as the final target. */
1781 if (GET_CODE (target) == SUBREG)
1783 subtarget = gen_reg_rtx (SImode);
1784 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1785 < GET_MODE_SIZE (SImode))
1786 target = SUBREG_REG (target);
1791 if (GET_CODE (operands[3]) == CONST_INT)
1793 /* Since we are inserting a known constant, we may be able to
1794 reduce the number of bits that we have to clear so that
1795 the mask becomes simple. */
1796 /* ??? This code does not check to see if the new mask is actually
1797 simpler. It may not be. */
1798 rtx op1 = gen_reg_rtx (SImode);
1799 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1800 start of this pattern. */
1801 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1802 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1804 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1805 emit_insn (gen_iorsi3 (subtarget, op1,
1806 GEN_INT (op3_value << start_bit)));
1808 else if (start_bit == 0
1809 && !(const_ok_for_arm (mask)
1810 || const_ok_for_arm (~mask)))
1812 /* A Trick, since we are setting the bottom bits in the word,
1813 we can shift operand[3] up, operand[0] down, OR them together
1814 and rotate the result back again. This takes 3 insns, and
1815 the third might be mergeable into another op. */
1816 /* The shift up copes with the possibility that operand[3] is
1817 wider than the bitfield. */
1818 rtx op0 = gen_reg_rtx (SImode);
1819 rtx op1 = gen_reg_rtx (SImode);
1821 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1822 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1823 emit_insn (gen_iorsi3 (op1, op1, op0));
1824 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1826 else if ((width + start_bit == 32)
1827 && !(const_ok_for_arm (mask)
1828 || const_ok_for_arm (~mask)))
1830 /* Similar trick, but slightly less efficient. */
1832 rtx op0 = gen_reg_rtx (SImode);
1833 rtx op1 = gen_reg_rtx (SImode);
1835 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1836 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1837 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1838 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1842 rtx op0 = GEN_INT (mask);
1843 rtx op1 = gen_reg_rtx (SImode);
1844 rtx op2 = gen_reg_rtx (SImode);
1846 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1848 rtx tmp = gen_reg_rtx (SImode);
1850 emit_insn (gen_movsi (tmp, op0));
1854 /* Mask out any bits in operand[3] that are not needed. */
1855 emit_insn (gen_andsi3 (op1, operands[3], op0));
1857 if (GET_CODE (op0) == CONST_INT
1858 && (const_ok_for_arm (mask << start_bit)
1859 || const_ok_for_arm (~(mask << start_bit))))
1861 op0 = GEN_INT (~(mask << start_bit));
1862 emit_insn (gen_andsi3 (op2, operands[0], op0));
1866 if (GET_CODE (op0) == CONST_INT)
1868 rtx tmp = gen_reg_rtx (SImode);
1870 emit_insn (gen_movsi (tmp, op0));
1875 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1877 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1881 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1883 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1886 if (subtarget != target)
1888 /* If TARGET is still a SUBREG, then it must be wider than a word,
1889 so we must be careful only to set the subword we were asked to. */
1890 if (GET_CODE (target) == SUBREG)
1891 emit_move_insn (target, subtarget);
1893 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1900 ; constants for op 2 will never be given to these patterns.
1901 (define_insn_and_split "*anddi_notdi_di"
1902 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1903 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1904 (match_operand:DI 2 "s_register_operand" "0,r")))]
1907 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1908 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
1909 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
1912 operands[3] = gen_highpart (SImode, operands[0]);
1913 operands[0] = gen_lowpart (SImode, operands[0]);
1914 operands[4] = gen_highpart (SImode, operands[1]);
1915 operands[1] = gen_lowpart (SImode, operands[1]);
1916 operands[5] = gen_highpart (SImode, operands[2]);
1917 operands[2] = gen_lowpart (SImode, operands[2]);
1919 [(set_attr "length" "8")
1920 (set_attr "predicable" "yes")]
1923 (define_insn_and_split "*anddi_notzesidi_di"
1924 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1925 (and:DI (not:DI (zero_extend:DI
1926 (match_operand:SI 2 "s_register_operand" "r,r")))
1927 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1930 bic%?\\t%Q0, %Q1, %2
1932 ; (not (zero_extend ...)) allows us to just copy the high word from
1933 ; operand1 to operand0.
1936 && operands[0] != operands[1]"
1937 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
1938 (set (match_dup 3) (match_dup 4))]
1941 operands[3] = gen_highpart (SImode, operands[0]);
1942 operands[0] = gen_lowpart (SImode, operands[0]);
1943 operands[4] = gen_highpart (SImode, operands[1]);
1944 operands[1] = gen_lowpart (SImode, operands[1]);
1946 [(set_attr "length" "4,8")
1947 (set_attr "predicable" "yes")]
1950 (define_insn_and_split "*anddi_notsesidi_di"
1951 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1952 (and:DI (not:DI (sign_extend:DI
1953 (match_operand:SI 2 "s_register_operand" "r,r")))
1954 (match_operand:DI 1 "s_register_operand" "0,r")))]
1957 "TARGET_ARM && reload_completed"
1958 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
1959 (set (match_dup 3) (and:SI (not:SI
1960 (ashiftrt:SI (match_dup 2) (const_int 31)))
1964 operands[3] = gen_highpart (SImode, operands[0]);
1965 operands[0] = gen_lowpart (SImode, operands[0]);
1966 operands[4] = gen_highpart (SImode, operands[1]);
1967 operands[1] = gen_lowpart (SImode, operands[1]);
1969 [(set_attr "length" "8")
1970 (set_attr "predicable" "yes")]
1973 (define_insn "andsi_notsi_si"
1974 [(set (match_operand:SI 0 "s_register_operand" "=r")
1975 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1976 (match_operand:SI 1 "s_register_operand" "r")))]
1978 "bic%?\\t%0, %1, %2"
1979 [(set_attr "predicable" "yes")]
1982 (define_insn "bicsi3"
1983 [(set (match_operand:SI 0 "register_operand" "=l")
1984 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
1985 (match_operand:SI 2 "register_operand" "0")))]
1988 [(set_attr "length" "2")]
1991 (define_insn "andsi_not_shiftsi_si"
1992 [(set (match_operand:SI 0 "s_register_operand" "=r")
1993 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
1994 [(match_operand:SI 2 "s_register_operand" "r")
1995 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
1996 (match_operand:SI 1 "s_register_operand" "r")))]
1998 "bic%?\\t%0, %1, %2%S4"
1999 [(set_attr "predicable" "yes")
2000 (set_attr "shift" "2")
2001 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2002 (const_string "alu_shift")
2003 (const_string "alu_shift_reg")))]
2006 (define_insn "*andsi_notsi_si_compare0"
2007 [(set (reg:CC_NOOV CC_REGNUM)
2009 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2010 (match_operand:SI 1 "s_register_operand" "r"))
2012 (set (match_operand:SI 0 "s_register_operand" "=r")
2013 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2015 "bic%?s\\t%0, %1, %2"
2016 [(set_attr "conds" "set")]
2019 (define_insn "*andsi_notsi_si_compare0_scratch"
2020 [(set (reg:CC_NOOV CC_REGNUM)
2022 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2023 (match_operand:SI 1 "s_register_operand" "r"))
2025 (clobber (match_scratch:SI 0 "=r"))]
2027 "bic%?s\\t%0, %1, %2"
2028 [(set_attr "conds" "set")]
2031 (define_insn "iordi3"
2032 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2033 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2034 (match_operand:DI 2 "s_register_operand" "r,r")))]
2035 "TARGET_ARM && ! TARGET_IWMMXT"
2037 [(set_attr "length" "8")
2038 (set_attr "predicable" "yes")]
2041 (define_insn "*iordi_zesidi_di"
2042 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2043 (ior:DI (zero_extend:DI
2044 (match_operand:SI 2 "s_register_operand" "r,r"))
2045 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2048 orr%?\\t%Q0, %Q1, %2
2050 [(set_attr "length" "4,8")
2051 (set_attr "predicable" "yes")]
2054 (define_insn "*iordi_sesidi_di"
2055 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2056 (ior:DI (sign_extend:DI
2057 (match_operand:SI 2 "s_register_operand" "r,r"))
2058 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2061 [(set_attr "length" "8")
2062 (set_attr "predicable" "yes")]
2065 (define_expand "iorsi3"
2066 [(set (match_operand:SI 0 "s_register_operand" "")
2067 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2068 (match_operand:SI 2 "reg_or_int_operand" "")))]
2071 if (GET_CODE (operands[2]) == CONST_INT)
2075 arm_split_constant (IOR, SImode, NULL_RTX,
2076 INTVAL (operands[2]), operands[0], operands[1],
2078 ? 0 : preserve_subexpressions_p ()));
2081 else /* TARGET_THUMB */
2082 operands [2] = force_reg (SImode, operands [2]);
2087 (define_insn_and_split "*arm_iorsi3"
2088 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2089 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2090 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2096 && GET_CODE (operands[2]) == CONST_INT
2097 && !const_ok_for_arm (INTVAL (operands[2]))"
2098 [(clobber (const_int 0))]
2100 arm_split_constant (IOR, SImode, curr_insn,
2101 INTVAL (operands[2]), operands[0], operands[1], 0);
2104 [(set_attr "length" "4,16")
2105 (set_attr "predicable" "yes")]
2108 (define_insn "*thumb_iorsi3"
2109 [(set (match_operand:SI 0 "register_operand" "=l")
2110 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2111 (match_operand:SI 2 "register_operand" "l")))]
2114 [(set_attr "length" "2")]
2118 [(match_scratch:SI 3 "r")
2119 (set (match_operand:SI 0 "s_register_operand" "")
2120 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2121 (match_operand:SI 2 "const_int_operand" "")))]
2123 && !const_ok_for_arm (INTVAL (operands[2]))
2124 && const_ok_for_arm (~INTVAL (operands[2]))"
2125 [(set (match_dup 3) (match_dup 2))
2126 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2130 (define_insn "*iorsi3_compare0"
2131 [(set (reg:CC_NOOV CC_REGNUM)
2132 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2133 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2135 (set (match_operand:SI 0 "s_register_operand" "=r")
2136 (ior:SI (match_dup 1) (match_dup 2)))]
2138 "orr%?s\\t%0, %1, %2"
2139 [(set_attr "conds" "set")]
2142 (define_insn "*iorsi3_compare0_scratch"
2143 [(set (reg:CC_NOOV CC_REGNUM)
2144 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2145 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2147 (clobber (match_scratch:SI 0 "=r"))]
2149 "orr%?s\\t%0, %1, %2"
2150 [(set_attr "conds" "set")]
2153 (define_insn "xordi3"
2154 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2155 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2156 (match_operand:DI 2 "s_register_operand" "r,r")))]
2157 "TARGET_ARM && !TARGET_IWMMXT"
2159 [(set_attr "length" "8")
2160 (set_attr "predicable" "yes")]
2163 (define_insn "*xordi_zesidi_di"
2164 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2165 (xor:DI (zero_extend:DI
2166 (match_operand:SI 2 "s_register_operand" "r,r"))
2167 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2170 eor%?\\t%Q0, %Q1, %2
2172 [(set_attr "length" "4,8")
2173 (set_attr "predicable" "yes")]
2176 (define_insn "*xordi_sesidi_di"
2177 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2178 (xor:DI (sign_extend:DI
2179 (match_operand:SI 2 "s_register_operand" "r,r"))
2180 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2183 [(set_attr "length" "8")
2184 (set_attr "predicable" "yes")]
2187 (define_expand "xorsi3"
2188 [(set (match_operand:SI 0 "s_register_operand" "")
2189 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2190 (match_operand:SI 2 "arm_rhs_operand" "")))]
2193 if (GET_CODE (operands[2]) == CONST_INT)
2194 operands[2] = force_reg (SImode, operands[2]);
2198 (define_insn "*arm_xorsi3"
2199 [(set (match_operand:SI 0 "s_register_operand" "=r")
2200 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2201 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2203 "eor%?\\t%0, %1, %2"
2204 [(set_attr "predicable" "yes")]
2207 (define_insn "*thumb_xorsi3"
2208 [(set (match_operand:SI 0 "register_operand" "=l")
2209 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2210 (match_operand:SI 2 "register_operand" "l")))]
2213 [(set_attr "length" "2")]
2216 (define_insn "*xorsi3_compare0"
2217 [(set (reg:CC_NOOV CC_REGNUM)
2218 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2219 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2221 (set (match_operand:SI 0 "s_register_operand" "=r")
2222 (xor:SI (match_dup 1) (match_dup 2)))]
2224 "eor%?s\\t%0, %1, %2"
2225 [(set_attr "conds" "set")]
2228 (define_insn "*xorsi3_compare0_scratch"
2229 [(set (reg:CC_NOOV CC_REGNUM)
2230 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2231 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2235 [(set_attr "conds" "set")]
2238 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2239 ; (NOT D) we can sometimes merge the final NOT into one of the following
2243 [(set (match_operand:SI 0 "s_register_operand" "")
2244 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2245 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2246 (match_operand:SI 3 "arm_rhs_operand" "")))
2247 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2249 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2250 (not:SI (match_dup 3))))
2251 (set (match_dup 0) (not:SI (match_dup 4)))]
2255 (define_insn "*andsi_iorsi3_notsi"
2256 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2257 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2258 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2259 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2261 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2262 [(set_attr "length" "8")
2263 (set_attr "predicable" "yes")]
2267 [(set (match_operand:SI 0 "s_register_operand" "")
2268 (match_operator:SI 1 "logical_binary_operator"
2269 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2270 (match_operand:SI 3 "const_int_operand" "")
2271 (match_operand:SI 4 "const_int_operand" ""))
2272 (match_operator:SI 9 "logical_binary_operator"
2273 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2274 (match_operand:SI 6 "const_int_operand" ""))
2275 (match_operand:SI 7 "s_register_operand" "")])]))
2276 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2278 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2279 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2282 [(ashift:SI (match_dup 2) (match_dup 4))
2286 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2289 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2293 [(set (match_operand:SI 0 "s_register_operand" "")
2294 (match_operator:SI 1 "logical_binary_operator"
2295 [(match_operator:SI 9 "logical_binary_operator"
2296 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2297 (match_operand:SI 6 "const_int_operand" ""))
2298 (match_operand:SI 7 "s_register_operand" "")])
2299 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2300 (match_operand:SI 3 "const_int_operand" "")
2301 (match_operand:SI 4 "const_int_operand" ""))]))
2302 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2304 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2305 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2308 [(ashift:SI (match_dup 2) (match_dup 4))
2312 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2315 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2319 [(set (match_operand:SI 0 "s_register_operand" "")
2320 (match_operator:SI 1 "logical_binary_operator"
2321 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2322 (match_operand:SI 3 "const_int_operand" "")
2323 (match_operand:SI 4 "const_int_operand" ""))
2324 (match_operator:SI 9 "logical_binary_operator"
2325 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2326 (match_operand:SI 6 "const_int_operand" ""))
2327 (match_operand:SI 7 "s_register_operand" "")])]))
2328 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2330 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2331 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2334 [(ashift:SI (match_dup 2) (match_dup 4))
2338 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2341 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2345 [(set (match_operand:SI 0 "s_register_operand" "")
2346 (match_operator:SI 1 "logical_binary_operator"
2347 [(match_operator:SI 9 "logical_binary_operator"
2348 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2349 (match_operand:SI 6 "const_int_operand" ""))
2350 (match_operand:SI 7 "s_register_operand" "")])
2351 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2352 (match_operand:SI 3 "const_int_operand" "")
2353 (match_operand:SI 4 "const_int_operand" ""))]))
2354 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2356 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2357 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2360 [(ashift:SI (match_dup 2) (match_dup 4))
2364 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2367 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2371 ;; Minimum and maximum insns
2373 (define_insn "smaxsi3"
2374 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2375 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2376 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2377 (clobber (reg:CC CC_REGNUM))]
2380 cmp\\t%1, %2\;movlt\\t%0, %2
2381 cmp\\t%1, %2\;movge\\t%0, %1
2382 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2383 [(set_attr "conds" "clob")
2384 (set_attr "length" "8,8,12")]
2387 (define_insn "sminsi3"
2388 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2389 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2390 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2391 (clobber (reg:CC CC_REGNUM))]
2394 cmp\\t%1, %2\;movge\\t%0, %2
2395 cmp\\t%1, %2\;movlt\\t%0, %1
2396 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2397 [(set_attr "conds" "clob")
2398 (set_attr "length" "8,8,12")]
2401 (define_insn "umaxsi3"
2402 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2403 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2404 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2405 (clobber (reg:CC CC_REGNUM))]
2408 cmp\\t%1, %2\;movcc\\t%0, %2
2409 cmp\\t%1, %2\;movcs\\t%0, %1
2410 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2411 [(set_attr "conds" "clob")
2412 (set_attr "length" "8,8,12")]
2415 (define_insn "uminsi3"
2416 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2417 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2418 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2419 (clobber (reg:CC CC_REGNUM))]
2422 cmp\\t%1, %2\;movcs\\t%0, %2
2423 cmp\\t%1, %2\;movcc\\t%0, %1
2424 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2425 [(set_attr "conds" "clob")
2426 (set_attr "length" "8,8,12")]
2429 (define_insn "*store_minmaxsi"
2430 [(set (match_operand:SI 0 "memory_operand" "=m")
2431 (match_operator:SI 3 "minmax_operator"
2432 [(match_operand:SI 1 "s_register_operand" "r")
2433 (match_operand:SI 2 "s_register_operand" "r")]))
2434 (clobber (reg:CC CC_REGNUM))]
2437 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2438 operands[1], operands[2]);
2439 output_asm_insn (\"cmp\\t%1, %2\", operands);
2440 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2441 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2444 [(set_attr "conds" "clob")
2445 (set_attr "length" "12")
2446 (set_attr "type" "store1")]
2449 ; Reject the frame pointer in operand[1], since reloading this after
2450 ; it has been eliminated can cause carnage.
2451 (define_insn "*minmax_arithsi"
2452 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2453 (match_operator:SI 4 "shiftable_operator"
2454 [(match_operator:SI 5 "minmax_operator"
2455 [(match_operand:SI 2 "s_register_operand" "r,r")
2456 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2457 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2458 (clobber (reg:CC CC_REGNUM))]
2460 && (GET_CODE (operands[1]) != REG
2461 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
2462 && REGNO(operands[1]) != ARG_POINTER_REGNUM))"
2465 enum rtx_code code = GET_CODE (operands[4]);
2467 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2468 operands[2], operands[3]);
2469 output_asm_insn (\"cmp\\t%2, %3\", operands);
2470 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2471 if (which_alternative != 0 || operands[3] != const0_rtx
2472 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2473 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2476 [(set_attr "conds" "clob")
2477 (set_attr "length" "12")]
2481 ;; Shift and rotation insns
2483 (define_expand "ashldi3"
2484 [(set (match_operand:DI 0 "s_register_operand" "")
2485 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2486 (match_operand:SI 2 "reg_or_int_operand" "")))]
2489 if (GET_CODE (operands[2]) == CONST_INT)
2491 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2493 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2496 /* Ideally we shouldn't fail here if we could know that operands[1]
2497 ends up already living in an iwmmxt register. Otherwise it's
2498 cheaper to have the alternate code being generated than moving
2499 values to iwmmxt regs and back. */
2502 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2507 (define_insn "arm_ashldi3_1bit"
2508 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2509 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2511 (clobber (reg:CC CC_REGNUM))]
2513 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2514 [(set_attr "conds" "clob")
2515 (set_attr "length" "8")]
2518 (define_expand "ashlsi3"
2519 [(set (match_operand:SI 0 "s_register_operand" "")
2520 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2521 (match_operand:SI 2 "arm_rhs_operand" "")))]
2524 if (GET_CODE (operands[2]) == CONST_INT
2525 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2527 emit_insn (gen_movsi (operands[0], const0_rtx));
2533 (define_insn "*thumb_ashlsi3"
2534 [(set (match_operand:SI 0 "register_operand" "=l,l")
2535 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2536 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2539 [(set_attr "length" "2")]
2542 (define_expand "ashrdi3"
2543 [(set (match_operand:DI 0 "s_register_operand" "")
2544 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2545 (match_operand:SI 2 "reg_or_int_operand" "")))]
2548 if (GET_CODE (operands[2]) == CONST_INT)
2550 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2552 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2555 /* Ideally we shouldn't fail here if we could know that operands[1]
2556 ends up already living in an iwmmxt register. Otherwise it's
2557 cheaper to have the alternate code being generated than moving
2558 values to iwmmxt regs and back. */
2561 else if (!TARGET_REALLY_IWMMXT)
2566 (define_insn "arm_ashrdi3_1bit"
2567 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2568 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2570 (clobber (reg:CC CC_REGNUM))]
2572 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2573 [(set_attr "conds" "clob")
2574 (set_attr "length" "8")]
2577 (define_expand "ashrsi3"
2578 [(set (match_operand:SI 0 "s_register_operand" "")
2579 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2580 (match_operand:SI 2 "arm_rhs_operand" "")))]
2583 if (GET_CODE (operands[2]) == CONST_INT
2584 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2585 operands[2] = GEN_INT (31);
2589 (define_insn "*thumb_ashrsi3"
2590 [(set (match_operand:SI 0 "register_operand" "=l,l")
2591 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2592 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2595 [(set_attr "length" "2")]
2598 (define_expand "lshrdi3"
2599 [(set (match_operand:DI 0 "s_register_operand" "")
2600 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2601 (match_operand:SI 2 "reg_or_int_operand" "")))]
2604 if (GET_CODE (operands[2]) == CONST_INT)
2606 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2608 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2611 /* Ideally we shouldn't fail here if we could know that operands[1]
2612 ends up already living in an iwmmxt register. Otherwise it's
2613 cheaper to have the alternate code being generated than moving
2614 values to iwmmxt regs and back. */
2617 else if (!TARGET_REALLY_IWMMXT)
2622 (define_insn "arm_lshrdi3_1bit"
2623 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2624 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2626 (clobber (reg:CC CC_REGNUM))]
2628 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2629 [(set_attr "conds" "clob")
2630 (set_attr "length" "8")]
2633 (define_expand "lshrsi3"
2634 [(set (match_operand:SI 0 "s_register_operand" "")
2635 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2636 (match_operand:SI 2 "arm_rhs_operand" "")))]
2639 if (GET_CODE (operands[2]) == CONST_INT
2640 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2642 emit_insn (gen_movsi (operands[0], const0_rtx));
2648 (define_insn "*thumb_lshrsi3"
2649 [(set (match_operand:SI 0 "register_operand" "=l,l")
2650 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2651 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2654 [(set_attr "length" "2")]
2657 (define_expand "rotlsi3"
2658 [(set (match_operand:SI 0 "s_register_operand" "")
2659 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2660 (match_operand:SI 2 "reg_or_int_operand" "")))]
2663 if (GET_CODE (operands[2]) == CONST_INT)
2664 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2667 rtx reg = gen_reg_rtx (SImode);
2668 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2674 (define_expand "rotrsi3"
2675 [(set (match_operand:SI 0 "s_register_operand" "")
2676 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2677 (match_operand:SI 2 "arm_rhs_operand" "")))]
2682 if (GET_CODE (operands[2]) == CONST_INT
2683 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2684 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2686 else /* TARGET_THUMB */
2688 if (GET_CODE (operands [2]) == CONST_INT)
2689 operands [2] = force_reg (SImode, operands[2]);
2694 (define_insn "*thumb_rotrsi3"
2695 [(set (match_operand:SI 0 "register_operand" "=l")
2696 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2697 (match_operand:SI 2 "register_operand" "l")))]
2700 [(set_attr "length" "2")]
2703 (define_insn "*arm_shiftsi3"
2704 [(set (match_operand:SI 0 "s_register_operand" "=r")
2705 (match_operator:SI 3 "shift_operator"
2706 [(match_operand:SI 1 "s_register_operand" "r")
2707 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2710 [(set_attr "predicable" "yes")
2711 (set_attr "shift" "1")
2712 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2713 (const_string "alu_shift")
2714 (const_string "alu_shift_reg")))]
2717 (define_insn "*shiftsi3_compare0"
2718 [(set (reg:CC_NOOV CC_REGNUM)
2719 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2720 [(match_operand:SI 1 "s_register_operand" "r")
2721 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2723 (set (match_operand:SI 0 "s_register_operand" "=r")
2724 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2726 "mov%?s\\t%0, %1%S3"
2727 [(set_attr "conds" "set")
2728 (set_attr "shift" "1")
2729 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2730 (const_string "alu_shift")
2731 (const_string "alu_shift_reg")))]
2734 (define_insn "*shiftsi3_compare0_scratch"
2735 [(set (reg:CC_NOOV CC_REGNUM)
2736 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2737 [(match_operand:SI 1 "s_register_operand" "r")
2738 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2740 (clobber (match_scratch:SI 0 "=r"))]
2742 "mov%?s\\t%0, %1%S3"
2743 [(set_attr "conds" "set")
2744 (set_attr "shift" "1")]
2747 (define_insn "*notsi_shiftsi"
2748 [(set (match_operand:SI 0 "s_register_operand" "=r")
2749 (not:SI (match_operator:SI 3 "shift_operator"
2750 [(match_operand:SI 1 "s_register_operand" "r")
2751 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2754 [(set_attr "predicable" "yes")
2755 (set_attr "shift" "1")
2756 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2757 (const_string "alu_shift")
2758 (const_string "alu_shift_reg")))]
2761 (define_insn "*notsi_shiftsi_compare0"
2762 [(set (reg:CC_NOOV CC_REGNUM)
2763 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2764 [(match_operand:SI 1 "s_register_operand" "r")
2765 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2767 (set (match_operand:SI 0 "s_register_operand" "=r")
2768 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2770 "mvn%?s\\t%0, %1%S3"
2771 [(set_attr "conds" "set")
2772 (set_attr "shift" "1")
2773 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2774 (const_string "alu_shift")
2775 (const_string "alu_shift_reg")))]
2778 (define_insn "*not_shiftsi_compare0_scratch"
2779 [(set (reg:CC_NOOV CC_REGNUM)
2780 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2781 [(match_operand:SI 1 "s_register_operand" "r")
2782 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2784 (clobber (match_scratch:SI 0 "=r"))]
2786 "mvn%?s\\t%0, %1%S3"
2787 [(set_attr "conds" "set")
2788 (set_attr "shift" "1")
2789 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2790 (const_string "alu_shift")
2791 (const_string "alu_shift_reg")))]
2794 ;; We don't really have extzv, but defining this using shifts helps
2795 ;; to reduce register pressure later on.
2797 (define_expand "extzv"
2799 (ashift:SI (match_operand:SI 1 "register_operand" "")
2800 (match_operand:SI 2 "const_int_operand" "")))
2801 (set (match_operand:SI 0 "register_operand" "")
2802 (lshiftrt:SI (match_dup 4)
2803 (match_operand:SI 3 "const_int_operand" "")))]
2807 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2808 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2810 operands[3] = GEN_INT (rshift);
2814 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2818 operands[2] = GEN_INT (lshift);
2819 operands[4] = gen_reg_rtx (SImode);
2824 ;; Unary arithmetic insns
2826 (define_expand "negdi2"
2828 [(set (match_operand:DI 0 "s_register_operand" "")
2829 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2830 (clobber (reg:CC CC_REGNUM))])]
2835 if (GET_CODE (operands[1]) != REG)
2836 operands[1] = force_reg (SImode, operands[1]);
2841 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
2842 ;; The second alternative is to allow the common case of a *full* overlap.
2843 (define_insn "*arm_negdi2"
2844 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2845 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
2846 (clobber (reg:CC CC_REGNUM))]
2848 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
2849 [(set_attr "conds" "clob")
2850 (set_attr "length" "8")]
2853 (define_insn "*thumb_negdi2"
2854 [(set (match_operand:DI 0 "register_operand" "=&l")
2855 (neg:DI (match_operand:DI 1 "register_operand" "l")))
2856 (clobber (reg:CC CC_REGNUM))]
2858 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
2859 [(set_attr "length" "6")]
2862 (define_expand "negsi2"
2863 [(set (match_operand:SI 0 "s_register_operand" "")
2864 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
2869 (define_insn "*arm_negsi2"
2870 [(set (match_operand:SI 0 "s_register_operand" "=r")
2871 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
2873 "rsb%?\\t%0, %1, #0"
2874 [(set_attr "predicable" "yes")]
2877 (define_insn "*thumb_negsi2"
2878 [(set (match_operand:SI 0 "register_operand" "=l")
2879 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
2882 [(set_attr "length" "2")]
2885 (define_expand "negsf2"
2886 [(set (match_operand:SF 0 "s_register_operand" "")
2887 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
2888 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2892 (define_expand "negdf2"
2893 [(set (match_operand:DF 0 "s_register_operand" "")
2894 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
2895 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2898 ;; abssi2 doesn't really clobber the condition codes if a different register
2899 ;; is being set. To keep things simple, assume during rtl manipulations that
2900 ;; it does, but tell the final scan operator the truth. Similarly for
2903 (define_expand "abssi2"
2905 [(set (match_operand:SI 0 "s_register_operand" "")
2906 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
2907 (clobber (reg:CC CC_REGNUM))])]
2911 (define_insn "*arm_abssi2"
2912 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
2913 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
2914 (clobber (reg:CC CC_REGNUM))]
2917 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
2918 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
2919 [(set_attr "conds" "clob,*")
2920 (set_attr "shift" "1")
2921 ;; predicable can't be set based on the variant, so left as no
2922 (set_attr "length" "8")]
2925 (define_insn "*neg_abssi2"
2926 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
2927 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
2928 (clobber (reg:CC CC_REGNUM))]
2931 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
2932 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
2933 [(set_attr "conds" "clob,*")
2934 (set_attr "shift" "1")
2935 ;; predicable can't be set based on the variant, so left as no
2936 (set_attr "length" "8")]
2939 (define_expand "abssf2"
2940 [(set (match_operand:SF 0 "s_register_operand" "")
2941 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
2942 "TARGET_ARM && TARGET_HARD_FLOAT"
2945 (define_expand "absdf2"
2946 [(set (match_operand:DF 0 "s_register_operand" "")
2947 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
2948 "TARGET_ARM && TARGET_HARD_FLOAT"
2951 (define_expand "sqrtsf2"
2952 [(set (match_operand:SF 0 "s_register_operand" "")
2953 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
2954 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
2957 (define_expand "sqrtdf2"
2958 [(set (match_operand:DF 0 "s_register_operand" "")
2959 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
2960 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
2963 (define_insn_and_split "one_cmpldi2"
2964 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2965 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
2968 "TARGET_ARM && reload_completed"
2969 [(set (match_dup 0) (not:SI (match_dup 1)))
2970 (set (match_dup 2) (not:SI (match_dup 3)))]
2973 operands[2] = gen_highpart (SImode, operands[0]);
2974 operands[0] = gen_lowpart (SImode, operands[0]);
2975 operands[3] = gen_highpart (SImode, operands[1]);
2976 operands[1] = gen_lowpart (SImode, operands[1]);
2978 [(set_attr "length" "8")
2979 (set_attr "predicable" "yes")]
2982 (define_expand "one_cmplsi2"
2983 [(set (match_operand:SI 0 "s_register_operand" "")
2984 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
2989 (define_insn "*arm_one_cmplsi2"
2990 [(set (match_operand:SI 0 "s_register_operand" "=r")
2991 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
2994 [(set_attr "predicable" "yes")]
2997 (define_insn "*thumb_one_cmplsi2"
2998 [(set (match_operand:SI 0 "register_operand" "=l")
2999 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3002 [(set_attr "length" "2")]
3005 (define_insn "*notsi_compare0"
3006 [(set (reg:CC_NOOV CC_REGNUM)
3007 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3009 (set (match_operand:SI 0 "s_register_operand" "=r")
3010 (not:SI (match_dup 1)))]
3013 [(set_attr "conds" "set")]
3016 (define_insn "*notsi_compare0_scratch"
3017 [(set (reg:CC_NOOV CC_REGNUM)
3018 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3020 (clobber (match_scratch:SI 0 "=r"))]
3023 [(set_attr "conds" "set")]
3026 ;; Fixed <--> Floating conversion insns
3028 (define_expand "floatsisf2"
3029 [(set (match_operand:SF 0 "s_register_operand" "")
3030 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3031 "TARGET_ARM && TARGET_HARD_FLOAT"
3033 if (TARGET_MAVERICK)
3035 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3040 (define_expand "floatsidf2"
3041 [(set (match_operand:DF 0 "s_register_operand" "")
3042 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3043 "TARGET_ARM && TARGET_HARD_FLOAT"
3045 if (TARGET_MAVERICK)
3047 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3052 (define_expand "fix_truncsfsi2"
3053 [(set (match_operand:SI 0 "s_register_operand" "")
3054 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3055 "TARGET_ARM && TARGET_HARD_FLOAT"
3057 if (TARGET_MAVERICK)
3059 if (!cirrus_fp_register (operands[0], SImode))
3060 operands[0] = force_reg (SImode, operands[0]);
3061 if (!cirrus_fp_register (operands[1], SFmode))
3062 operands[1] = force_reg (SFmode, operands[0]);
3063 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3068 (define_expand "fix_truncdfsi2"
3069 [(set (match_operand:SI 0 "s_register_operand" "")
3070 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3071 "TARGET_ARM && TARGET_HARD_FLOAT"
3073 if (TARGET_MAVERICK)
3075 if (!cirrus_fp_register (operands[1], DFmode))
3076 operands[1] = force_reg (DFmode, operands[0]);
3077 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3084 (define_expand "truncdfsf2"
3085 [(set (match_operand:SF 0 "s_register_operand" "")
3087 (match_operand:DF 1 "s_register_operand" "")))]
3088 "TARGET_ARM && TARGET_HARD_FLOAT"
3092 ;; Zero and sign extension instructions.
3094 (define_insn "zero_extendsidi2"
3095 [(set (match_operand:DI 0 "s_register_operand" "=r")
3096 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3099 if (REGNO (operands[1])
3100 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3101 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3102 return \"mov%?\\t%R0, #0\";
3104 [(set_attr "length" "8")
3105 (set_attr "predicable" "yes")]
3108 (define_insn "zero_extendqidi2"
3109 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3110 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3113 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3114 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3115 [(set_attr "length" "8")
3116 (set_attr "predicable" "yes")
3117 (set_attr "type" "*,load_byte")
3118 (set_attr "pool_range" "*,4092")
3119 (set_attr "neg_pool_range" "*,4084")]
3122 (define_insn "extendsidi2"
3123 [(set (match_operand:DI 0 "s_register_operand" "=r")
3124 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3127 if (REGNO (operands[1])
3128 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3129 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3130 return \"mov%?\\t%R0, %Q0, asr #31\";
3132 [(set_attr "length" "8")
3133 (set_attr "shift" "1")
3134 (set_attr "predicable" "yes")]
3137 (define_expand "zero_extendhisi2"
3139 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3141 (set (match_operand:SI 0 "s_register_operand" "")
3142 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3146 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3148 /* Note: We do not have to worry about TARGET_MMU_TRAPS
3149 here because the insn below will generate an LDRH instruction
3150 rather than an LDR instruction, so we cannot get an unaligned
3152 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3153 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3157 if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
3159 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3163 if (!s_register_operand (operands[1], HImode))
3164 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3168 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3169 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3173 operands[1] = gen_lowpart (SImode, operands[1]);
3174 operands[2] = gen_reg_rtx (SImode);
3178 (define_insn "*thumb_zero_extendhisi2"
3179 [(set (match_operand:SI 0 "register_operand" "=l")
3180 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3181 "TARGET_THUMB && !arm_arch6"
3183 rtx mem = XEXP (operands[1], 0);
3185 if (GET_CODE (mem) == CONST)
3186 mem = XEXP (mem, 0);
3188 if (GET_CODE (mem) == LABEL_REF)
3189 return \"ldr\\t%0, %1\";
3191 if (GET_CODE (mem) == PLUS)
3193 rtx a = XEXP (mem, 0);
3194 rtx b = XEXP (mem, 1);
3196 /* This can happen due to bugs in reload. */
3197 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3200 ops[0] = operands[0];
3203 output_asm_insn (\"mov %0, %1\", ops);
3205 XEXP (mem, 0) = operands[0];
3208 else if ( GET_CODE (a) == LABEL_REF
3209 && GET_CODE (b) == CONST_INT)
3210 return \"ldr\\t%0, %1\";
3213 return \"ldrh\\t%0, %1\";
3215 [(set_attr "length" "4")
3216 (set_attr "type" "load_byte")
3217 (set_attr "pool_range" "60")]
3220 (define_insn "*thumb_zero_extendhisi2_v6"
3221 [(set (match_operand:SI 0 "register_operand" "=l,l")
3222 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3223 "TARGET_THUMB && arm_arch6"
3227 if (which_alternative == 0)
3228 return \"uxth\\t%0, %1\";
3230 mem = XEXP (operands[1], 0);
3232 if (GET_CODE (mem) == CONST)
3233 mem = XEXP (mem, 0);
3235 if (GET_CODE (mem) == LABEL_REF)
3236 return \"ldr\\t%0, %1\";
3238 if (GET_CODE (mem) == PLUS)
3240 rtx a = XEXP (mem, 0);
3241 rtx b = XEXP (mem, 1);
3243 /* This can happen due to bugs in reload. */
3244 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3247 ops[0] = operands[0];
3250 output_asm_insn (\"mov %0, %1\", ops);
3252 XEXP (mem, 0) = operands[0];
3255 else if ( GET_CODE (a) == LABEL_REF
3256 && GET_CODE (b) == CONST_INT)
3257 return \"ldr\\t%0, %1\";
3260 return \"ldrh\\t%0, %1\";
3262 [(set_attr "length" "2,4")
3263 (set_attr "type" "alu_shift,load_byte")
3264 (set_attr "pool_range" "*,60")]
3267 (define_insn "*arm_zero_extendhisi2"
3268 [(set (match_operand:SI 0 "s_register_operand" "=r")
3269 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3270 "TARGET_ARM && arm_arch4 && !arm_arch6"
3272 [(set_attr "type" "load_byte")
3273 (set_attr "predicable" "yes")
3274 (set_attr "pool_range" "256")
3275 (set_attr "neg_pool_range" "244")]
3278 (define_insn "*arm_zero_extendhisi2_v6"
3279 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3280 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3281 "TARGET_ARM && arm_arch6"
3285 [(set_attr "type" "alu_shift,load_byte")
3286 (set_attr "predicable" "yes")
3287 (set_attr "pool_range" "*,256")
3288 (set_attr "neg_pool_range" "*,244")]
3291 (define_insn "*arm_zero_extendhisi2addsi"
3292 [(set (match_operand:SI 0 "s_register_operand" "=r")
3293 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3294 (match_operand:SI 2 "s_register_operand" "r")))]
3295 "TARGET_ARM && arm_arch6"
3296 "uxtah%?\\t%0, %2, %1"
3297 [(set_attr "type" "alu_shift")
3298 (set_attr "predicable" "yes")]
3302 [(set (match_operand:SI 0 "s_register_operand" "")
3303 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3304 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3305 "TARGET_ARM && (!arm_arch4)"
3306 [(set (match_dup 2) (match_dup 1))
3307 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
3309 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3315 [(set (match_operand:SI 0 "s_register_operand" "")
3316 (match_operator:SI 3 "shiftable_operator"
3317 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3318 (match_operand:SI 4 "s_register_operand" "")]))
3319 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3320 "TARGET_ARM && (!arm_arch4)"
3321 [(set (match_dup 2) (match_dup 1))
3324 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3326 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3331 (define_expand "zero_extendqisi2"
3332 [(set (match_operand:SI 0 "s_register_operand" "")
3333 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3336 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3340 emit_insn (gen_andsi3 (operands[0],
3341 gen_lowpart (SImode, operands[1]),
3344 else /* TARGET_THUMB */
3346 rtx temp = gen_reg_rtx (SImode);
3349 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3350 operands[1] = gen_lowpart (SImode, operands[1]);
3353 ops[1] = operands[1];
3354 ops[2] = GEN_INT (24);
3356 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3357 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3359 ops[0] = operands[0];
3361 ops[2] = GEN_INT (24);
3363 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3364 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3371 (define_insn "*thumb_zero_extendqisi2"
3372 [(set (match_operand:SI 0 "register_operand" "=l")
3373 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3374 "TARGET_THUMB && !arm_arch6"
3376 [(set_attr "length" "2")
3377 (set_attr "type" "load_byte")
3378 (set_attr "pool_range" "32")]
3381 (define_insn "*thumb_zero_extendqisi2_v6"
3382 [(set (match_operand:SI 0 "register_operand" "=l,l")
3383 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3384 "TARGET_THUMB && arm_arch6"
3388 [(set_attr "length" "2,2")
3389 (set_attr "type" "alu_shift,load_byte")
3390 (set_attr "pool_range" "*,32")]
3393 (define_insn "*arm_zero_extendqisi2"
3394 [(set (match_operand:SI 0 "s_register_operand" "=r")
3395 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3396 "TARGET_ARM && !arm_arch6"
3397 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3398 [(set_attr "type" "load_byte")
3399 (set_attr "predicable" "yes")
3400 (set_attr "pool_range" "4096")
3401 (set_attr "neg_pool_range" "4084")]
3404 (define_insn "*arm_zero_extendqisi2_v6"
3405 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3406 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3407 "TARGET_ARM && arm_arch6"
3410 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3411 [(set_attr "type" "alu_shift,load_byte")
3412 (set_attr "predicable" "yes")
3413 (set_attr "pool_range" "*,4096")
3414 (set_attr "neg_pool_range" "*,4084")]
3417 (define_insn "*arm_zero_extendqisi2addsi"
3418 [(set (match_operand:SI 0 "s_register_operand" "=r")
3419 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3420 (match_operand:SI 2 "s_register_operand" "r")))]
3421 "TARGET_ARM && arm_arch6"
3422 "uxtab%?\\t%0, %2, %1"
3423 [(set_attr "predicable" "yes")
3424 (set_attr "type" "alu_shift")]
3428 [(set (match_operand:SI 0 "s_register_operand" "")
3429 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3430 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3431 "TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3432 [(set (match_dup 2) (match_dup 1))
3433 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3437 (define_insn "*compareqi_eq0"
3438 [(set (reg:CC_Z CC_REGNUM)
3439 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3443 [(set_attr "conds" "set")]
3446 (define_expand "extendhisi2"
3448 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3450 (set (match_operand:SI 0 "s_register_operand" "")
3451 (ashiftrt:SI (match_dup 2)
3456 if (GET_CODE (operands[1]) == MEM)
3460 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3465 /* Note: We do not have to worry about TARGET_MMU_TRAPS
3466 here because the insn below will generate an LDRH instruction
3467 rather than an LDR instruction, so we cannot get an unaligned
3469 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3470 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3475 if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
3477 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3481 if (!s_register_operand (operands[1], HImode))
3482 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3487 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3489 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3490 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3495 operands[1] = gen_lowpart (SImode, operands[1]);
3496 operands[2] = gen_reg_rtx (SImode);
3500 (define_insn "thumb_extendhisi2"
3501 [(set (match_operand:SI 0 "register_operand" "=l")
3502 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
3503 (clobber (match_scratch:SI 2 "=&l"))]
3504 "TARGET_THUMB && !arm_arch6"
3508 rtx mem = XEXP (operands[1], 0);
3510 /* This code used to try to use 'V', and fix the address only if it was
3511 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3512 range of QImode offsets, and offsettable_address_p does a QImode
3515 if (GET_CODE (mem) == CONST)
3516 mem = XEXP (mem, 0);
3518 if (GET_CODE (mem) == LABEL_REF)
3519 return \"ldr\\t%0, %1\";
3521 if (GET_CODE (mem) == PLUS)
3523 rtx a = XEXP (mem, 0);
3524 rtx b = XEXP (mem, 1);
3526 if (GET_CODE (a) == LABEL_REF
3527 && GET_CODE (b) == CONST_INT)
3528 return \"ldr\\t%0, %1\";
3530 if (GET_CODE (b) == REG)
3531 return \"ldrsh\\t%0, %1\";
3539 ops[2] = const0_rtx;
3542 if (GET_CODE (ops[1]) != REG)
3548 ops[0] = operands[0];
3549 ops[3] = operands[2];
3550 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3553 [(set_attr "length" "4")
3554 (set_attr "type" "load_byte")
3555 (set_attr "pool_range" "1020")]
3558 ;; We used to have an early-clobber on the scratch register here.
3559 ;; However, there's a bug somewhere in reload which means that this
3560 ;; can be partially ignored during spill allocation if the memory
3561 ;; address also needs reloading; this causes an abort later on when
3562 ;; we try to verify the operands. Fortunately, we don't really need
3563 ;; the early-clobber: we can always use operand 0 if operand 2
3564 ;; overlaps the address.
3565 (define_insn "*thumb_extendhisi2_insn_v6"
3566 [(set (match_operand:SI 0 "register_operand" "=l,l")
3567 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
3568 (clobber (match_scratch:SI 2 "=X,l"))]
3569 "TARGET_THUMB && arm_arch6"
3575 if (which_alternative == 0)
3576 return \"sxth\\t%0, %1\";
3578 mem = XEXP (operands[1], 0);
3580 /* This code used to try to use 'V', and fix the address only if it was
3581 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3582 range of QImode offsets, and offsettable_address_p does a QImode
3585 if (GET_CODE (mem) == CONST)
3586 mem = XEXP (mem, 0);
3588 if (GET_CODE (mem) == LABEL_REF)
3589 return \"ldr\\t%0, %1\";
3591 if (GET_CODE (mem) == PLUS)
3593 rtx a = XEXP (mem, 0);
3594 rtx b = XEXP (mem, 1);
3596 if (GET_CODE (a) == LABEL_REF
3597 && GET_CODE (b) == CONST_INT)
3598 return \"ldr\\t%0, %1\";
3600 if (GET_CODE (b) == REG)
3601 return \"ldrsh\\t%0, %1\";
3609 ops[2] = const0_rtx;
3612 if (GET_CODE (ops[1]) != REG)
3618 ops[0] = operands[0];
3619 if (reg_mentioned_p (operands[2], ops[1]))
3622 ops[3] = operands[2];
3623 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3626 [(set_attr "length" "2,4")
3627 (set_attr "type" "alu_shift,load_byte")
3628 (set_attr "pool_range" "*,1020")]
3631 (define_expand "extendhisi2_mem"
3632 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3634 (zero_extend:SI (match_dup 7)))
3635 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
3636 (set (match_operand:SI 0 "" "")
3637 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
3642 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3644 mem1 = gen_rtx_MEM (QImode, addr);
3645 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3646 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3647 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3648 operands[0] = gen_lowpart (SImode, operands[0]);
3650 operands[2] = gen_reg_rtx (SImode);
3651 operands[3] = gen_reg_rtx (SImode);
3652 operands[6] = gen_reg_rtx (SImode);
3655 if (BYTES_BIG_ENDIAN)
3657 operands[4] = operands[2];
3658 operands[5] = operands[3];
3662 operands[4] = operands[3];
3663 operands[5] = operands[2];
3668 (define_insn "*arm_extendhisi2"
3669 [(set (match_operand:SI 0 "s_register_operand" "=r")
3670 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3671 "TARGET_ARM && arm_arch4 && !arm_arch6"
3673 [(set_attr "type" "load_byte")
3674 (set_attr "predicable" "yes")
3675 (set_attr "pool_range" "256")
3676 (set_attr "neg_pool_range" "244")]
3679 (define_insn "*arm_extendhisi2_v6"
3680 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3681 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3682 "TARGET_ARM && arm_arch6"
3686 [(set_attr "type" "alu_shift,load_byte")
3687 (set_attr "predicable" "yes")
3688 (set_attr "pool_range" "*,256")
3689 (set_attr "neg_pool_range" "*,244")]
3692 (define_insn "*arm_extendhisi2addsi"
3693 [(set (match_operand:SI 0 "s_register_operand" "=r")
3694 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3695 (match_operand:SI 2 "s_register_operand" "r")))]
3696 "TARGET_ARM && arm_arch6"
3697 "sxtah%?\\t%0, %2, %1"
3701 [(set (match_operand:SI 0 "s_register_operand" "")
3702 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3703 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3704 "TARGET_ARM && (!arm_arch4)"
3705 [(set (match_dup 2) (match_dup 1))
3706 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
3708 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3714 [(set (match_operand:SI 0 "s_register_operand" "")
3715 (match_operator:SI 3 "shiftable_operator"
3716 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3717 (match_operand:SI 4 "s_register_operand" "")]))
3718 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3719 "TARGET_ARM && (!arm_arch4)"
3720 [(set (match_dup 2) (match_dup 1))
3723 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3724 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3729 (define_expand "extendqihi2"
3731 (ashift:SI (match_operand:QI 1 "general_operand" "")
3733 (set (match_operand:HI 0 "s_register_operand" "")
3734 (ashiftrt:SI (match_dup 2)
3739 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
3741 emit_insn (gen_rtx_SET (VOIDmode,
3743 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
3746 if (!s_register_operand (operands[1], QImode))
3747 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3748 operands[0] = gen_lowpart (SImode, operands[0]);
3749 operands[1] = gen_lowpart (SImode, operands[1]);
3750 operands[2] = gen_reg_rtx (SImode);
3754 (define_insn "*extendqihi_insn"
3755 [(set (match_operand:HI 0 "s_register_operand" "=r")
3756 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
3757 "TARGET_ARM && arm_arch4"
3759 [(set_attr "type" "load_byte")
3760 (set_attr "predicable" "yes")
3761 (set_attr "pool_range" "256")
3762 (set_attr "neg_pool_range" "244")]
3765 (define_expand "extendqisi2"
3767 (ashift:SI (match_operand:QI 1 "general_operand" "")
3769 (set (match_operand:SI 0 "s_register_operand" "")
3770 (ashiftrt:SI (match_dup 2)
3775 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3777 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3778 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3782 if (!s_register_operand (operands[1], QImode))
3783 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3787 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3788 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3792 operands[1] = gen_lowpart (SImode, operands[1]);
3793 operands[2] = gen_reg_rtx (SImode);
3797 (define_insn "*arm_extendqisi"
3798 [(set (match_operand:SI 0 "s_register_operand" "=r")
3799 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
3800 "TARGET_ARM && arm_arch4 && !arm_arch6"
3802 [(set_attr "type" "load_byte")
3803 (set_attr "predicable" "yes")
3804 (set_attr "pool_range" "256")
3805 (set_attr "neg_pool_range" "244")]
3808 (define_insn "*arm_extendqisi_v6"
3809 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3810 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
3811 "TARGET_ARM && arm_arch6"
3815 [(set_attr "type" "alu_shift,load_byte")
3816 (set_attr "predicable" "yes")
3817 (set_attr "pool_range" "*,256")
3818 (set_attr "neg_pool_range" "*,244")]
3821 (define_insn "*arm_extendqisi2addsi"
3822 [(set (match_operand:SI 0 "s_register_operand" "=r")
3823 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3824 (match_operand:SI 2 "s_register_operand" "r")))]
3825 "TARGET_ARM && arm_arch6"
3826 "sxtab%?\\t%0, %2, %1"
3827 [(set_attr "type" "alu_shift")
3828 (set_attr "predicable" "yes")]
3831 (define_insn "*thumb_extendqisi2"
3832 [(set (match_operand:SI 0 "register_operand" "=l,l")
3833 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
3834 "TARGET_THUMB && !arm_arch6"
3838 rtx mem = XEXP (operands[1], 0);
3840 if (GET_CODE (mem) == CONST)
3841 mem = XEXP (mem, 0);
3843 if (GET_CODE (mem) == LABEL_REF)
3844 return \"ldr\\t%0, %1\";
3846 if (GET_CODE (mem) == PLUS
3847 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3848 return \"ldr\\t%0, %1\";
3850 if (which_alternative == 0)
3851 return \"ldrsb\\t%0, %1\";
3853 ops[0] = operands[0];
3855 if (GET_CODE (mem) == PLUS)
3857 rtx a = XEXP (mem, 0);
3858 rtx b = XEXP (mem, 1);
3863 if (GET_CODE (a) == REG)
3865 if (GET_CODE (b) == REG)
3866 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3867 else if (REGNO (a) == REGNO (ops[0]))
3869 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3870 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3871 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3874 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3876 else if (GET_CODE (b) != REG)
3880 if (REGNO (b) == REGNO (ops[0]))
3882 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3883 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3884 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3887 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3890 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3892 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3893 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3894 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3899 ops[2] = const0_rtx;
3901 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3905 [(set_attr "length" "2,6")
3906 (set_attr "type" "load_byte,load_byte")
3907 (set_attr "pool_range" "32,32")]
3910 (define_insn "*thumb_extendqisi2_v6"
3911 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
3912 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
3913 "TARGET_THUMB && arm_arch6"
3919 if (which_alternative == 0)
3920 return \"sxtb\\t%0, %1\";
3922 mem = XEXP (operands[1], 0);
3924 if (GET_CODE (mem) == CONST)
3925 mem = XEXP (mem, 0);
3927 if (GET_CODE (mem) == LABEL_REF)
3928 return \"ldr\\t%0, %1\";
3930 if (GET_CODE (mem) == PLUS
3931 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3932 return \"ldr\\t%0, %1\";
3934 if (which_alternative == 0)
3935 return \"ldrsb\\t%0, %1\";
3937 ops[0] = operands[0];
3939 if (GET_CODE (mem) == PLUS)
3941 rtx a = XEXP (mem, 0);
3942 rtx b = XEXP (mem, 1);
3947 if (GET_CODE (a) == REG)
3949 if (GET_CODE (b) == REG)
3950 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3951 else if (REGNO (a) == REGNO (ops[0]))
3953 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3954 output_asm_insn (\"sxtb\\t%0, %0\", ops);
3957 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3959 else if (GET_CODE (b) != REG)
3963 if (REGNO (b) == REGNO (ops[0]))
3965 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3966 output_asm_insn (\"sxtb\\t%0, %0\", ops);
3969 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3972 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3974 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3975 output_asm_insn (\"sxtb\\t%0, %0\", ops);
3980 ops[2] = const0_rtx;
3982 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3986 [(set_attr "length" "2,2,4")
3987 (set_attr "type" "alu_shift,load_byte,load_byte")
3988 (set_attr "pool_range" "*,32,32")]
3991 (define_expand "extendsfdf2"
3992 [(set (match_operand:DF 0 "s_register_operand" "")
3993 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
3994 "TARGET_ARM && TARGET_HARD_FLOAT"
3998 ;; Move insns (including loads and stores)
4000 ;; XXX Just some ideas about movti.
4001 ;; I don't think these are a good idea on the arm, there just aren't enough
4003 ;;(define_expand "loadti"
4004 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4005 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4008 ;;(define_expand "storeti"
4009 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4010 ;; (match_operand:TI 1 "s_register_operand" ""))]
4013 ;;(define_expand "movti"
4014 ;; [(set (match_operand:TI 0 "general_operand" "")
4015 ;; (match_operand:TI 1 "general_operand" ""))]
4021 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4022 ;; operands[1] = copy_to_reg (operands[1]);
4023 ;; if (GET_CODE (operands[0]) == MEM)
4024 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4025 ;; else if (GET_CODE (operands[1]) == MEM)
4026 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4030 ;; emit_insn (insn);
4034 ;; Recognize garbage generated above.
4037 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4038 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4042 ;; register mem = (which_alternative < 3);
4043 ;; register const char *template;
4045 ;; operands[mem] = XEXP (operands[mem], 0);
4046 ;; switch (which_alternative)
4048 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4049 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4050 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4051 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4052 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4053 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4055 ;; output_asm_insn (template, operands);
4059 (define_expand "movdi"
4060 [(set (match_operand:DI 0 "general_operand" "")
4061 (match_operand:DI 1 "general_operand" ""))]
4066 if (!no_new_pseudos)
4068 if (GET_CODE (operands[0]) != REG)
4069 operands[1] = force_reg (DImode, operands[1]);
4075 (define_insn "*arm_movdi"
4076 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m")
4077 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
4079 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4082 return (output_move_double (operands));
4084 [(set_attr "length" "8")
4085 (set_attr "type" "*,load2,store2")
4086 (set_attr "pool_range" "*,1020,*")
4087 (set_attr "neg_pool_range" "*,1008,*")]
4090 ;; We can't actually do base+index doubleword loads if the index and
4091 ;; destination overlap. Split here so that we at least have chance to
4094 [(set (match_operand:DI 0 "s_register_operand" "")
4095 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
4096 (match_operand:SI 2 "s_register_operand" ""))))]
4098 && reg_overlap_mentioned_p (operands[0], operands[1])
4099 && reg_overlap_mentioned_p (operands[0], operands[2])"
4101 (plus:SI (match_dup 1)
4104 (mem:DI (match_dup 4)))]
4106 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
4110 ;;; ??? This should have alternatives for constants.
4111 ;;; ??? This was originally identical to the movdf_insn pattern.
4112 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4113 ;;; thumb_reorg with a memory reference.
4114 (define_insn "*thumb_movdi_insn"
4115 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4116 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4118 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4119 && ( register_operand (operands[0], DImode)
4120 || register_operand (operands[1], DImode))"
4123 switch (which_alternative)
4127 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4128 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4129 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4131 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4133 operands[1] = GEN_INT (- INTVAL (operands[1]));
4134 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4136 return \"ldmia\\t%1, {%0, %H0}\";
4138 return \"stmia\\t%0, {%1, %H1}\";
4140 return thumb_load_double_from_address (operands);
4142 operands[2] = gen_rtx_MEM (SImode,
4143 plus_constant (XEXP (operands[0], 0), 4));
4144 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4147 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4148 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4149 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4152 [(set_attr "length" "4,4,6,2,2,6,4,4")
4153 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4154 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4157 (define_expand "movsi"
4158 [(set (match_operand:SI 0 "general_operand" "")
4159 (match_operand:SI 1 "general_operand" ""))]
4164 /* Everything except mem = const or mem = mem can be done easily. */
4165 if (GET_CODE (operands[0]) == MEM)
4166 operands[1] = force_reg (SImode, operands[1]);
4167 if (arm_general_register_operand (operands[0], SImode)
4168 && GET_CODE (operands[1]) == CONST_INT
4169 && !(const_ok_for_arm (INTVAL (operands[1]))
4170 || const_ok_for_arm (~INTVAL (operands[1]))))
4172 arm_split_constant (SET, SImode, NULL_RTX,
4173 INTVAL (operands[1]), operands[0], NULL_RTX,
4175 : preserve_subexpressions_p ()));
4179 else /* TARGET_THUMB.... */
4181 if (!no_new_pseudos)
4183 if (GET_CODE (operands[0]) != REG)
4184 operands[1] = force_reg (SImode, operands[1]);
4189 && (CONSTANT_P (operands[1])
4190 || symbol_mentioned_p (operands[1])
4191 || label_mentioned_p (operands[1])))
4192 operands[1] = legitimize_pic_address (operands[1], SImode,
4193 (no_new_pseudos ? operands[0] : 0));
4197 (define_insn "*arm_movsi_insn"
4198 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4199 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4200 "TARGET_ARM && ! TARGET_IWMMXT
4201 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4202 && ( register_operand (operands[0], SImode)
4203 || register_operand (operands[1], SImode))"
4209 [(set_attr "type" "*,*,load1,store1")
4210 (set_attr "predicable" "yes")
4211 (set_attr "pool_range" "*,*,4096,*")
4212 (set_attr "neg_pool_range" "*,*,4084,*")]
4216 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4217 (match_operand:SI 1 "const_int_operand" ""))]
4219 && (!(const_ok_for_arm (INTVAL (operands[1]))
4220 || const_ok_for_arm (~INTVAL (operands[1]))))"
4221 [(clobber (const_int 0))]
4223 arm_split_constant (SET, SImode, NULL_RTX,
4224 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4229 (define_insn "*thumb_movsi_insn"
4230 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4231 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4233 && ( register_operand (operands[0], SImode)
4234 || register_operand (operands[1], SImode))"
4245 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4246 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4247 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4251 [(set (match_operand:SI 0 "register_operand" "")
4252 (match_operand:SI 1 "const_int_operand" ""))]
4253 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4254 [(set (match_dup 0) (match_dup 1))
4255 (set (match_dup 0) (neg:SI (match_dup 0)))]
4256 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4260 [(set (match_operand:SI 0 "register_operand" "")
4261 (match_operand:SI 1 "const_int_operand" ""))]
4262 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4263 [(set (match_dup 0) (match_dup 1))
4264 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4267 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4268 unsigned HOST_WIDE_INT mask = 0xff;
4271 for (i = 0; i < 25; i++)
4272 if ((val & (mask << i)) == val)
4275 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4279 operands[1] = GEN_INT (val >> i);
4280 operands[2] = GEN_INT (i);
4284 ;; When generating pic, we need to load the symbol offset into a register.
4285 ;; So that the optimizer does not confuse this with a normal symbol load
4286 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4287 ;; since that is the only type of relocation we can use.
4289 ;; The rather odd constraints on the following are to force reload to leave
4290 ;; the insn alone, and to force the minipool generation pass to then move
4291 ;; the GOT symbol to memory.
4293 (define_insn "pic_load_addr_arm"
4294 [(set (match_operand:SI 0 "s_register_operand" "=r")
4295 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4296 "TARGET_ARM && flag_pic"
4298 [(set_attr "type" "load1")
4299 (set (attr "pool_range") (const_int 4096))
4300 (set (attr "neg_pool_range") (const_int 4084))]
4303 (define_insn "pic_load_addr_thumb"
4304 [(set (match_operand:SI 0 "s_register_operand" "=l")
4305 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4306 "TARGET_THUMB && flag_pic"
4308 [(set_attr "type" "load1")
4309 (set (attr "pool_range") (const_int 1024))]
4312 ;; This variant is used for AOF assembly, since it needs to mention the
4313 ;; pic register in the rtl.
4314 (define_expand "pic_load_addr_based"
4315 [(set (match_operand:SI 0 "s_register_operand" "")
4316 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4317 "TARGET_ARM && flag_pic"
4318 "operands[2] = pic_offset_table_rtx;"
4321 (define_insn "*pic_load_addr_based_insn"
4322 [(set (match_operand:SI 0 "s_register_operand" "=r")
4323 (unspec:SI [(match_operand 1 "" "")
4324 (match_operand 2 "s_register_operand" "r")]
4326 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4328 #ifdef AOF_ASSEMBLER
4329 operands[1] = aof_pic_entry (operands[1]);
4331 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4334 [(set_attr "type" "load1")
4335 (set (attr "pool_range")
4336 (if_then_else (eq_attr "is_thumb" "yes")
4339 (set (attr "neg_pool_range")
4340 (if_then_else (eq_attr "is_thumb" "yes")
4345 (define_insn "pic_add_dot_plus_four"
4346 [(set (match_operand:SI 0 "register_operand" "+r")
4347 (unspec:SI [(plus:SI (match_dup 0)
4348 (const (plus:SI (pc) (const_int 4))))]
4350 (use (label_ref (match_operand 1 "" "")))]
4351 "TARGET_THUMB && flag_pic"
4353 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4354 CODE_LABEL_NUMBER (operands[1]));
4355 return \"add\\t%0, %|pc\";
4357 [(set_attr "length" "2")]
4360 (define_insn "pic_add_dot_plus_eight"
4361 [(set (match_operand:SI 0 "register_operand" "+r")
4362 (unspec:SI [(plus:SI (match_dup 0)
4363 (const (plus:SI (pc) (const_int 8))))]
4365 (use (label_ref (match_operand 1 "" "")))]
4366 "TARGET_ARM && flag_pic"
4368 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4369 CODE_LABEL_NUMBER (operands[1]));
4370 return \"add%?\\t%0, %|pc, %0\";
4372 [(set_attr "predicable" "yes")]
4375 (define_expand "builtin_setjmp_receiver"
4376 [(label_ref (match_operand 0 "" ""))]
4380 arm_finalize_pic (0);
4384 ;; If copying one reg to another we can set the condition codes according to
4385 ;; its value. Such a move is common after a return from subroutine and the
4386 ;; result is being tested against zero.
4388 (define_insn "*movsi_compare0"
4389 [(set (reg:CC CC_REGNUM)
4390 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4392 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4397 sub%?s\\t%0, %1, #0"
4398 [(set_attr "conds" "set")]
4401 ;; Subroutine to store a half word from a register into memory.
4402 ;; Operand 0 is the source register (HImode)
4403 ;; Operand 1 is the destination address in a register (SImode)
4405 ;; In both this routine and the next, we must be careful not to spill
4406 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4407 ;; can generate unrecognizable rtl.
4409 (define_expand "storehi"
4410 [;; store the low byte
4411 (set (match_operand 1 "" "") (match_dup 3))
4412 ;; extract the high byte
4414 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4415 ;; store the high byte
4416 (set (match_dup 4) (match_dup 5))]
4420 rtx op1 = operands[1];
4421 rtx addr = XEXP (op1, 0);
4422 enum rtx_code code = GET_CODE (addr);
4424 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4426 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4428 operands[4] = adjust_address (op1, QImode, 1);
4429 operands[1] = adjust_address (operands[1], QImode, 0);
4430 operands[3] = gen_lowpart (QImode, operands[0]);
4431 operands[0] = gen_lowpart (SImode, operands[0]);
4432 operands[2] = gen_reg_rtx (SImode);
4433 operands[5] = gen_lowpart (QImode, operands[2]);
4437 (define_expand "storehi_bigend"
4438 [(set (match_dup 4) (match_dup 3))
4440 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4441 (set (match_operand 1 "" "") (match_dup 5))]
4445 rtx op1 = operands[1];
4446 rtx addr = XEXP (op1, 0);
4447 enum rtx_code code = GET_CODE (addr);
4449 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4451 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4453 operands[4] = adjust_address (op1, QImode, 1);
4454 operands[1] = adjust_address (operands[1], QImode, 0);
4455 operands[3] = gen_lowpart (QImode, operands[0]);
4456 operands[0] = gen_lowpart (SImode, operands[0]);
4457 operands[2] = gen_reg_rtx (SImode);
4458 operands[5] = gen_lowpart (QImode, operands[2]);
4462 ;; Subroutine to store a half word integer constant into memory.
4463 (define_expand "storeinthi"
4464 [(set (match_operand 0 "" "")
4465 (match_operand 1 "" ""))
4466 (set (match_dup 3) (match_dup 2))]
4470 HOST_WIDE_INT value = INTVAL (operands[1]);
4471 rtx addr = XEXP (operands[0], 0);
4472 rtx op0 = operands[0];
4473 enum rtx_code code = GET_CODE (addr);
4475 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4477 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4479 operands[1] = gen_reg_rtx (SImode);
4480 if (BYTES_BIG_ENDIAN)
4482 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4483 if ((value & 255) == ((value >> 8) & 255))
4484 operands[2] = operands[1];
4487 operands[2] = gen_reg_rtx (SImode);
4488 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4493 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4494 if ((value & 255) == ((value >> 8) & 255))
4495 operands[2] = operands[1];
4498 operands[2] = gen_reg_rtx (SImode);
4499 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4503 operands[3] = adjust_address (op0, QImode, 1);
4504 operands[0] = adjust_address (operands[0], QImode, 0);
4505 operands[2] = gen_lowpart (QImode, operands[2]);
4506 operands[1] = gen_lowpart (QImode, operands[1]);
4510 (define_expand "storehi_single_op"
4511 [(set (match_operand:HI 0 "memory_operand" "")
4512 (match_operand:HI 1 "general_operand" ""))]
4513 "TARGET_ARM && arm_arch4"
4515 if (!s_register_operand (operands[1], HImode))
4516 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4520 (define_expand "movhi"
4521 [(set (match_operand:HI 0 "general_operand" "")
4522 (match_operand:HI 1 "general_operand" ""))]
4527 if (!no_new_pseudos)
4529 if (GET_CODE (operands[0]) == MEM)
4533 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4536 if (GET_CODE (operands[1]) == CONST_INT)
4537 emit_insn (gen_storeinthi (operands[0], operands[1]));
4540 if (GET_CODE (operands[1]) == MEM)
4541 operands[1] = force_reg (HImode, operands[1]);
4542 if (BYTES_BIG_ENDIAN)
4543 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4545 emit_insn (gen_storehi (operands[1], operands[0]));
4549 /* Sign extend a constant, and keep it in an SImode reg. */
4550 else if (GET_CODE (operands[1]) == CONST_INT)
4552 rtx reg = gen_reg_rtx (SImode);
4553 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4555 /* If the constant is already valid, leave it alone. */
4556 if (!const_ok_for_arm (val))
4558 /* If setting all the top bits will make the constant
4559 loadable in a single instruction, then set them.
4560 Otherwise, sign extend the number. */
4562 if (const_ok_for_arm (~(val | ~0xffff)))
4564 else if (val & 0x8000)
4568 emit_insn (gen_movsi (reg, GEN_INT (val)));
4569 operands[1] = gen_lowpart (HImode, reg);
4571 else if (arm_arch4 && !no_new_pseudos && optimize > 0
4572 && GET_CODE (operands[1]) == MEM)
4574 rtx reg = gen_reg_rtx (SImode);
4576 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4577 operands[1] = gen_lowpart (HImode, reg);
4579 else if (!arm_arch4)
4581 /* Note: We do not have to worry about TARGET_MMU_TRAPS
4582 for v4 and up architectures because LDRH instructions will
4583 be used to access the HI values, and these cannot generate
4584 unaligned word access faults in the MMU. */
4585 if (GET_CODE (operands[1]) == MEM)
4587 if (TARGET_MMU_TRAPS)
4590 rtx offset = const0_rtx;
4591 rtx reg = gen_reg_rtx (SImode);
4593 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4594 || (GET_CODE (base) == PLUS
4595 && (GET_CODE (offset = XEXP (base, 1))
4597 && ((INTVAL(offset) & 1) != 1)
4598 && GET_CODE (base = XEXP (base, 0)) == REG))
4599 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4601 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4604 new = gen_rtx_MEM (SImode,
4605 plus_constant (base, new_offset));
4606 MEM_COPY_ATTRIBUTES (new, operands[1]);
4607 emit_insn (gen_movsi (reg, new));
4608 if (((INTVAL (offset) & 2) != 0)
4609 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4611 rtx reg2 = gen_reg_rtx (SImode);
4613 emit_insn (gen_lshrsi3 (reg2, reg,
4619 emit_insn (gen_movhi_bytes (reg, operands[1]));
4621 operands[1] = gen_lowpart (HImode, reg);
4623 else if (BYTES_BIG_ENDIAN)
4626 rtx offset = const0_rtx;
4628 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4629 || (GET_CODE (base) == PLUS
4630 && (GET_CODE (offset = XEXP (base, 1))
4632 && GET_CODE (base = XEXP (base, 0)) == REG))
4633 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4635 rtx reg = gen_reg_rtx (SImode);
4638 if ((INTVAL (offset) & 2) == 2)
4640 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
4641 new = gen_rtx_MEM (SImode,
4642 plus_constant (base,
4644 MEM_COPY_ATTRIBUTES (new, operands[1]);
4645 emit_insn (gen_movsi (reg, new));
4649 new = gen_rtx_MEM (SImode,
4650 XEXP (operands[1], 0));
4651 MEM_COPY_ATTRIBUTES (new, operands[1]);
4652 emit_insn (gen_rotated_loadsi (reg, new));
4655 operands[1] = gen_lowpart (HImode, reg);
4659 emit_insn (gen_movhi_bigend (operands[0],
4667 /* Handle loading a large integer during reload. */
4668 else if (GET_CODE (operands[1]) == CONST_INT
4669 && !const_ok_for_arm (INTVAL (operands[1]))
4670 && !const_ok_for_arm (~INTVAL (operands[1])))
4672 /* Writing a constant to memory needs a scratch, which should
4673 be handled with SECONDARY_RELOADs. */
4674 if (GET_CODE (operands[0]) != REG)
4677 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4678 emit_insn (gen_movsi (operands[0], operands[1]));
4682 else /* TARGET_THUMB */
4684 if (!no_new_pseudos)
4686 if (GET_CODE (operands[0]) != REG)
4687 operands[1] = force_reg (HImode, operands[1]);
4689 /* ??? We shouldn't really get invalid addresses here, but this can
4690 happen if we are passed a SP (never OK for HImode/QImode) or
4691 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4692 HImode/QImode) relative address. */
4693 /* ??? This should perhaps be fixed elsewhere, for instance, in
4694 fixup_stack_1, by checking for other kinds of invalid addresses,
4695 e.g. a bare reference to a virtual register. This may confuse the
4696 alpha though, which must handle this case differently. */
4697 if (GET_CODE (operands[0]) == MEM
4698 && !memory_address_p (GET_MODE (operands[0]),
4699 XEXP (operands[0], 0)))
4701 = replace_equiv_address (operands[0],
4702 copy_to_reg (XEXP (operands[0], 0)));
4704 if (GET_CODE (operands[1]) == MEM
4705 && !memory_address_p (GET_MODE (operands[1]),
4706 XEXP (operands[1], 0)))
4708 = replace_equiv_address (operands[1],
4709 copy_to_reg (XEXP (operands[1], 0)));
4711 /* Handle loading a large integer during reload. */
4712 else if (GET_CODE (operands[1]) == CONST_INT
4713 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4715 /* Writing a constant to memory needs a scratch, which should
4716 be handled with SECONDARY_RELOADs. */
4717 if (GET_CODE (operands[0]) != REG)
4720 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4721 emit_insn (gen_movsi (operands[0], operands[1]));
4728 (define_insn "*thumb_movhi_insn"
4729 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4730 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4732 && ( register_operand (operands[0], HImode)
4733 || register_operand (operands[1], HImode))"
4735 switch (which_alternative)
4737 case 0: return \"add %0, %1, #0\";
4738 case 2: return \"strh %1, %0\";
4739 case 3: return \"mov %0, %1\";
4740 case 4: return \"mov %0, %1\";
4741 case 5: return \"mov %0, %1\";
4744 /* The stack pointer can end up being taken as an index register.
4745 Catch this case here and deal with it. */
4746 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4747 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4748 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4751 ops[0] = operands[0];
4752 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4754 output_asm_insn (\"mov %0, %1\", ops);
4756 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4759 return \"ldrh %0, %1\";
4761 [(set_attr "length" "2,4,2,2,2,2")
4762 (set_attr "type" "*,load1,store1,*,*,*")]
4766 (define_insn "rotated_loadsi"
4767 [(set (match_operand:SI 0 "s_register_operand" "=r")
4768 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
4770 "TARGET_ARM && (!TARGET_MMU_TRAPS)"
4775 ops[0] = operands[0];
4776 ops[1] = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[1], 0), 2));
4777 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
4780 [(set_attr "type" "load1")
4781 (set_attr "predicable" "yes")]
4784 (define_expand "movhi_bytes"
4785 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4787 (zero_extend:SI (match_dup 6)))
4788 (set (match_operand:SI 0 "" "")
4789 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4794 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4796 mem1 = gen_rtx_MEM (QImode, addr);
4797 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4798 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4799 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4800 operands[0] = gen_lowpart (SImode, operands[0]);
4802 operands[2] = gen_reg_rtx (SImode);
4803 operands[3] = gen_reg_rtx (SImode);
4806 if (BYTES_BIG_ENDIAN)
4808 operands[4] = operands[2];
4809 operands[5] = operands[3];
4813 operands[4] = operands[3];
4814 operands[5] = operands[2];
4819 (define_expand "movhi_bigend"
4821 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4824 (ashiftrt:SI (match_dup 2) (const_int 16)))
4825 (set (match_operand:HI 0 "s_register_operand" "")
4829 operands[2] = gen_reg_rtx (SImode);
4830 operands[3] = gen_reg_rtx (SImode);
4831 operands[4] = gen_lowpart (HImode, operands[3]);
4835 ;; Pattern to recognize insn generated default case above
4836 (define_insn "*movhi_insn_arch4"
4837 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4838 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4841 && (GET_CODE (operands[1]) != CONST_INT
4842 || const_ok_for_arm (INTVAL (operands[1]))
4843 || const_ok_for_arm (~INTVAL (operands[1])))"
4845 mov%?\\t%0, %1\\t%@ movhi
4846 mvn%?\\t%0, #%B1\\t%@ movhi
4847 str%?h\\t%1, %0\\t%@ movhi
4848 ldr%?h\\t%0, %1\\t%@ movhi"
4849 [(set_attr "type" "*,*,store1,load1")
4850 (set_attr "predicable" "yes")
4851 (set_attr "pool_range" "*,*,*,256")
4852 (set_attr "neg_pool_range" "*,*,*,244")]
4855 (define_insn "*movhi_insn_littleend"
4856 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
4857 (match_operand:HI 1 "general_operand" "rI,K,m"))]
4860 && !BYTES_BIG_ENDIAN
4861 && !TARGET_MMU_TRAPS
4862 && (GET_CODE (operands[1]) != CONST_INT
4863 || const_ok_for_arm (INTVAL (operands[1]))
4864 || const_ok_for_arm (~INTVAL (operands[1])))"
4866 mov%?\\t%0, %1\\t%@ movhi
4867 mvn%?\\t%0, #%B1\\t%@ movhi
4868 ldr%?\\t%0, %1\\t%@ movhi"
4869 [(set_attr "type" "*,*,load1")
4870 (set_attr "predicable" "yes")
4871 (set_attr "pool_range" "4096")
4872 (set_attr "neg_pool_range" "4084")]
4875 (define_insn "*movhi_insn_bigend"
4876 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
4877 (match_operand:HI 1 "general_operand" "rI,K,m"))]
4881 && !TARGET_MMU_TRAPS
4882 && (GET_CODE (operands[1]) != CONST_INT
4883 || const_ok_for_arm (INTVAL (operands[1]))
4884 || const_ok_for_arm (~INTVAL (operands[1])))"
4886 mov%?\\t%0, %1\\t%@ movhi
4887 mvn%?\\t%0, #%B1\\t%@ movhi
4888 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
4889 [(set_attr "type" "*,*,load1")
4890 (set_attr "predicable" "yes")
4891 (set_attr "length" "4,4,8")
4892 (set_attr "pool_range" "*,*,4092")
4893 (set_attr "neg_pool_range" "*,*,4084")]
4896 (define_insn "*loadhi_si_bigend"
4897 [(set (match_operand:SI 0 "s_register_operand" "=r")
4898 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
4902 && !TARGET_MMU_TRAPS"
4903 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
4904 [(set_attr "type" "load1")
4905 (set_attr "predicable" "yes")
4906 (set_attr "pool_range" "4096")
4907 (set_attr "neg_pool_range" "4084")]
4910 (define_insn "*movhi_bytes"
4911 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4912 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4913 "TARGET_ARM && TARGET_MMU_TRAPS"
4915 mov%?\\t%0, %1\\t%@ movhi
4916 mvn%?\\t%0, #%B1\\t%@ movhi"
4917 [(set_attr "predicable" "yes")]
4920 (define_insn "thumb_movhi_clobber"
4921 [(set (match_operand:HI 0 "memory_operand" "=m")
4922 (match_operand:HI 1 "register_operand" "l"))
4923 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4929 ;; We use a DImode scratch because we may occasionally need an additional
4930 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4931 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4932 (define_expand "reload_outhi"
4933 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4934 (match_operand:HI 1 "s_register_operand" "r")
4935 (match_operand:DI 2 "s_register_operand" "=&l")])]
4938 arm_reload_out_hi (operands);
4940 thumb_reload_out_hi (operands);
4945 (define_expand "reload_inhi"
4946 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4947 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4948 (match_operand:DI 2 "s_register_operand" "=&r")])]
4949 "TARGET_THUMB || (TARGET_ARM && TARGET_MMU_TRAPS)"
4952 arm_reload_in_hi (operands);
4954 thumb_reload_out_hi (operands);
4958 (define_expand "movqi"
4959 [(set (match_operand:QI 0 "general_operand" "")
4960 (match_operand:QI 1 "general_operand" ""))]
4965 /* Everything except mem = const or mem = mem can be done easily */
4967 if (!no_new_pseudos)
4969 if (GET_CODE (operands[1]) == CONST_INT)
4971 rtx reg = gen_reg_rtx (SImode);
4973 emit_insn (gen_movsi (reg, operands[1]));
4974 operands[1] = gen_lowpart (QImode, reg);
4976 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4978 rtx reg = gen_reg_rtx (SImode);
4980 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4981 operands[1] = gen_lowpart (QImode, reg);
4983 if (GET_CODE (operands[0]) == MEM)
4984 operands[1] = force_reg (QImode, operands[1]);
4987 else /* TARGET_THUMB */
4989 if (!no_new_pseudos)
4991 if (GET_CODE (operands[0]) != REG)
4992 operands[1] = force_reg (QImode, operands[1]);
4994 /* ??? We shouldn't really get invalid addresses here, but this can
4995 happen if we are passed a SP (never OK for HImode/QImode) or
4996 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4997 HImode/QImode) relative address. */
4998 /* ??? This should perhaps be fixed elsewhere, for instance, in
4999 fixup_stack_1, by checking for other kinds of invalid addresses,
5000 e.g. a bare reference to a virtual register. This may confuse the
5001 alpha though, which must handle this case differently. */
5002 if (GET_CODE (operands[0]) == MEM
5003 && !memory_address_p (GET_MODE (operands[0]),
5004 XEXP (operands[0], 0)))
5006 = replace_equiv_address (operands[0],
5007 copy_to_reg (XEXP (operands[0], 0)));
5008 if (GET_CODE (operands[1]) == MEM
5009 && !memory_address_p (GET_MODE (operands[1]),
5010 XEXP (operands[1], 0)))
5012 = replace_equiv_address (operands[1],
5013 copy_to_reg (XEXP (operands[1], 0)));
5015 /* Handle loading a large integer during reload. */
5016 else if (GET_CODE (operands[1]) == CONST_INT
5017 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
5019 /* Writing a constant to memory needs a scratch, which should
5020 be handled with SECONDARY_RELOADs. */
5021 if (GET_CODE (operands[0]) != REG)
5024 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5025 emit_insn (gen_movsi (operands[0], operands[1]));
5033 (define_insn "*arm_movqi_insn"
5034 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5035 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
5037 && ( register_operand (operands[0], QImode)
5038 || register_operand (operands[1], QImode))"
5044 [(set_attr "type" "*,*,load1,store1")
5045 (set_attr "predicable" "yes")]
5048 (define_insn "*thumb_movqi_insn"
5049 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5050 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5052 && ( register_operand (operands[0], QImode)
5053 || register_operand (operands[1], QImode))"
5061 [(set_attr "length" "2")
5062 (set_attr "type" "*,load1,store1,*,*,*")
5063 (set_attr "pool_range" "*,32,*,*,*,*")]
5066 (define_expand "movsf"
5067 [(set (match_operand:SF 0 "general_operand" "")
5068 (match_operand:SF 1 "general_operand" ""))]
5073 if (GET_CODE (operands[0]) == MEM)
5074 operands[1] = force_reg (SFmode, operands[1]);
5076 else /* TARGET_THUMB */
5078 if (!no_new_pseudos)
5080 if (GET_CODE (operands[0]) != REG)
5081 operands[1] = force_reg (SFmode, operands[1]);
5088 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5089 (match_operand:SF 1 "immediate_operand" ""))]
5091 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5093 && GET_CODE (operands[1]) == CONST_DOUBLE"
5094 [(set (match_dup 2) (match_dup 3))]
5096 operands[2] = gen_lowpart (SImode, operands[0]);
5097 operands[3] = gen_lowpart (SImode, operands[1]);
5098 if (operands[2] == 0 || operands[3] == 0)
5103 (define_insn "*arm_movsf_soft_insn"
5104 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5105 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5107 && TARGET_SOFT_FLOAT
5108 && (GET_CODE (operands[0]) != MEM
5109 || register_operand (operands[1], SFmode))"
5112 ldr%?\\t%0, %1\\t%@ float
5113 str%?\\t%1, %0\\t%@ float"
5114 [(set_attr "length" "4,4,4")
5115 (set_attr "predicable" "yes")
5116 (set_attr "type" "*,load1,store1")
5117 (set_attr "pool_range" "*,4096,*")
5118 (set_attr "neg_pool_range" "*,4084,*")]
5121 ;;; ??? This should have alternatives for constants.
5122 (define_insn "*thumb_movsf_insn"
5123 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5124 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5126 && ( register_operand (operands[0], SFmode)
5127 || register_operand (operands[1], SFmode))"
5136 [(set_attr "length" "2")
5137 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5138 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5141 (define_expand "movdf"
5142 [(set (match_operand:DF 0 "general_operand" "")
5143 (match_operand:DF 1 "general_operand" ""))]
5148 if (GET_CODE (operands[0]) == MEM)
5149 operands[1] = force_reg (DFmode, operands[1]);
5151 else /* TARGET_THUMB */
5153 if (!no_new_pseudos)
5155 if (GET_CODE (operands[0]) != REG)
5156 operands[1] = force_reg (DFmode, operands[1]);
5162 ;; Reloading a df mode value stored in integer regs to memory can require a
5164 (define_expand "reload_outdf"
5165 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5166 (match_operand:DF 1 "s_register_operand" "r")
5167 (match_operand:SI 2 "s_register_operand" "=&r")]
5171 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5174 operands[2] = XEXP (operands[0], 0);
5175 else if (code == POST_INC || code == PRE_DEC)
5177 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5178 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5179 emit_insn (gen_movdi (operands[0], operands[1]));
5182 else if (code == PRE_INC)
5184 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5186 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5189 else if (code == POST_DEC)
5190 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5192 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5193 XEXP (XEXP (operands[0], 0), 1)));
5195 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5198 if (code == POST_DEC)
5199 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5205 (define_insn "*movdf_soft_insn"
5206 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
5207 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
5208 "TARGET_ARM && TARGET_SOFT_FLOAT
5210 "* return output_move_double (operands);"
5211 [(set_attr "length" "8,8,8")
5212 (set_attr "type" "*,load2,store2")
5213 (set_attr "pool_range" "1020")
5214 (set_attr "neg_pool_range" "1008")]
5217 ;;; ??? This should have alternatives for constants.
5218 ;;; ??? This was originally identical to the movdi_insn pattern.
5219 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5220 ;;; thumb_reorg with a memory reference.
5221 (define_insn "*thumb_movdf_insn"
5222 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5223 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5225 && ( register_operand (operands[0], DFmode)
5226 || register_operand (operands[1], DFmode))"
5228 switch (which_alternative)
5232 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5233 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5234 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5236 return \"ldmia\\t%1, {%0, %H0}\";
5238 return \"stmia\\t%0, {%1, %H1}\";
5240 return thumb_load_double_from_address (operands);
5242 operands[2] = gen_rtx_MEM (SImode,
5243 plus_constant (XEXP (operands[0], 0), 4));
5244 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5247 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5248 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5249 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5252 [(set_attr "length" "4,2,2,6,4,4")
5253 (set_attr "type" "*,load2,store2,load2,store2,*")
5254 (set_attr "pool_range" "*,*,*,1020,*,*")]
5258 (define_expand "movv2si"
5259 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5260 (match_operand:V2SI 1 "general_operand" ""))]
5261 "TARGET_REALLY_IWMMXT"
5265 (define_expand "movv4hi"
5266 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5267 (match_operand:V4HI 1 "general_operand" ""))]
5268 "TARGET_REALLY_IWMMXT"
5272 (define_expand "movv8qi"
5273 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5274 (match_operand:V8QI 1 "general_operand" ""))]
5275 "TARGET_REALLY_IWMMXT"
5280 ;; load- and store-multiple insns
5281 ;; The arm can load/store any set of registers, provided that they are in
5282 ;; ascending order; but that is beyond GCC so stick with what it knows.
5284 (define_expand "load_multiple"
5285 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5286 (match_operand:SI 1 "" ""))
5287 (use (match_operand:SI 2 "" ""))])]
5290 /* Support only fixed point registers. */
5291 if (GET_CODE (operands[2]) != CONST_INT
5292 || INTVAL (operands[2]) > 14
5293 || INTVAL (operands[2]) < 2
5294 || GET_CODE (operands[1]) != MEM
5295 || GET_CODE (operands[0]) != REG
5296 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5297 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5301 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5302 force_reg (SImode, XEXP (operands[1], 0)),
5303 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
5304 MEM_IN_STRUCT_P(operands[1]),
5305 MEM_SCALAR_P (operands[1]));
5309 ;; Load multiple with write-back
5311 (define_insn "*ldmsi_postinc4"
5312 [(match_parallel 0 "load_multiple_operation"
5313 [(set (match_operand:SI 1 "s_register_operand" "=r")
5314 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5316 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5317 (mem:SI (match_dup 2)))
5318 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5319 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5320 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5321 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5322 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5323 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5324 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5325 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5326 [(set_attr "type" "load4")
5327 (set_attr "predicable" "yes")]
5330 (define_insn "*ldmsi_postinc3"
5331 [(match_parallel 0 "load_multiple_operation"
5332 [(set (match_operand:SI 1 "s_register_operand" "=r")
5333 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5335 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5336 (mem:SI (match_dup 2)))
5337 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5338 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5339 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5340 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5341 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5342 "ldm%?ia\\t%1!, {%3, %4, %5}"
5343 [(set_attr "type" "load3")
5344 (set_attr "predicable" "yes")]
5347 (define_insn "*ldmsi_postinc2"
5348 [(match_parallel 0 "load_multiple_operation"
5349 [(set (match_operand:SI 1 "s_register_operand" "=r")
5350 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5352 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5353 (mem:SI (match_dup 2)))
5354 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5355 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5356 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5357 "ldm%?ia\\t%1!, {%3, %4}"
5358 [(set_attr "type" "load2")
5359 (set_attr "predicable" "yes")]
5362 ;; Ordinary load multiple
5364 (define_insn "*ldmsi4"
5365 [(match_parallel 0 "load_multiple_operation"
5366 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5367 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5368 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5369 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5370 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5371 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5372 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5373 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5374 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5375 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5376 [(set_attr "type" "load4")
5377 (set_attr "predicable" "yes")]
5380 (define_insn "*ldmsi3"
5381 [(match_parallel 0 "load_multiple_operation"
5382 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5383 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5384 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5385 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5386 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5387 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5388 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5389 "ldm%?ia\\t%1, {%2, %3, %4}"
5390 [(set_attr "type" "load3")
5391 (set_attr "predicable" "yes")]
5394 (define_insn "*ldmsi2"
5395 [(match_parallel 0 "load_multiple_operation"
5396 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5397 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5398 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5399 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5400 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5401 "ldm%?ia\\t%1, {%2, %3}"
5402 [(set_attr "type" "load2")
5403 (set_attr "predicable" "yes")]
5406 (define_expand "store_multiple"
5407 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5408 (match_operand:SI 1 "" ""))
5409 (use (match_operand:SI 2 "" ""))])]
5412 /* Support only fixed point registers. */
5413 if (GET_CODE (operands[2]) != CONST_INT
5414 || INTVAL (operands[2]) > 14
5415 || INTVAL (operands[2]) < 2
5416 || GET_CODE (operands[1]) != REG
5417 || GET_CODE (operands[0]) != MEM
5418 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5419 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5423 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5424 force_reg (SImode, XEXP (operands[0], 0)),
5425 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
5426 MEM_IN_STRUCT_P(operands[0]),
5427 MEM_SCALAR_P (operands[0]));
5431 ;; Store multiple with write-back
5433 (define_insn "*stmsi_postinc4"
5434 [(match_parallel 0 "store_multiple_operation"
5435 [(set (match_operand:SI 1 "s_register_operand" "=r")
5436 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5438 (set (mem:SI (match_dup 2))
5439 (match_operand:SI 3 "arm_hard_register_operand" ""))
5440 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5441 (match_operand:SI 4 "arm_hard_register_operand" ""))
5442 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5443 (match_operand:SI 5 "arm_hard_register_operand" ""))
5444 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5445 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5446 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5447 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5448 [(set_attr "predicable" "yes")
5449 (set_attr "type" "store4")]
5452 (define_insn "*stmsi_postinc3"
5453 [(match_parallel 0 "store_multiple_operation"
5454 [(set (match_operand:SI 1 "s_register_operand" "=r")
5455 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5457 (set (mem:SI (match_dup 2))
5458 (match_operand:SI 3 "arm_hard_register_operand" ""))
5459 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5460 (match_operand:SI 4 "arm_hard_register_operand" ""))
5461 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5462 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5463 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5464 "stm%?ia\\t%1!, {%3, %4, %5}"
5465 [(set_attr "predicable" "yes")
5466 (set_attr "type" "store3")]
5469 (define_insn "*stmsi_postinc2"
5470 [(match_parallel 0 "store_multiple_operation"
5471 [(set (match_operand:SI 1 "s_register_operand" "=r")
5472 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5474 (set (mem:SI (match_dup 2))
5475 (match_operand:SI 3 "arm_hard_register_operand" ""))
5476 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5477 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5478 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5479 "stm%?ia\\t%1!, {%3, %4}"
5480 [(set_attr "predicable" "yes")
5481 (set_attr "type" "store2")]
5484 ;; Ordinary store multiple
5486 (define_insn "*stmsi4"
5487 [(match_parallel 0 "store_multiple_operation"
5488 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5489 (match_operand:SI 2 "arm_hard_register_operand" ""))
5490 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5491 (match_operand:SI 3 "arm_hard_register_operand" ""))
5492 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5493 (match_operand:SI 4 "arm_hard_register_operand" ""))
5494 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5495 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5496 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5497 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5498 [(set_attr "predicable" "yes")
5499 (set_attr "type" "store4")]
5502 (define_insn "*stmsi3"
5503 [(match_parallel 0 "store_multiple_operation"
5504 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5505 (match_operand:SI 2 "arm_hard_register_operand" ""))
5506 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5507 (match_operand:SI 3 "arm_hard_register_operand" ""))
5508 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5509 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5510 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5511 "stm%?ia\\t%1, {%2, %3, %4}"
5512 [(set_attr "predicable" "yes")
5513 (set_attr "type" "store3")]
5516 (define_insn "*stmsi2"
5517 [(match_parallel 0 "store_multiple_operation"
5518 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5519 (match_operand:SI 2 "arm_hard_register_operand" ""))
5520 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5521 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5522 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5523 "stm%?ia\\t%1, {%2, %3}"
5524 [(set_attr "predicable" "yes")
5525 (set_attr "type" "store2")]
5528 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5529 ;; We could let this apply for blocks of less than this, but it clobbers so
5530 ;; many registers that there is then probably a better way.
5532 (define_expand "movstrqi"
5533 [(match_operand:BLK 0 "general_operand" "")
5534 (match_operand:BLK 1 "general_operand" "")
5535 (match_operand:SI 2 "const_int_operand" "")
5536 (match_operand:SI 3 "const_int_operand" "")]
5541 if (arm_gen_movstrqi (operands))
5545 else /* TARGET_THUMB */
5547 if ( INTVAL (operands[3]) != 4
5548 || INTVAL (operands[2]) > 48)
5551 thumb_expand_movstrqi (operands);
5557 ;; Thumb block-move insns
5559 (define_insn "movmem12b"
5560 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5561 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5562 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5563 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5564 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5565 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5566 (set (match_operand:SI 0 "register_operand" "=l")
5567 (plus:SI (match_dup 2) (const_int 12)))
5568 (set (match_operand:SI 1 "register_operand" "=l")
5569 (plus:SI (match_dup 3) (const_int 12)))
5570 (clobber (match_scratch:SI 4 "=&l"))
5571 (clobber (match_scratch:SI 5 "=&l"))
5572 (clobber (match_scratch:SI 6 "=&l"))]
5574 "* return thumb_output_move_mem_multiple (3, operands);"
5575 [(set_attr "length" "4")
5576 ; This isn't entirely accurate... It loads as well, but in terms of
5577 ; scheduling the following insn it is better to consider it as a store
5578 (set_attr "type" "store3")]
5581 (define_insn "movmem8b"
5582 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5583 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5584 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5585 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5586 (set (match_operand:SI 0 "register_operand" "=l")
5587 (plus:SI (match_dup 2) (const_int 8)))
5588 (set (match_operand:SI 1 "register_operand" "=l")
5589 (plus:SI (match_dup 3) (const_int 8)))
5590 (clobber (match_scratch:SI 4 "=&l"))
5591 (clobber (match_scratch:SI 5 "=&l"))]
5593 "* return thumb_output_move_mem_multiple (2, operands);"
5594 [(set_attr "length" "4")
5595 ; This isn't entirely accurate... It loads as well, but in terms of
5596 ; scheduling the following insn it is better to consider it as a store
5597 (set_attr "type" "store2")]
5602 ;; Compare & branch insns
5603 ;; The range calculations are based as follows:
5604 ;; For forward branches, the address calculation returns the address of
5605 ;; the next instruction. This is 2 beyond the branch instruction.
5606 ;; For backward branches, the address calculation returns the address of
5607 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5608 ;; instruction for the shortest sequence, and 4 before the branch instruction
5609 ;; if we have to jump around an unconditional branch.
5610 ;; To the basic branch range the PC offset must be added (this is +4).
5611 ;; So for forward branches we have
5612 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5613 ;; And for backward branches we have
5614 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5616 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5617 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5619 (define_expand "cbranchsi4"
5620 [(set (pc) (if_then_else
5621 (match_operator 0 "arm_comparison_operator"
5622 [(match_operand:SI 1 "s_register_operand" "")
5623 (match_operand:SI 2 "nonmemory_operand" "")])
5624 (label_ref (match_operand 3 "" ""))
5628 if (thumb_cmpneg_operand (operands[2], SImode))
5630 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5631 operands[3], operands[0]));
5634 if (!thumb_cmp_operand (operands[2], SImode))
5635 operands[2] = force_reg (SImode, operands[2]);
5638 (define_insn "*cbranchsi4_insn"
5639 [(set (pc) (if_then_else
5640 (match_operator 0 "arm_comparison_operator"
5641 [(match_operand:SI 1 "s_register_operand" "l,*h")
5642 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5643 (label_ref (match_operand 3 "" ""))
5647 output_asm_insn (\"cmp\\t%1, %2\", operands);
5649 switch (get_attr_length (insn))
5651 case 4: return \"b%d0\\t%l3\";
5652 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5653 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5656 [(set (attr "far_jump")
5658 (eq_attr "length" "8")
5659 (const_string "yes")
5660 (const_string "no")))
5661 (set (attr "length")
5663 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5664 (le (minus (match_dup 3) (pc)) (const_int 256)))
5667 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5668 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5673 (define_insn "cbranchsi4_scratch"
5674 [(set (pc) (if_then_else
5675 (match_operator 4 "arm_comparison_operator"
5676 [(match_operand:SI 1 "s_register_operand" "l,0")
5677 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5678 (label_ref (match_operand 3 "" ""))
5680 (clobber (match_scratch:SI 0 "=l,l"))]
5683 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5685 switch (get_attr_length (insn))
5687 case 4: return \"b%d4\\t%l3\";
5688 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5689 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5692 [(set (attr "far_jump")
5694 (eq_attr "length" "8")
5695 (const_string "yes")
5696 (const_string "no")))
5697 (set (attr "length")
5699 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5700 (le (minus (match_dup 3) (pc)) (const_int 256)))
5703 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5704 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5708 (define_insn "*movsi_cbranchsi4"
5711 (match_operator 3 "arm_comparison_operator"
5712 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5714 (label_ref (match_operand 2 "" ""))
5716 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5720 if (which_alternative == 0)
5721 output_asm_insn (\"cmp\t%0, #0\", operands);
5722 else if (which_alternative == 1)
5723 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5726 output_asm_insn (\"cmp\t%1, #0\", operands);
5727 if (which_alternative == 2)
5728 output_asm_insn (\"mov\t%0, %1\", operands);
5730 output_asm_insn (\"str\t%1, %0\", operands);
5732 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5734 case 4: return \"b%d3\\t%l2\";
5735 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5736 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5739 [(set (attr "far_jump")
5741 (ior (and (gt (symbol_ref ("which_alternative"))
5743 (eq_attr "length" "8"))
5744 (eq_attr "length" "10"))
5745 (const_string "yes")
5746 (const_string "no")))
5747 (set (attr "length")
5749 (le (symbol_ref ("which_alternative"))
5752 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5753 (le (minus (match_dup 2) (pc)) (const_int 256)))
5756 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5757 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5761 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5762 (le (minus (match_dup 2) (pc)) (const_int 256)))
5765 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5766 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5771 (define_insn "*negated_cbranchsi4"
5774 (match_operator 0 "arm_comparison_operator"
5775 [(match_operand:SI 1 "s_register_operand" "l")
5776 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5777 (label_ref (match_operand 3 "" ""))
5781 output_asm_insn (\"cmn\\t%1, %2\", operands);
5782 switch (get_attr_length (insn))
5784 case 4: return \"b%d0\\t%l3\";
5785 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5786 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5789 [(set (attr "far_jump")
5791 (eq_attr "length" "8")
5792 (const_string "yes")
5793 (const_string "no")))
5794 (set (attr "length")
5796 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5797 (le (minus (match_dup 3) (pc)) (const_int 256)))
5800 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5801 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5806 (define_insn "*tbit_cbranch"
5809 (match_operator 0 "equality_operator"
5810 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5812 (match_operand:SI 2 "const_int_operand" "i"))
5814 (label_ref (match_operand 3 "" ""))
5816 (clobber (match_scratch:SI 4 "=l"))]
5821 op[0] = operands[4];
5822 op[1] = operands[1];
5823 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5825 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5826 switch (get_attr_length (insn))
5828 case 4: return \"b%d0\\t%l3\";
5829 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5830 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5833 [(set (attr "far_jump")
5835 (eq_attr "length" "8")
5836 (const_string "yes")
5837 (const_string "no")))
5838 (set (attr "length")
5840 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5841 (le (minus (match_dup 3) (pc)) (const_int 256)))
5844 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5845 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5850 (define_insn "*tstsi3_cbranch"
5853 (match_operator 3 "equality_operator"
5854 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5855 (match_operand:SI 1 "s_register_operand" "l"))
5857 (label_ref (match_operand 2 "" ""))
5862 output_asm_insn (\"tst\\t%0, %1\", operands);
5863 switch (get_attr_length (insn))
5865 case 4: return \"b%d3\\t%l2\";
5866 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5867 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5870 [(set (attr "far_jump")
5872 (eq_attr "length" "8")
5873 (const_string "yes")
5874 (const_string "no")))
5875 (set (attr "length")
5877 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5878 (le (minus (match_dup 2) (pc)) (const_int 256)))
5881 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5882 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5887 (define_insn "*andsi3_cbranch"
5890 (match_operator 5 "equality_operator"
5891 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5892 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5894 (label_ref (match_operand 4 "" ""))
5896 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5897 (and:SI (match_dup 2) (match_dup 3)))
5898 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5902 if (which_alternative == 0)
5903 output_asm_insn (\"and\\t%0, %3\", operands);
5904 else if (which_alternative == 1)
5906 output_asm_insn (\"and\\t%1, %3\", operands);
5907 output_asm_insn (\"mov\\t%0, %1\", operands);
5911 output_asm_insn (\"and\\t%1, %3\", operands);
5912 output_asm_insn (\"str\\t%1, %0\", operands);
5915 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5917 case 4: return \"b%d5\\t%l4\";
5918 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5919 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5922 [(set (attr "far_jump")
5924 (ior (and (eq (symbol_ref ("which_alternative"))
5926 (eq_attr "length" "8"))
5927 (eq_attr "length" "10"))
5928 (const_string "yes")
5929 (const_string "no")))
5930 (set (attr "length")
5932 (eq (symbol_ref ("which_alternative"))
5935 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5936 (le (minus (match_dup 4) (pc)) (const_int 256)))
5939 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
5940 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5944 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
5945 (le (minus (match_dup 4) (pc)) (const_int 256)))
5948 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
5949 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5954 (define_insn "*orrsi3_cbranch_scratch"
5957 (match_operator 4 "equality_operator"
5958 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
5959 (match_operand:SI 2 "s_register_operand" "l"))
5961 (label_ref (match_operand 3 "" ""))
5963 (clobber (match_scratch:SI 0 "=l"))]
5967 output_asm_insn (\"orr\\t%0, %2\", operands);
5968 switch (get_attr_length (insn))
5970 case 4: return \"b%d4\\t%l3\";
5971 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5972 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5975 [(set (attr "far_jump")
5977 (eq_attr "length" "8")
5978 (const_string "yes")
5979 (const_string "no")))
5980 (set (attr "length")
5982 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5983 (le (minus (match_dup 3) (pc)) (const_int 256)))
5986 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5987 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5992 (define_insn "*orrsi3_cbranch"
5995 (match_operator 5 "equality_operator"
5996 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5997 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5999 (label_ref (match_operand 4 "" ""))
6001 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6002 (ior:SI (match_dup 2) (match_dup 3)))
6003 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6007 if (which_alternative == 0)
6008 output_asm_insn (\"orr\\t%0, %3\", operands);
6009 else if (which_alternative == 1)
6011 output_asm_insn (\"orr\\t%1, %3\", operands);
6012 output_asm_insn (\"mov\\t%0, %1\", operands);
6016 output_asm_insn (\"orr\\t%1, %3\", operands);
6017 output_asm_insn (\"str\\t%1, %0\", operands);
6020 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6022 case 4: return \"b%d5\\t%l4\";
6023 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6024 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6027 [(set (attr "far_jump")
6029 (ior (and (eq (symbol_ref ("which_alternative"))
6031 (eq_attr "length" "8"))
6032 (eq_attr "length" "10"))
6033 (const_string "yes")
6034 (const_string "no")))
6035 (set (attr "length")
6037 (eq (symbol_ref ("which_alternative"))
6040 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6041 (le (minus (match_dup 4) (pc)) (const_int 256)))
6044 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6045 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6049 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6050 (le (minus (match_dup 4) (pc)) (const_int 256)))
6053 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6054 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6059 (define_insn "*xorsi3_cbranch_scratch"
6062 (match_operator 4 "equality_operator"
6063 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6064 (match_operand:SI 2 "s_register_operand" "l"))
6066 (label_ref (match_operand 3 "" ""))
6068 (clobber (match_scratch:SI 0 "=l"))]
6072 output_asm_insn (\"eor\\t%0, %2\", operands);
6073 switch (get_attr_length (insn))
6075 case 4: return \"b%d4\\t%l3\";
6076 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6077 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6080 [(set (attr "far_jump")
6082 (eq_attr "length" "8")
6083 (const_string "yes")
6084 (const_string "no")))
6085 (set (attr "length")
6087 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6088 (le (minus (match_dup 3) (pc)) (const_int 256)))
6091 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6092 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6097 (define_insn "*xorsi3_cbranch"
6100 (match_operator 5 "equality_operator"
6101 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6102 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6104 (label_ref (match_operand 4 "" ""))
6106 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6107 (xor:SI (match_dup 2) (match_dup 3)))
6108 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6112 if (which_alternative == 0)
6113 output_asm_insn (\"eor\\t%0, %3\", operands);
6114 else if (which_alternative == 1)
6116 output_asm_insn (\"eor\\t%1, %3\", operands);
6117 output_asm_insn (\"mov\\t%0, %1\", operands);
6121 output_asm_insn (\"eor\\t%1, %3\", operands);
6122 output_asm_insn (\"str\\t%1, %0\", operands);
6125 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6127 case 4: return \"b%d5\\t%l4\";
6128 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6129 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6132 [(set (attr "far_jump")
6134 (ior (and (eq (symbol_ref ("which_alternative"))
6136 (eq_attr "length" "8"))
6137 (eq_attr "length" "10"))
6138 (const_string "yes")
6139 (const_string "no")))
6140 (set (attr "length")
6142 (eq (symbol_ref ("which_alternative"))
6145 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6146 (le (minus (match_dup 4) (pc)) (const_int 256)))
6149 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6150 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6154 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6155 (le (minus (match_dup 4) (pc)) (const_int 256)))
6158 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6159 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6164 (define_insn "*bicsi3_cbranch_scratch"
6167 (match_operator 4 "equality_operator"
6168 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6169 (match_operand:SI 1 "s_register_operand" "0"))
6171 (label_ref (match_operand 3 "" ""))
6173 (clobber (match_scratch:SI 0 "=l"))]
6177 output_asm_insn (\"bic\\t%0, %2\", operands);
6178 switch (get_attr_length (insn))
6180 case 4: return \"b%d4\\t%l3\";
6181 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6182 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6185 [(set (attr "far_jump")
6187 (eq_attr "length" "8")
6188 (const_string "yes")
6189 (const_string "no")))
6190 (set (attr "length")
6192 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6193 (le (minus (match_dup 3) (pc)) (const_int 256)))
6196 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6197 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6202 (define_insn "*bicsi3_cbranch"
6205 (match_operator 5 "equality_operator"
6206 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6207 (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
6209 (label_ref (match_operand 4 "" ""))
6211 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6212 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6213 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6217 if (which_alternative == 0)
6218 output_asm_insn (\"bic\\t%0, %3\", operands);
6219 else if (which_alternative == 1)
6221 output_asm_insn (\"bic\\t%1, %3\", operands);
6222 output_asm_insn (\"mov\\t%0, %1\", operands);
6226 output_asm_insn (\"bic\\t%1, %3\", operands);
6227 output_asm_insn (\"str\\t%1, %0\", operands);
6230 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6232 case 4: return \"b%d5\\t%l4\";
6233 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6234 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6237 [(set (attr "far_jump")
6239 (ior (and (eq (symbol_ref ("which_alternative"))
6241 (eq_attr "length" "8"))
6242 (eq_attr "length" "10"))
6243 (const_string "yes")
6244 (const_string "no")))
6245 (set (attr "length")
6247 (eq (symbol_ref ("which_alternative"))
6250 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6251 (le (minus (match_dup 4) (pc)) (const_int 256)))
6254 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6255 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6259 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6260 (le (minus (match_dup 4) (pc)) (const_int 256)))
6263 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6264 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6269 (define_insn "*cbranchne_decr1"
6271 (if_then_else (match_operator 3 "equality_operator"
6272 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6274 (label_ref (match_operand 4 "" ""))
6276 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6277 (plus:SI (match_dup 2) (const_int -1)))
6278 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6283 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6285 VOIDmode, operands[2], const1_rtx);
6286 cond[1] = operands[4];
6288 if (which_alternative == 0)
6289 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6290 else if (which_alternative == 1)
6292 /* We must provide an alternative for a hi reg because reload
6293 cannot handle output reloads on a jump instruction, but we
6294 can't subtract into that. Fortunately a mov from lo to hi
6295 does not clobber the condition codes. */
6296 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6297 output_asm_insn (\"mov\\t%0, %1\", operands);
6301 /* Similarly, but the target is memory. */
6302 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6303 output_asm_insn (\"str\\t%1, %0\", operands);
6306 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6309 output_asm_insn (\"b%d0\\t%l1\", cond);
6312 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6313 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6315 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6316 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6320 [(set (attr "far_jump")
6322 (ior (and (eq (symbol_ref ("which_alternative"))
6324 (eq_attr "length" "8"))
6325 (eq_attr "length" "10"))
6326 (const_string "yes")
6327 (const_string "no")))
6328 (set_attr_alternative "length"
6332 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6333 (le (minus (match_dup 4) (pc)) (const_int 256)))
6336 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6337 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6342 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6343 (le (minus (match_dup 4) (pc)) (const_int 256)))
6346 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6347 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6352 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6353 (le (minus (match_dup 4) (pc)) (const_int 256)))
6356 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6357 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6362 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6363 (le (minus (match_dup 4) (pc)) (const_int 256)))
6366 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6367 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6372 (define_insn "*addsi3_cbranch"
6375 (match_operator 4 "comparison_operator"
6377 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6378 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6380 (label_ref (match_operand 5 "" ""))
6383 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6384 (plus:SI (match_dup 2) (match_dup 3)))
6385 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6387 && (GET_CODE (operands[4]) == EQ
6388 || GET_CODE (operands[4]) == NE
6389 || GET_CODE (operands[4]) == GE
6390 || GET_CODE (operands[4]) == LT)"
6396 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6397 cond[1] = operands[2];
6398 cond[2] = operands[3];
6400 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6401 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6403 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6405 if (which_alternative >= 3
6406 && which_alternative < 4)
6407 output_asm_insn (\"mov\\t%0, %1\", operands);
6408 else if (which_alternative >= 4)
6409 output_asm_insn (\"str\\t%1, %0\", operands);
6411 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6414 return \"b%d4\\t%l5\";
6416 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6418 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6422 [(set (attr "far_jump")
6424 (ior (and (lt (symbol_ref ("which_alternative"))
6426 (eq_attr "length" "8"))
6427 (eq_attr "length" "10"))
6428 (const_string "yes")
6429 (const_string "no")))
6430 (set (attr "length")
6432 (lt (symbol_ref ("which_alternative"))
6435 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6436 (le (minus (match_dup 5) (pc)) (const_int 256)))
6439 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6440 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6444 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6445 (le (minus (match_dup 5) (pc)) (const_int 256)))
6448 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6449 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6454 (define_insn "*addsi3_cbranch_scratch"
6457 (match_operator 3 "comparison_operator"
6459 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6460 (match_operand:SI 2 "reg_or_int_operand" "J,l,I,L"))
6462 (label_ref (match_operand 4 "" ""))
6464 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6466 && (GET_CODE (operands[3]) == EQ
6467 || GET_CODE (operands[3]) == NE
6468 || GET_CODE (operands[3]) == GE
6469 || GET_CODE (operands[3]) == LT)"
6472 switch (which_alternative)
6475 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6478 output_asm_insn (\"cmn\t%1, %2\", operands);
6481 output_asm_insn (\"add\t%0, %1, %2\", operands);
6484 output_asm_insn (\"add\t%0, %0, %2\", operands);
6488 switch (get_attr_length (insn))
6491 return \"b%d3\\t%l4\";
6493 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6495 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6499 [(set (attr "far_jump")
6501 (eq_attr "length" "8")
6502 (const_string "yes")
6503 (const_string "no")))
6504 (set (attr "length")
6506 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6507 (le (minus (match_dup 4) (pc)) (const_int 256)))
6510 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6511 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6516 (define_insn "*subsi3_cbranch"
6519 (match_operator 4 "comparison_operator"
6521 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6522 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6524 (label_ref (match_operand 5 "" ""))
6526 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6527 (minus:SI (match_dup 2) (match_dup 3)))
6528 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6530 && (GET_CODE (operands[4]) == EQ
6531 || GET_CODE (operands[4]) == NE
6532 || GET_CODE (operands[4]) == GE
6533 || GET_CODE (operands[4]) == LT)"
6536 if (which_alternative == 0)
6537 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6538 else if (which_alternative == 1)
6540 /* We must provide an alternative for a hi reg because reload
6541 cannot handle output reloads on a jump instruction, but we
6542 can't subtract into that. Fortunately a mov from lo to hi
6543 does not clobber the condition codes. */
6544 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6545 output_asm_insn (\"mov\\t%0, %1\", operands);
6549 /* Similarly, but the target is memory. */
6550 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6551 output_asm_insn (\"str\\t%1, %0\", operands);
6554 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6557 return \"b%d4\\t%l5\";
6559 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6561 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6565 [(set (attr "far_jump")
6567 (ior (and (eq (symbol_ref ("which_alternative"))
6569 (eq_attr "length" "8"))
6570 (eq_attr "length" "10"))
6571 (const_string "yes")
6572 (const_string "no")))
6573 (set (attr "length")
6575 (eq (symbol_ref ("which_alternative"))
6578 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6579 (le (minus (match_dup 5) (pc)) (const_int 256)))
6582 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6583 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6587 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6588 (le (minus (match_dup 5) (pc)) (const_int 256)))
6591 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6592 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6597 (define_insn "*subsi3_cbranch_scratch"
6600 (match_operator 0 "arm_comparison_operator"
6601 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6602 (match_operand:SI 2 "nonmemory_operand" "l"))
6604 (label_ref (match_operand 3 "" ""))
6607 && (GET_CODE (operands[0]) == EQ
6608 || GET_CODE (operands[0]) == NE
6609 || GET_CODE (operands[0]) == GE
6610 || GET_CODE (operands[0]) == LT)"
6612 output_asm_insn (\"cmp\\t%1, %2\", operands);
6613 switch (get_attr_length (insn))
6615 case 4: return \"b%d0\\t%l3\";
6616 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6617 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6620 [(set (attr "far_jump")
6622 (eq_attr "length" "8")
6623 (const_string "yes")
6624 (const_string "no")))
6625 (set (attr "length")
6627 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6628 (le (minus (match_dup 3) (pc)) (const_int 256)))
6631 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6632 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6637 ;; Comparison and test insns
6639 (define_expand "cmpsi"
6640 [(match_operand:SI 0 "s_register_operand" "")
6641 (match_operand:SI 1 "arm_add_operand" "")]
6644 arm_compare_op0 = operands[0];
6645 arm_compare_op1 = operands[1];
6650 (define_expand "cmpsf"
6651 [(match_operand:SF 0 "s_register_operand" "")
6652 (match_operand:SF 1 "arm_float_compare_operand" "")]
6653 "TARGET_ARM && TARGET_HARD_FLOAT"
6655 arm_compare_op0 = operands[0];
6656 arm_compare_op1 = operands[1];
6661 (define_expand "cmpdf"
6662 [(match_operand:DF 0 "s_register_operand" "")
6663 (match_operand:DF 1 "arm_float_compare_operand" "")]
6664 "TARGET_ARM && TARGET_HARD_FLOAT"
6666 arm_compare_op0 = operands[0];
6667 arm_compare_op1 = operands[1];
6672 (define_insn "*arm_cmpsi_insn"
6673 [(set (reg:CC CC_REGNUM)
6674 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6675 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6680 [(set_attr "conds" "set")]
6683 (define_insn "*cmpsi_shiftsi"
6684 [(set (reg:CC CC_REGNUM)
6685 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6686 (match_operator:SI 3 "shift_operator"
6687 [(match_operand:SI 1 "s_register_operand" "r")
6688 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6691 [(set_attr "conds" "set")
6692 (set_attr "shift" "1")
6693 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6694 (const_string "alu_shift")
6695 (const_string "alu_shift_reg")))]
6698 (define_insn "*cmpsi_shiftsi_swp"
6699 [(set (reg:CC_SWP CC_REGNUM)
6700 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6701 [(match_operand:SI 1 "s_register_operand" "r")
6702 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6703 (match_operand:SI 0 "s_register_operand" "r")))]
6706 [(set_attr "conds" "set")
6707 (set_attr "shift" "1")
6708 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6709 (const_string "alu_shift")
6710 (const_string "alu_shift_reg")))]
6713 (define_insn "*cmpsi_neg_shiftsi"
6714 [(set (reg:CC CC_REGNUM)
6715 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6716 (neg:SI (match_operator:SI 3 "shift_operator"
6717 [(match_operand:SI 1 "s_register_operand" "r")
6718 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
6721 [(set_attr "conds" "set")
6722 (set_attr "shift" "1")
6723 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6724 (const_string "alu_shift")
6725 (const_string "alu_shift_reg")))]
6728 ;; Cirrus SF compare instruction
6729 (define_insn "*cirrus_cmpsf"
6730 [(set (reg:CCFP CC_REGNUM)
6731 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6732 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6733 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6734 "cfcmps%?\\tr15, %V0, %V1"
6735 [(set_attr "type" "mav_farith")
6736 (set_attr "cirrus" "compare")]
6739 ;; Cirrus DF compare instruction
6740 (define_insn "*cirrus_cmpdf"
6741 [(set (reg:CCFP CC_REGNUM)
6742 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6743 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6744 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6745 "cfcmpd%?\\tr15, %V0, %V1"
6746 [(set_attr "type" "mav_farith")
6747 (set_attr "cirrus" "compare")]
6750 ;; Cirrus DI compare instruction
6751 (define_expand "cmpdi"
6752 [(match_operand:DI 0 "cirrus_fp_register" "")
6753 (match_operand:DI 1 "cirrus_fp_register" "")]
6754 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6756 arm_compare_op0 = operands[0];
6757 arm_compare_op1 = operands[1];
6761 (define_insn "*cirrus_cmpdi"
6762 [(set (reg:CC CC_REGNUM)
6763 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6764 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6765 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6766 "cfcmp64%?\\tr15, %V0, %V1"
6767 [(set_attr "type" "mav_farith")
6768 (set_attr "cirrus" "compare")]
6771 ; This insn allows redundant compares to be removed by cse, nothing should
6772 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6773 ; is deleted later on. The match_dup will match the mode here, so that
6774 ; mode changes of the condition codes aren't lost by this even though we don't
6775 ; specify what they are.
6777 (define_insn "*deleted_compare"
6778 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6780 "\\t%@ deleted compare"
6781 [(set_attr "conds" "set")
6782 (set_attr "length" "0")]
6786 ;; Conditional branch insns
6788 (define_expand "beq"
6790 (if_then_else (eq (match_dup 1) (const_int 0))
6791 (label_ref (match_operand 0 "" ""))
6794 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6797 (define_expand "bne"
6799 (if_then_else (ne (match_dup 1) (const_int 0))
6800 (label_ref (match_operand 0 "" ""))
6803 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6806 (define_expand "bgt"
6808 (if_then_else (gt (match_dup 1) (const_int 0))
6809 (label_ref (match_operand 0 "" ""))
6812 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6815 (define_expand "ble"
6817 (if_then_else (le (match_dup 1) (const_int 0))
6818 (label_ref (match_operand 0 "" ""))
6821 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6824 (define_expand "bge"
6826 (if_then_else (ge (match_dup 1) (const_int 0))
6827 (label_ref (match_operand 0 "" ""))
6830 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6833 (define_expand "blt"
6835 (if_then_else (lt (match_dup 1) (const_int 0))
6836 (label_ref (match_operand 0 "" ""))
6839 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6842 (define_expand "bgtu"
6844 (if_then_else (gtu (match_dup 1) (const_int 0))
6845 (label_ref (match_operand 0 "" ""))
6848 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6851 (define_expand "bleu"
6853 (if_then_else (leu (match_dup 1) (const_int 0))
6854 (label_ref (match_operand 0 "" ""))
6857 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6860 (define_expand "bgeu"
6862 (if_then_else (geu (match_dup 1) (const_int 0))
6863 (label_ref (match_operand 0 "" ""))
6866 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6869 (define_expand "bltu"
6871 (if_then_else (ltu (match_dup 1) (const_int 0))
6872 (label_ref (match_operand 0 "" ""))
6875 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6878 (define_expand "bunordered"
6880 (if_then_else (unordered (match_dup 1) (const_int 0))
6881 (label_ref (match_operand 0 "" ""))
6883 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6884 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6888 (define_expand "bordered"
6890 (if_then_else (ordered (match_dup 1) (const_int 0))
6891 (label_ref (match_operand 0 "" ""))
6893 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6894 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6898 (define_expand "bungt"
6900 (if_then_else (ungt (match_dup 1) (const_int 0))
6901 (label_ref (match_operand 0 "" ""))
6903 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6904 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
6907 (define_expand "bunlt"
6909 (if_then_else (unlt (match_dup 1) (const_int 0))
6910 (label_ref (match_operand 0 "" ""))
6912 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6913 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6916 (define_expand "bunge"
6918 (if_then_else (unge (match_dup 1) (const_int 0))
6919 (label_ref (match_operand 0 "" ""))
6921 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6922 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6925 (define_expand "bunle"
6927 (if_then_else (unle (match_dup 1) (const_int 0))
6928 (label_ref (match_operand 0 "" ""))
6930 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6931 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
6934 ;; The following two patterns need two branch instructions, since there is
6935 ;; no single instruction that will handle all cases.
6936 (define_expand "buneq"
6938 (if_then_else (uneq (match_dup 1) (const_int 0))
6939 (label_ref (match_operand 0 "" ""))
6941 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6942 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
6945 (define_expand "bltgt"
6947 (if_then_else (ltgt (match_dup 1) (const_int 0))
6948 (label_ref (match_operand 0 "" ""))
6950 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6951 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
6955 ;; Patterns to match conditional branch insns.
6958 ; Special pattern to match UNEQ.
6959 (define_insn "*arm_buneq"
6961 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6962 (label_ref (match_operand 0 "" ""))
6964 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6966 if (arm_ccfsm_state != 0)
6969 return \"bvs\\t%l0\;beq\\t%l0\";
6971 [(set_attr "conds" "jump_clob")
6972 (set_attr "length" "8")]
6975 ; Special pattern to match LTGT.
6976 (define_insn "*arm_bltgt"
6978 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
6979 (label_ref (match_operand 0 "" ""))
6981 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6983 if (arm_ccfsm_state != 0)
6986 return \"bmi\\t%l0\;bgt\\t%l0\";
6988 [(set_attr "conds" "jump_clob")
6989 (set_attr "length" "8")]
6992 (define_insn "*arm_cond_branch"
6994 (if_then_else (match_operator 1 "arm_comparison_operator"
6995 [(match_operand 2 "cc_register" "") (const_int 0)])
6996 (label_ref (match_operand 0 "" ""))
7000 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7002 arm_ccfsm_state += 2;
7005 return \"b%d1\\t%l0\";
7007 [(set_attr "conds" "use")
7008 (set_attr "type" "branch")]
7011 ; Special pattern to match reversed UNEQ.
7012 (define_insn "*arm_buneq_reversed"
7014 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
7016 (label_ref (match_operand 0 "" ""))))]
7017 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7019 if (arm_ccfsm_state != 0)
7022 return \"bmi\\t%l0\;bgt\\t%l0\";
7024 [(set_attr "conds" "jump_clob")
7025 (set_attr "length" "8")]
7028 ; Special pattern to match reversed LTGT.
7029 (define_insn "*arm_bltgt_reversed"
7031 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7033 (label_ref (match_operand 0 "" ""))))]
7034 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7036 if (arm_ccfsm_state != 0)
7039 return \"bvs\\t%l0\;beq\\t%l0\";
7041 [(set_attr "conds" "jump_clob")
7042 (set_attr "length" "8")]
7045 (define_insn "*arm_cond_branch_reversed"
7047 (if_then_else (match_operator 1 "arm_comparison_operator"
7048 [(match_operand 2 "cc_register" "") (const_int 0)])
7050 (label_ref (match_operand 0 "" ""))))]
7053 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7055 arm_ccfsm_state += 2;
7058 return \"b%D1\\t%l0\";
7060 [(set_attr "conds" "use")
7061 (set_attr "type" "branch")]
7068 (define_expand "seq"
7069 [(set (match_operand:SI 0 "s_register_operand" "")
7070 (eq:SI (match_dup 1) (const_int 0)))]
7072 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7075 (define_expand "sne"
7076 [(set (match_operand:SI 0 "s_register_operand" "")
7077 (ne:SI (match_dup 1) (const_int 0)))]
7079 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7082 (define_expand "sgt"
7083 [(set (match_operand:SI 0 "s_register_operand" "")
7084 (gt:SI (match_dup 1) (const_int 0)))]
7086 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7089 (define_expand "sle"
7090 [(set (match_operand:SI 0 "s_register_operand" "")
7091 (le:SI (match_dup 1) (const_int 0)))]
7093 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7096 (define_expand "sge"
7097 [(set (match_operand:SI 0 "s_register_operand" "")
7098 (ge:SI (match_dup 1) (const_int 0)))]
7100 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7103 (define_expand "slt"
7104 [(set (match_operand:SI 0 "s_register_operand" "")
7105 (lt:SI (match_dup 1) (const_int 0)))]
7107 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7110 (define_expand "sgtu"
7111 [(set (match_operand:SI 0 "s_register_operand" "")
7112 (gtu:SI (match_dup 1) (const_int 0)))]
7114 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7117 (define_expand "sleu"
7118 [(set (match_operand:SI 0 "s_register_operand" "")
7119 (leu:SI (match_dup 1) (const_int 0)))]
7121 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7124 (define_expand "sgeu"
7125 [(set (match_operand:SI 0 "s_register_operand" "")
7126 (geu:SI (match_dup 1) (const_int 0)))]
7128 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7131 (define_expand "sltu"
7132 [(set (match_operand:SI 0 "s_register_operand" "")
7133 (ltu:SI (match_dup 1) (const_int 0)))]
7135 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7138 (define_expand "sunordered"
7139 [(set (match_operand:SI 0 "s_register_operand" "")
7140 (unordered:SI (match_dup 1) (const_int 0)))]
7141 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7142 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7146 (define_expand "sordered"
7147 [(set (match_operand:SI 0 "s_register_operand" "")
7148 (ordered:SI (match_dup 1) (const_int 0)))]
7149 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7150 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7154 (define_expand "sungt"
7155 [(set (match_operand:SI 0 "s_register_operand" "")
7156 (ungt:SI (match_dup 1) (const_int 0)))]
7157 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7158 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7162 (define_expand "sunge"
7163 [(set (match_operand:SI 0 "s_register_operand" "")
7164 (unge:SI (match_dup 1) (const_int 0)))]
7165 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7166 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7170 (define_expand "sunlt"
7171 [(set (match_operand:SI 0 "s_register_operand" "")
7172 (unlt:SI (match_dup 1) (const_int 0)))]
7173 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7174 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7178 (define_expand "sunle"
7179 [(set (match_operand:SI 0 "s_register_operand" "")
7180 (unle:SI (match_dup 1) (const_int 0)))]
7181 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7182 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7186 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7187 ;;; simple ARM instructions.
7189 ; (define_expand "suneq"
7190 ; [(set (match_operand:SI 0 "s_register_operand" "")
7191 ; (uneq:SI (match_dup 1) (const_int 0)))]
7192 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7196 ; (define_expand "sltgt"
7197 ; [(set (match_operand:SI 0 "s_register_operand" "")
7198 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7199 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7203 (define_insn "*mov_scc"
7204 [(set (match_operand:SI 0 "s_register_operand" "=r")
7205 (match_operator:SI 1 "arm_comparison_operator"
7206 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7208 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7209 [(set_attr "conds" "use")
7210 (set_attr "length" "8")]
7213 (define_insn "*mov_negscc"
7214 [(set (match_operand:SI 0 "s_register_operand" "=r")
7215 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7216 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7218 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7219 [(set_attr "conds" "use")
7220 (set_attr "length" "8")]
7223 (define_insn "*mov_notscc"
7224 [(set (match_operand:SI 0 "s_register_operand" "=r")
7225 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7226 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7228 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7229 [(set_attr "conds" "use")
7230 (set_attr "length" "8")]
7234 ;; Conditional move insns
7236 (define_expand "movsicc"
7237 [(set (match_operand:SI 0 "s_register_operand" "")
7238 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7239 (match_operand:SI 2 "arm_not_operand" "")
7240 (match_operand:SI 3 "arm_not_operand" "")))]
7244 enum rtx_code code = GET_CODE (operands[1]);
7247 if (code == UNEQ || code == LTGT)
7250 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7251 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7255 (define_expand "movsfcc"
7256 [(set (match_operand:SF 0 "s_register_operand" "")
7257 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7258 (match_operand:SF 2 "s_register_operand" "")
7259 (match_operand:SF 3 "nonmemory_operand" "")))]
7263 enum rtx_code code = GET_CODE (operands[1]);
7266 if (code == UNEQ || code == LTGT)
7269 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7270 Otherwise, ensure it is a valid FP add operand */
7271 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7272 || (!arm_float_add_operand (operands[3], SFmode)))
7273 operands[3] = force_reg (SFmode, operands[3]);
7275 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7276 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7280 (define_expand "movdfcc"
7281 [(set (match_operand:DF 0 "s_register_operand" "")
7282 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7283 (match_operand:DF 2 "s_register_operand" "")
7284 (match_operand:DF 3 "arm_float_add_operand" "")))]
7285 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7288 enum rtx_code code = GET_CODE (operands[1]);
7291 if (code == UNEQ || code == LTGT)
7294 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7295 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7299 (define_insn "*movsicc_insn"
7300 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7302 (match_operator 3 "arm_comparison_operator"
7303 [(match_operand 4 "cc_register" "") (const_int 0)])
7304 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7305 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7312 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7313 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7314 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7315 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7316 [(set_attr "length" "4,4,4,4,8,8,8,8")
7317 (set_attr "conds" "use")]
7320 (define_insn "*movsfcc_soft_insn"
7321 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7322 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7323 [(match_operand 4 "cc_register" "") (const_int 0)])
7324 (match_operand:SF 1 "s_register_operand" "0,r")
7325 (match_operand:SF 2 "s_register_operand" "r,0")))]
7326 "TARGET_ARM && TARGET_SOFT_FLOAT"
7330 [(set_attr "conds" "use")]
7334 ;; Jump and linkage insns
7336 (define_expand "jump"
7338 (label_ref (match_operand 0 "" "")))]
7343 (define_insn "*arm_jump"
7345 (label_ref (match_operand 0 "" "")))]
7349 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7351 arm_ccfsm_state += 2;
7354 return \"b%?\\t%l0\";
7357 [(set_attr "predicable" "yes")]
7360 (define_insn "*thumb_jump"
7362 (label_ref (match_operand 0 "" "")))]
7365 if (get_attr_length (insn) == 2)
7367 return \"bl\\t%l0\\t%@ far jump\";
7369 [(set (attr "far_jump")
7371 (eq_attr "length" "4")
7372 (const_string "yes")
7373 (const_string "no")))
7374 (set (attr "length")
7376 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7377 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7382 (define_expand "call"
7383 [(parallel [(call (match_operand 0 "memory_operand" "")
7384 (match_operand 1 "general_operand" ""))
7385 (use (match_operand 2 "" ""))
7386 (clobber (reg:SI LR_REGNUM))])]
7392 /* In an untyped call, we can get NULL for operand 2. */
7393 if (operands[2] == NULL_RTX)
7394 operands[2] = const0_rtx;
7396 /* This is to decide if we should generate indirect calls by loading the
7397 32 bit address of the callee into a register before performing the
7398 branch and link. operand[2] encodes the long_call/short_call
7399 attribute of the function being called. This attribute is set whenever
7400 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7401 is used, and the short_call attribute can also be set if function is
7402 declared as static or if it has already been defined in the current
7403 compilation unit. See arm.c and arm.h for info about this. The third
7404 parameter to arm_is_longcall_p is used to tell it which pattern
7406 callee = XEXP (operands[0], 0);
7408 if (GET_CODE (callee) != REG
7409 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7410 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7414 (define_insn "*call_reg"
7415 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7416 (match_operand 1 "" ""))
7417 (use (match_operand 2 "" ""))
7418 (clobber (reg:SI LR_REGNUM))]
7421 return output_call (operands);
7423 ;; length is worst case, normally it is only two
7424 [(set_attr "length" "12")
7425 (set_attr "type" "call")]
7428 (define_insn "*call_mem"
7429 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7430 (match_operand 1 "" ""))
7431 (use (match_operand 2 "" ""))
7432 (clobber (reg:SI LR_REGNUM))]
7435 return output_call_mem (operands);
7437 [(set_attr "length" "12")
7438 (set_attr "type" "call")]
7441 (define_insn "*call_indirect"
7442 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7443 (match_operand 1 "" ""))
7444 (use (match_operand 2 "" ""))
7445 (clobber (reg:SI LR_REGNUM))]
7449 if (TARGET_CALLER_INTERWORKING)
7450 return \"bl\\t%__interwork_call_via_%0\";
7452 return \"bl\\t%__call_via_%0\";
7454 [(set_attr "type" "call")]
7457 (define_insn "*call_value_indirect"
7458 [(set (match_operand 0 "" "")
7459 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7460 (match_operand 2 "" "")))
7461 (use (match_operand 3 "" ""))
7462 (clobber (reg:SI LR_REGNUM))]
7466 if (TARGET_CALLER_INTERWORKING)
7467 return \"bl\\t%__interwork_call_via_%1\";
7469 return \"bl\\t%__call_via_%1\";
7471 [(set_attr "type" "call")]
7474 (define_expand "call_value"
7475 [(parallel [(set (match_operand 0 "" "")
7476 (call (match_operand 1 "memory_operand" "")
7477 (match_operand 2 "general_operand" "")))
7478 (use (match_operand 3 "" ""))
7479 (clobber (reg:SI LR_REGNUM))])]
7483 rtx callee = XEXP (operands[1], 0);
7485 /* In an untyped call, we can get NULL for operand 2. */
7486 if (operands[3] == 0)
7487 operands[3] = const0_rtx;
7489 /* See the comment in define_expand \"call\". */
7490 if (GET_CODE (callee) != REG
7491 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7492 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7496 (define_insn "*call_value_reg"
7497 [(set (match_operand 0 "" "")
7498 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7499 (match_operand 2 "" "")))
7500 (use (match_operand 3 "" ""))
7501 (clobber (reg:SI LR_REGNUM))]
7504 return output_call (&operands[1]);
7506 [(set_attr "length" "12")
7507 (set_attr "type" "call")]
7510 (define_insn "*call_value_mem"
7511 [(set (match_operand 0 "" "")
7512 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7513 (match_operand 2 "" "")))
7514 (use (match_operand 3 "" ""))
7515 (clobber (reg:SI LR_REGNUM))]
7516 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7518 return output_call_mem (&operands[1]);
7520 [(set_attr "length" "12")
7521 (set_attr "type" "call")]
7524 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7525 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7527 (define_insn "*call_symbol"
7528 [(call (mem:SI (match_operand:SI 0 "" ""))
7529 (match_operand 1 "" ""))
7530 (use (match_operand 2 "" ""))
7531 (clobber (reg:SI LR_REGNUM))]
7533 && (GET_CODE (operands[0]) == SYMBOL_REF)
7534 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7537 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7539 [(set_attr "type" "call")]
7542 (define_insn "*call_value_symbol"
7543 [(set (match_operand 0 "s_register_operand" "")
7544 (call (mem:SI (match_operand:SI 1 "" ""))
7545 (match_operand:SI 2 "" "")))
7546 (use (match_operand 3 "" ""))
7547 (clobber (reg:SI LR_REGNUM))]
7549 && (GET_CODE (operands[1]) == SYMBOL_REF)
7550 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7553 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7555 [(set_attr "type" "call")]
7558 (define_insn "*call_insn"
7559 [(call (mem:SI (match_operand:SI 0 "" ""))
7560 (match_operand:SI 1 "" ""))
7561 (use (match_operand 2 "" ""))
7562 (clobber (reg:SI LR_REGNUM))]
7564 && GET_CODE (operands[0]) == SYMBOL_REF
7565 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7567 [(set_attr "length" "4")
7568 (set_attr "type" "call")]
7571 (define_insn "*call_value_insn"
7572 [(set (match_operand 0 "register_operand" "")
7573 (call (mem:SI (match_operand 1 "" ""))
7574 (match_operand 2 "" "")))
7575 (use (match_operand 3 "" ""))
7576 (clobber (reg:SI LR_REGNUM))]
7578 && GET_CODE (operands[1]) == SYMBOL_REF
7579 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7581 [(set_attr "length" "4")
7582 (set_attr "type" "call")]
7585 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7586 (define_expand "sibcall"
7587 [(parallel [(call (match_operand 0 "memory_operand" "")
7588 (match_operand 1 "general_operand" ""))
7590 (use (match_operand 2 "" ""))])]
7594 if (operands[2] == NULL_RTX)
7595 operands[2] = const0_rtx;
7599 (define_expand "sibcall_value"
7600 [(parallel [(set (match_operand 0 "register_operand" "")
7601 (call (match_operand 1 "memory_operand" "")
7602 (match_operand 2 "general_operand" "")))
7604 (use (match_operand 3 "" ""))])]
7608 if (operands[3] == NULL_RTX)
7609 operands[3] = const0_rtx;
7613 (define_insn "*sibcall_insn"
7614 [(call (mem:SI (match_operand:SI 0 "" "X"))
7615 (match_operand 1 "" ""))
7617 (use (match_operand 2 "" ""))]
7618 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7620 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7622 [(set_attr "type" "call")]
7625 (define_insn "*sibcall_value_insn"
7626 [(set (match_operand 0 "s_register_operand" "")
7627 (call (mem:SI (match_operand:SI 1 "" "X"))
7628 (match_operand 2 "" "")))
7630 (use (match_operand 3 "" ""))]
7631 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7633 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7635 [(set_attr "type" "call")]
7638 ;; Often the return insn will be the same as loading from memory, so set attr
7639 (define_insn "return"
7641 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7644 if (arm_ccfsm_state == 2)
7646 arm_ccfsm_state += 2;
7649 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7651 [(set_attr "type" "load1")
7652 (set_attr "length" "12")
7653 (set_attr "predicable" "yes")]
7656 (define_insn "*cond_return"
7658 (if_then_else (match_operator 0 "arm_comparison_operator"
7659 [(match_operand 1 "cc_register" "") (const_int 0)])
7662 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7665 if (arm_ccfsm_state == 2)
7667 arm_ccfsm_state += 2;
7670 return output_return_instruction (operands[0], TRUE, FALSE);
7672 [(set_attr "conds" "use")
7673 (set_attr "length" "12")
7674 (set_attr "type" "load1")]
7677 (define_insn "*cond_return_inverted"
7679 (if_then_else (match_operator 0 "arm_comparison_operator"
7680 [(match_operand 1 "cc_register" "") (const_int 0)])
7683 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7686 if (arm_ccfsm_state == 2)
7688 arm_ccfsm_state += 2;
7691 return output_return_instruction (operands[0], TRUE, TRUE);
7693 [(set_attr "conds" "use")
7694 (set_attr "type" "load1")]
7697 ;; Generate a sequence of instructions to determine if the processor is
7698 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7701 (define_expand "return_addr_mask"
7703 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7705 (set (match_operand:SI 0 "s_register_operand" "")
7706 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7708 (const_int 67108860)))] ; 0x03fffffc
7711 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7714 (define_insn "*check_arch2"
7715 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7716 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7719 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7720 [(set_attr "length" "8")
7721 (set_attr "conds" "set")]
7724 ;; Call subroutine returning any type.
7726 (define_expand "untyped_call"
7727 [(parallel [(call (match_operand 0 "" "")
7729 (match_operand 1 "" "")
7730 (match_operand 2 "" "")])]
7736 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7738 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7740 rtx set = XVECEXP (operands[2], 0, i);
7742 emit_move_insn (SET_DEST (set), SET_SRC (set));
7745 /* The optimizer does not know that the call sets the function value
7746 registers we stored in the result block. We avoid problems by
7747 claiming that all hard registers are used and clobbered at this
7749 emit_insn (gen_blockage ());
7755 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7756 ;; all of memory. This blocks insns from being moved across this point.
7758 (define_insn "blockage"
7759 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7762 [(set_attr "length" "0")
7763 (set_attr "type" "block")]
7766 (define_expand "casesi"
7767 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7768 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7769 (match_operand:SI 2 "const_int_operand" "") ; total range
7770 (match_operand:SI 3 "" "") ; table label
7771 (match_operand:SI 4 "" "")] ; Out of range label
7776 if (operands[1] != const0_rtx)
7778 reg = gen_reg_rtx (SImode);
7780 emit_insn (gen_addsi3 (reg, operands[0],
7781 GEN_INT (-INTVAL (operands[1]))));
7785 if (!const_ok_for_arm (INTVAL (operands[2])))
7786 operands[2] = force_reg (SImode, operands[2]);
7788 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
7794 ;; The USE in this pattern is needed to tell flow analysis that this is
7795 ;; a CASESI insn. It has no other purpose.
7796 (define_insn "casesi_internal"
7797 [(parallel [(set (pc)
7799 (leu (match_operand:SI 0 "s_register_operand" "r")
7800 (match_operand:SI 1 "arm_rhs_operand" "rI"))
7801 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
7802 (label_ref (match_operand 2 "" ""))))
7803 (label_ref (match_operand 3 "" ""))))
7804 (clobber (reg:CC CC_REGNUM))
7805 (use (label_ref (match_dup 2)))])]
7809 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
7810 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
7812 [(set_attr "conds" "clob")
7813 (set_attr "length" "12")]
7816 (define_expand "indirect_jump"
7818 (match_operand:SI 0 "s_register_operand" ""))]
7823 (define_insn "*arm_indirect_jump"
7825 (match_operand:SI 0 "s_register_operand" "r"))]
7827 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
7828 [(set_attr "predicable" "yes")]
7831 ;; Although not supported by the define_expand above,
7832 ;; cse/combine may generate this form.
7833 (define_insn "*load_indirect_jump"
7835 (match_operand:SI 0 "memory_operand" "m"))]
7837 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
7838 [(set_attr "type" "load1")
7839 (set_attr "pool_range" "4096")
7840 (set_attr "neg_pool_range" "4084")
7841 (set_attr "predicable" "yes")]
7844 (define_insn "*thumb_indirect_jump"
7846 (match_operand:SI 0 "register_operand" "l*r"))]
7849 [(set_attr "conds" "clob")
7850 (set_attr "length" "2")]
7861 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
7862 return \"mov\\tr8, r8\";
7864 [(set (attr "length")
7865 (if_then_else (eq_attr "is_thumb" "yes")
7871 ;; Patterns to allow combination of arithmetic, cond code and shifts
7873 (define_insn "*arith_shiftsi"
7874 [(set (match_operand:SI 0 "s_register_operand" "=r")
7875 (match_operator:SI 1 "shiftable_operator"
7876 [(match_operator:SI 3 "shift_operator"
7877 [(match_operand:SI 4 "s_register_operand" "r")
7878 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7879 (match_operand:SI 2 "s_register_operand" "r")]))]
7881 "%i1%?\\t%0, %2, %4%S3"
7882 [(set_attr "predicable" "yes")
7883 (set_attr "shift" "4")
7884 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7885 (const_string "alu_shift")
7886 (const_string "alu_shift_reg")))]
7890 [(set (match_operand:SI 0 "s_register_operand" "")
7891 (match_operator:SI 1 "shiftable_operator"
7892 [(match_operator:SI 2 "shiftable_operator"
7893 [(match_operator:SI 3 "shift_operator"
7894 [(match_operand:SI 4 "s_register_operand" "")
7895 (match_operand:SI 5 "reg_or_int_operand" "")])
7896 (match_operand:SI 6 "s_register_operand" "")])
7897 (match_operand:SI 7 "arm_rhs_operand" "")]))
7898 (clobber (match_operand:SI 8 "s_register_operand" ""))]
7901 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7904 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
7907 (define_insn "*arith_shiftsi_compare0"
7908 [(set (reg:CC_NOOV CC_REGNUM)
7909 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7910 [(match_operator:SI 3 "shift_operator"
7911 [(match_operand:SI 4 "s_register_operand" "r")
7912 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7913 (match_operand:SI 2 "s_register_operand" "r")])
7915 (set (match_operand:SI 0 "s_register_operand" "=r")
7916 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7919 "%i1%?s\\t%0, %2, %4%S3"
7920 [(set_attr "conds" "set")
7921 (set_attr "shift" "4")
7922 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7923 (const_string "alu_shift")
7924 (const_string "alu_shift_reg")))]
7927 (define_insn "*arith_shiftsi_compare0_scratch"
7928 [(set (reg:CC_NOOV CC_REGNUM)
7929 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7930 [(match_operator:SI 3 "shift_operator"
7931 [(match_operand:SI 4 "s_register_operand" "r")
7932 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7933 (match_operand:SI 2 "s_register_operand" "r")])
7935 (clobber (match_scratch:SI 0 "=r"))]
7937 "%i1%?s\\t%0, %2, %4%S3"
7938 [(set_attr "conds" "set")
7939 (set_attr "shift" "4")
7940 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7941 (const_string "alu_shift")
7942 (const_string "alu_shift_reg")))]
7945 (define_insn "*sub_shiftsi"
7946 [(set (match_operand:SI 0 "s_register_operand" "=r")
7947 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7948 (match_operator:SI 2 "shift_operator"
7949 [(match_operand:SI 3 "s_register_operand" "r")
7950 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
7952 "sub%?\\t%0, %1, %3%S2"
7953 [(set_attr "predicable" "yes")
7954 (set_attr "shift" "3")
7955 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7956 (const_string "alu_shift")
7957 (const_string "alu_shift_reg")))]
7960 (define_insn "*sub_shiftsi_compare0"
7961 [(set (reg:CC_NOOV CC_REGNUM)
7963 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7964 (match_operator:SI 2 "shift_operator"
7965 [(match_operand:SI 3 "s_register_operand" "r")
7966 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7968 (set (match_operand:SI 0 "s_register_operand" "=r")
7969 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
7972 "sub%?s\\t%0, %1, %3%S2"
7973 [(set_attr "conds" "set")
7974 (set_attr "shift" "3")
7975 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7976 (const_string "alu_shift")
7977 (const_string "alu_shift_reg")))]
7980 (define_insn "*sub_shiftsi_compare0_scratch"
7981 [(set (reg:CC_NOOV CC_REGNUM)
7983 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7984 (match_operator:SI 2 "shift_operator"
7985 [(match_operand:SI 3 "s_register_operand" "r")
7986 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7988 (clobber (match_scratch:SI 0 "=r"))]
7990 "sub%?s\\t%0, %1, %3%S2"
7991 [(set_attr "conds" "set")
7992 (set_attr "shift" "3")
7993 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7994 (const_string "alu_shift")
7995 (const_string "alu_shift_reg")))]
8000 (define_insn "*and_scc"
8001 [(set (match_operand:SI 0 "s_register_operand" "=r")
8002 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8003 [(match_operand 3 "cc_register" "") (const_int 0)])
8004 (match_operand:SI 2 "s_register_operand" "r")))]
8006 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8007 [(set_attr "conds" "use")
8008 (set_attr "length" "8")]
8011 (define_insn "*ior_scc"
8012 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8013 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8014 [(match_operand 3 "cc_register" "") (const_int 0)])
8015 (match_operand:SI 1 "s_register_operand" "0,?r")))]
8019 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8020 [(set_attr "conds" "use")
8021 (set_attr "length" "4,8")]
8024 (define_insn "*compare_scc"
8025 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8026 (match_operator:SI 1 "arm_comparison_operator"
8027 [(match_operand:SI 2 "s_register_operand" "r,r")
8028 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8029 (clobber (reg:CC CC_REGNUM))]
8032 if (operands[3] == const0_rtx)
8034 if (GET_CODE (operands[1]) == LT)
8035 return \"mov\\t%0, %2, lsr #31\";
8037 if (GET_CODE (operands[1]) == GE)
8038 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8040 if (GET_CODE (operands[1]) == EQ)
8041 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8044 if (GET_CODE (operands[1]) == NE)
8046 if (which_alternative == 1)
8047 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8048 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8050 if (which_alternative == 1)
8051 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8053 output_asm_insn (\"cmp\\t%2, %3\", operands);
8054 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8056 [(set_attr "conds" "clob")
8057 (set_attr "length" "12")]
8060 (define_insn "*cond_move"
8061 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8062 (if_then_else:SI (match_operator 3 "equality_operator"
8063 [(match_operator 4 "arm_comparison_operator"
8064 [(match_operand 5 "cc_register" "") (const_int 0)])
8066 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8067 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8070 if (GET_CODE (operands[3]) == NE)
8072 if (which_alternative != 1)
8073 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8074 if (which_alternative != 0)
8075 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8078 if (which_alternative != 0)
8079 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8080 if (which_alternative != 1)
8081 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8084 [(set_attr "conds" "use")
8085 (set_attr "length" "4,4,8")]
8088 (define_insn "*cond_arith"
8089 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8090 (match_operator:SI 5 "shiftable_operator"
8091 [(match_operator:SI 4 "arm_comparison_operator"
8092 [(match_operand:SI 2 "s_register_operand" "r,r")
8093 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8094 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8095 (clobber (reg:CC CC_REGNUM))]
8098 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8099 return \"%i5\\t%0, %1, %2, lsr #31\";
8101 output_asm_insn (\"cmp\\t%2, %3\", operands);
8102 if (GET_CODE (operands[5]) == AND)
8103 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8104 else if (GET_CODE (operands[5]) == MINUS)
8105 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8106 else if (which_alternative != 0)
8107 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8108 return \"%i5%d4\\t%0, %1, #1\";
8110 [(set_attr "conds" "clob")
8111 (set_attr "length" "12")]
8114 (define_insn "*cond_sub"
8115 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8116 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8117 (match_operator:SI 4 "arm_comparison_operator"
8118 [(match_operand:SI 2 "s_register_operand" "r,r")
8119 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8120 (clobber (reg:CC CC_REGNUM))]
8123 output_asm_insn (\"cmp\\t%2, %3\", operands);
8124 if (which_alternative != 0)
8125 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8126 return \"sub%d4\\t%0, %1, #1\";
8128 [(set_attr "conds" "clob")
8129 (set_attr "length" "8,12")]
8132 (define_insn "*cmp_ite0"
8133 [(set (match_operand 6 "dominant_cc_register" "")
8136 (match_operator 4 "arm_comparison_operator"
8137 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8138 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8139 (match_operator:SI 5 "arm_comparison_operator"
8140 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8141 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8147 static const char * const opcodes[4][2] =
8149 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8150 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8151 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8152 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8153 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8154 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8155 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8156 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8159 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8161 return opcodes[which_alternative][swap];
8163 [(set_attr "conds" "set")
8164 (set_attr "length" "8")]
8167 (define_insn "*cmp_ite1"
8168 [(set (match_operand 6 "dominant_cc_register" "")
8171 (match_operator 4 "arm_comparison_operator"
8172 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8173 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8174 (match_operator:SI 5 "arm_comparison_operator"
8175 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8176 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8182 static const char * const opcodes[4][2] =
8184 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8185 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8186 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8187 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8188 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8189 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8190 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8191 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8194 comparison_dominates_p (GET_CODE (operands[5]),
8195 reverse_condition (GET_CODE (operands[4])));
8197 return opcodes[which_alternative][swap];
8199 [(set_attr "conds" "set")
8200 (set_attr "length" "8")]
8203 (define_insn "*cmp_and"
8204 [(set (match_operand 6 "dominant_cc_register" "")
8207 (match_operator 4 "arm_comparison_operator"
8208 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8209 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8210 (match_operator:SI 5 "arm_comparison_operator"
8211 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8212 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8217 static const char *const opcodes[4][2] =
8219 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8220 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8221 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8222 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8223 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8224 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8225 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8226 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8229 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8231 return opcodes[which_alternative][swap];
8233 [(set_attr "conds" "set")
8234 (set_attr "predicable" "no")
8235 (set_attr "length" "8")]
8238 (define_insn "*cmp_ior"
8239 [(set (match_operand 6 "dominant_cc_register" "")
8242 (match_operator 4 "arm_comparison_operator"
8243 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8244 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8245 (match_operator:SI 5 "arm_comparison_operator"
8246 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8247 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8252 static const char *const opcodes[4][2] =
8254 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8255 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8256 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8257 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8258 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8259 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8260 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8261 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8264 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8266 return opcodes[which_alternative][swap];
8269 [(set_attr "conds" "set")
8270 (set_attr "length" "8")]
8273 (define_insn_and_split "*ior_scc_scc"
8274 [(set (match_operand:SI 0 "s_register_operand" "=r")
8275 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8276 [(match_operand:SI 1 "s_register_operand" "r")
8277 (match_operand:SI 2 "arm_add_operand" "rIL")])
8278 (match_operator:SI 6 "arm_comparison_operator"
8279 [(match_operand:SI 4 "s_register_operand" "r")
8280 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8281 (clobber (reg:CC CC_REGNUM))]
8283 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8286 "TARGET_ARM && reload_completed"
8290 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8291 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8293 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8295 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8298 [(set_attr "conds" "clob")
8299 (set_attr "length" "16")])
8301 ; If the above pattern is followed by a CMP insn, then the compare is
8302 ; redundant, since we can rework the conditional instruction that follows.
8303 (define_insn_and_split "*ior_scc_scc_cmp"
8304 [(set (match_operand 0 "dominant_cc_register" "")
8305 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8306 [(match_operand:SI 1 "s_register_operand" "r")
8307 (match_operand:SI 2 "arm_add_operand" "rIL")])
8308 (match_operator:SI 6 "arm_comparison_operator"
8309 [(match_operand:SI 4 "s_register_operand" "r")
8310 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8312 (set (match_operand:SI 7 "s_register_operand" "=r")
8313 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8314 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8317 "TARGET_ARM && reload_completed"
8321 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8322 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8324 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8326 [(set_attr "conds" "set")
8327 (set_attr "length" "16")])
8329 (define_insn_and_split "*and_scc_scc"
8330 [(set (match_operand:SI 0 "s_register_operand" "=r")
8331 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8332 [(match_operand:SI 1 "s_register_operand" "r")
8333 (match_operand:SI 2 "arm_add_operand" "rIL")])
8334 (match_operator:SI 6 "arm_comparison_operator"
8335 [(match_operand:SI 4 "s_register_operand" "r")
8336 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8337 (clobber (reg:CC CC_REGNUM))]
8339 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8342 "TARGET_ARM && reload_completed
8343 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8348 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8349 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8351 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8353 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8356 [(set_attr "conds" "clob")
8357 (set_attr "length" "16")])
8359 ; If the above pattern is followed by a CMP insn, then the compare is
8360 ; redundant, since we can rework the conditional instruction that follows.
8361 (define_insn_and_split "*and_scc_scc_cmp"
8362 [(set (match_operand 0 "dominant_cc_register" "")
8363 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8364 [(match_operand:SI 1 "s_register_operand" "r")
8365 (match_operand:SI 2 "arm_add_operand" "rIL")])
8366 (match_operator:SI 6 "arm_comparison_operator"
8367 [(match_operand:SI 4 "s_register_operand" "r")
8368 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8370 (set (match_operand:SI 7 "s_register_operand" "=r")
8371 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8372 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8375 "TARGET_ARM && reload_completed"
8379 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8380 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8382 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8384 [(set_attr "conds" "set")
8385 (set_attr "length" "16")])
8387 ;; If there is no dominance in the comparison, then we can still save an
8388 ;; instruction in the AND case, since we can know that the second compare
8389 ;; need only zero the value if false (if true, then the value is already
8391 (define_insn_and_split "*and_scc_scc_nodom"
8392 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8393 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8394 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8395 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8396 (match_operator:SI 6 "arm_comparison_operator"
8397 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8398 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8399 (clobber (reg:CC CC_REGNUM))]
8401 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8404 "TARGET_ARM && reload_completed"
8405 [(parallel [(set (match_dup 0)
8406 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8407 (clobber (reg:CC CC_REGNUM))])
8408 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8410 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8413 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8414 operands[4], operands[5]),
8416 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8418 [(set_attr "conds" "clob")
8419 (set_attr "length" "20")])
8422 [(set (reg:CC_NOOV CC_REGNUM)
8423 (compare:CC_NOOV (ior:SI
8424 (and:SI (match_operand:SI 0 "s_register_operand" "")
8426 (match_operator:SI 1 "comparison_operator"
8427 [(match_operand:SI 2 "s_register_operand" "")
8428 (match_operand:SI 3 "arm_add_operand" "")]))
8430 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8433 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8435 (set (reg:CC_NOOV CC_REGNUM)
8436 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8441 [(set (reg:CC_NOOV CC_REGNUM)
8442 (compare:CC_NOOV (ior:SI
8443 (match_operator:SI 1 "comparison_operator"
8444 [(match_operand:SI 2 "s_register_operand" "")
8445 (match_operand:SI 3 "arm_add_operand" "")])
8446 (and:SI (match_operand:SI 0 "s_register_operand" "")
8449 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8452 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8454 (set (reg:CC_NOOV CC_REGNUM)
8455 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8459 (define_insn "*negscc"
8460 [(set (match_operand:SI 0 "s_register_operand" "=r")
8461 (neg:SI (match_operator 3 "arm_comparison_operator"
8462 [(match_operand:SI 1 "s_register_operand" "r")
8463 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8464 (clobber (reg:CC CC_REGNUM))]
8467 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8468 return \"mov\\t%0, %1, asr #31\";
8470 if (GET_CODE (operands[3]) == NE)
8471 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8473 if (GET_CODE (operands[3]) == GT)
8474 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8476 output_asm_insn (\"cmp\\t%1, %2\", operands);
8477 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8478 return \"mvn%d3\\t%0, #0\";
8480 [(set_attr "conds" "clob")
8481 (set_attr "length" "12")]
8484 (define_insn "movcond"
8485 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8487 (match_operator 5 "arm_comparison_operator"
8488 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8489 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8490 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8491 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8492 (clobber (reg:CC CC_REGNUM))]
8495 if (GET_CODE (operands[5]) == LT
8496 && (operands[4] == const0_rtx))
8498 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8500 if (operands[2] == const0_rtx)
8501 return \"and\\t%0, %1, %3, asr #31\";
8502 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8504 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8506 if (operands[1] == const0_rtx)
8507 return \"bic\\t%0, %2, %3, asr #31\";
8508 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8510 /* The only case that falls through to here is when both ops 1 & 2
8514 if (GET_CODE (operands[5]) == GE
8515 && (operands[4] == const0_rtx))
8517 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8519 if (operands[2] == const0_rtx)
8520 return \"bic\\t%0, %1, %3, asr #31\";
8521 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8523 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8525 if (operands[1] == const0_rtx)
8526 return \"and\\t%0, %2, %3, asr #31\";
8527 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8529 /* The only case that falls through to here is when both ops 1 & 2
8532 if (GET_CODE (operands[4]) == CONST_INT
8533 && !const_ok_for_arm (INTVAL (operands[4])))
8534 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8536 output_asm_insn (\"cmp\\t%3, %4\", operands);
8537 if (which_alternative != 0)
8538 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8539 if (which_alternative != 1)
8540 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8543 [(set_attr "conds" "clob")
8544 (set_attr "length" "8,8,12")]
8547 (define_insn "*ifcompare_plus_move"
8548 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8549 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8550 [(match_operand:SI 4 "s_register_operand" "r,r")
8551 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8553 (match_operand:SI 2 "s_register_operand" "r,r")
8554 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8555 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8556 (clobber (reg:CC CC_REGNUM))]
8559 [(set_attr "conds" "clob")
8560 (set_attr "length" "8,12")]
8563 (define_insn "*if_plus_move"
8564 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8566 (match_operator 4 "arm_comparison_operator"
8567 [(match_operand 5 "cc_register" "") (const_int 0)])
8569 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8570 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8571 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8575 sub%d4\\t%0, %2, #%n3
8576 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8577 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8578 [(set_attr "conds" "use")
8579 (set_attr "length" "4,4,8,8")
8580 (set_attr "type" "*,*,*,*")]
8583 (define_insn "*ifcompare_move_plus"
8584 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8585 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8586 [(match_operand:SI 4 "s_register_operand" "r,r")
8587 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8588 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8590 (match_operand:SI 2 "s_register_operand" "r,r")
8591 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8592 (clobber (reg:CC CC_REGNUM))]
8595 [(set_attr "conds" "clob")
8596 (set_attr "length" "8,12")]
8599 (define_insn "*if_move_plus"
8600 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8602 (match_operator 4 "arm_comparison_operator"
8603 [(match_operand 5 "cc_register" "") (const_int 0)])
8604 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8606 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8607 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8611 sub%D4\\t%0, %2, #%n3
8612 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8613 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8614 [(set_attr "conds" "use")
8615 (set_attr "length" "4,4,8,8")
8616 (set_attr "type" "*,*,*,*")]
8619 (define_insn "*ifcompare_arith_arith"
8620 [(set (match_operand:SI 0 "s_register_operand" "=r")
8621 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8622 [(match_operand:SI 5 "s_register_operand" "r")
8623 (match_operand:SI 6 "arm_add_operand" "rIL")])
8624 (match_operator:SI 8 "shiftable_operator"
8625 [(match_operand:SI 1 "s_register_operand" "r")
8626 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8627 (match_operator:SI 7 "shiftable_operator"
8628 [(match_operand:SI 3 "s_register_operand" "r")
8629 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8630 (clobber (reg:CC CC_REGNUM))]
8633 [(set_attr "conds" "clob")
8634 (set_attr "length" "12")]
8637 (define_insn "*if_arith_arith"
8638 [(set (match_operand:SI 0 "s_register_operand" "=r")
8639 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8640 [(match_operand 8 "cc_register" "") (const_int 0)])
8641 (match_operator:SI 6 "shiftable_operator"
8642 [(match_operand:SI 1 "s_register_operand" "r")
8643 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8644 (match_operator:SI 7 "shiftable_operator"
8645 [(match_operand:SI 3 "s_register_operand" "r")
8646 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8648 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8649 [(set_attr "conds" "use")
8650 (set_attr "length" "8")]
8653 (define_insn "*ifcompare_arith_move"
8654 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8655 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8656 [(match_operand:SI 2 "s_register_operand" "r,r")
8657 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8658 (match_operator:SI 7 "shiftable_operator"
8659 [(match_operand:SI 4 "s_register_operand" "r,r")
8660 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8661 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8662 (clobber (reg:CC CC_REGNUM))]
8665 /* If we have an operation where (op x 0) is the identity operation and
8666 the conditional operator is LT or GE and we are comparing against zero and
8667 everything is in registers then we can do this in two instructions. */
8668 if (operands[3] == const0_rtx
8669 && GET_CODE (operands[7]) != AND
8670 && GET_CODE (operands[5]) == REG
8671 && GET_CODE (operands[1]) == REG
8672 && REGNO (operands[1]) == REGNO (operands[4])
8673 && REGNO (operands[4]) != REGNO (operands[0]))
8675 if (GET_CODE (operands[6]) == LT)
8676 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8677 else if (GET_CODE (operands[6]) == GE)
8678 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8680 if (GET_CODE (operands[3]) == CONST_INT
8681 && !const_ok_for_arm (INTVAL (operands[3])))
8682 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8684 output_asm_insn (\"cmp\\t%2, %3\", operands);
8685 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8686 if (which_alternative != 0)
8687 return \"mov%D6\\t%0, %1\";
8690 [(set_attr "conds" "clob")
8691 (set_attr "length" "8,12")]
8694 (define_insn "*if_arith_move"
8695 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8696 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8697 [(match_operand 6 "cc_register" "") (const_int 0)])
8698 (match_operator:SI 5 "shiftable_operator"
8699 [(match_operand:SI 2 "s_register_operand" "r,r")
8700 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8701 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8705 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8706 [(set_attr "conds" "use")
8707 (set_attr "length" "4,8")
8708 (set_attr "type" "*,*")]
8711 (define_insn "*ifcompare_move_arith"
8712 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8713 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8714 [(match_operand:SI 4 "s_register_operand" "r,r")
8715 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8716 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8717 (match_operator:SI 7 "shiftable_operator"
8718 [(match_operand:SI 2 "s_register_operand" "r,r")
8719 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8720 (clobber (reg:CC CC_REGNUM))]
8723 /* If we have an operation where (op x 0) is the identity operation and
8724 the conditional operator is LT or GE and we are comparing against zero and
8725 everything is in registers then we can do this in two instructions */
8726 if (operands[5] == const0_rtx
8727 && GET_CODE (operands[7]) != AND
8728 && GET_CODE (operands[3]) == REG
8729 && GET_CODE (operands[1]) == REG
8730 && REGNO (operands[1]) == REGNO (operands[2])
8731 && REGNO (operands[2]) != REGNO (operands[0]))
8733 if (GET_CODE (operands[6]) == GE)
8734 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8735 else if (GET_CODE (operands[6]) == LT)
8736 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8739 if (GET_CODE (operands[5]) == CONST_INT
8740 && !const_ok_for_arm (INTVAL (operands[5])))
8741 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8743 output_asm_insn (\"cmp\\t%4, %5\", operands);
8745 if (which_alternative != 0)
8746 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8747 return \"%I7%D6\\t%0, %2, %3\";
8749 [(set_attr "conds" "clob")
8750 (set_attr "length" "8,12")]
8753 (define_insn "*if_move_arith"
8754 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8756 (match_operator 4 "arm_comparison_operator"
8757 [(match_operand 6 "cc_register" "") (const_int 0)])
8758 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8759 (match_operator:SI 5 "shiftable_operator"
8760 [(match_operand:SI 2 "s_register_operand" "r,r")
8761 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8765 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8766 [(set_attr "conds" "use")
8767 (set_attr "length" "4,8")
8768 (set_attr "type" "*,*")]
8771 (define_insn "*ifcompare_move_not"
8772 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8774 (match_operator 5 "arm_comparison_operator"
8775 [(match_operand:SI 3 "s_register_operand" "r,r")
8776 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8777 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8779 (match_operand:SI 2 "s_register_operand" "r,r"))))
8780 (clobber (reg:CC CC_REGNUM))]
8783 [(set_attr "conds" "clob")
8784 (set_attr "length" "8,12")]
8787 (define_insn "*if_move_not"
8788 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8790 (match_operator 4 "arm_comparison_operator"
8791 [(match_operand 3 "cc_register" "") (const_int 0)])
8792 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8793 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
8797 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
8798 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8799 [(set_attr "conds" "use")
8800 (set_attr "length" "4,8,8")]
8803 (define_insn "*ifcompare_not_move"
8804 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8806 (match_operator 5 "arm_comparison_operator"
8807 [(match_operand:SI 3 "s_register_operand" "r,r")
8808 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8810 (match_operand:SI 2 "s_register_operand" "r,r"))
8811 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8812 (clobber (reg:CC CC_REGNUM))]
8815 [(set_attr "conds" "clob")
8816 (set_attr "length" "8,12")]
8819 (define_insn "*if_not_move"
8820 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8822 (match_operator 4 "arm_comparison_operator"
8823 [(match_operand 3 "cc_register" "") (const_int 0)])
8824 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
8825 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8829 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
8830 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8831 [(set_attr "conds" "use")
8832 (set_attr "length" "4,8,8")]
8835 (define_insn "*ifcompare_shift_move"
8836 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8838 (match_operator 6 "arm_comparison_operator"
8839 [(match_operand:SI 4 "s_register_operand" "r,r")
8840 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8841 (match_operator:SI 7 "shift_operator"
8842 [(match_operand:SI 2 "s_register_operand" "r,r")
8843 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
8844 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8845 (clobber (reg:CC CC_REGNUM))]
8848 [(set_attr "conds" "clob")
8849 (set_attr "length" "8,12")]
8852 (define_insn "*if_shift_move"
8853 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8855 (match_operator 5 "arm_comparison_operator"
8856 [(match_operand 6 "cc_register" "") (const_int 0)])
8857 (match_operator:SI 4 "shift_operator"
8858 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8859 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
8860 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8864 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
8865 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8866 [(set_attr "conds" "use")
8867 (set_attr "shift" "2")
8868 (set_attr "length" "4,8,8")
8869 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8870 (const_string "alu_shift")
8871 (const_string "alu_shift_reg")))]
8874 (define_insn "*ifcompare_move_shift"
8875 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8877 (match_operator 6 "arm_comparison_operator"
8878 [(match_operand:SI 4 "s_register_operand" "r,r")
8879 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8880 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8881 (match_operator:SI 7 "shift_operator"
8882 [(match_operand:SI 2 "s_register_operand" "r,r")
8883 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
8884 (clobber (reg:CC CC_REGNUM))]
8887 [(set_attr "conds" "clob")
8888 (set_attr "length" "8,12")]
8891 (define_insn "*if_move_shift"
8892 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8894 (match_operator 5 "arm_comparison_operator"
8895 [(match_operand 6 "cc_register" "") (const_int 0)])
8896 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8897 (match_operator:SI 4 "shift_operator"
8898 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8899 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
8903 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
8904 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8905 [(set_attr "conds" "use")
8906 (set_attr "shift" "2")
8907 (set_attr "length" "4,8,8")
8908 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8909 (const_string "alu_shift")
8910 (const_string "alu_shift_reg")))]
8913 (define_insn "*ifcompare_shift_shift"
8914 [(set (match_operand:SI 0 "s_register_operand" "=r")
8916 (match_operator 7 "arm_comparison_operator"
8917 [(match_operand:SI 5 "s_register_operand" "r")
8918 (match_operand:SI 6 "arm_add_operand" "rIL")])
8919 (match_operator:SI 8 "shift_operator"
8920 [(match_operand:SI 1 "s_register_operand" "r")
8921 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8922 (match_operator:SI 9 "shift_operator"
8923 [(match_operand:SI 3 "s_register_operand" "r")
8924 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
8925 (clobber (reg:CC CC_REGNUM))]
8928 [(set_attr "conds" "clob")
8929 (set_attr "length" "12")]
8932 (define_insn "*if_shift_shift"
8933 [(set (match_operand:SI 0 "s_register_operand" "=r")
8935 (match_operator 5 "arm_comparison_operator"
8936 [(match_operand 8 "cc_register" "") (const_int 0)])
8937 (match_operator:SI 6 "shift_operator"
8938 [(match_operand:SI 1 "s_register_operand" "r")
8939 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8940 (match_operator:SI 7 "shift_operator"
8941 [(match_operand:SI 3 "s_register_operand" "r")
8942 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
8944 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8945 [(set_attr "conds" "use")
8946 (set_attr "shift" "1")
8947 (set_attr "length" "8")
8948 (set (attr "type") (if_then_else
8949 (and (match_operand 2 "const_int_operand" "")
8950 (match_operand 4 "const_int_operand" ""))
8951 (const_string "alu_shift")
8952 (const_string "alu_shift_reg")))]
8955 (define_insn "*ifcompare_not_arith"
8956 [(set (match_operand:SI 0 "s_register_operand" "=r")
8958 (match_operator 6 "arm_comparison_operator"
8959 [(match_operand:SI 4 "s_register_operand" "r")
8960 (match_operand:SI 5 "arm_add_operand" "rIL")])
8961 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8962 (match_operator:SI 7 "shiftable_operator"
8963 [(match_operand:SI 2 "s_register_operand" "r")
8964 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
8965 (clobber (reg:CC CC_REGNUM))]
8968 [(set_attr "conds" "clob")
8969 (set_attr "length" "12")]
8972 (define_insn "*if_not_arith"
8973 [(set (match_operand:SI 0 "s_register_operand" "=r")
8975 (match_operator 5 "arm_comparison_operator"
8976 [(match_operand 4 "cc_register" "") (const_int 0)])
8977 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8978 (match_operator:SI 6 "shiftable_operator"
8979 [(match_operand:SI 2 "s_register_operand" "r")
8980 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
8982 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8983 [(set_attr "conds" "use")
8984 (set_attr "length" "8")]
8987 (define_insn "*ifcompare_arith_not"
8988 [(set (match_operand:SI 0 "s_register_operand" "=r")
8990 (match_operator 6 "arm_comparison_operator"
8991 [(match_operand:SI 4 "s_register_operand" "r")
8992 (match_operand:SI 5 "arm_add_operand" "rIL")])
8993 (match_operator:SI 7 "shiftable_operator"
8994 [(match_operand:SI 2 "s_register_operand" "r")
8995 (match_operand:SI 3 "arm_rhs_operand" "rI")])
8996 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
8997 (clobber (reg:CC CC_REGNUM))]
9000 [(set_attr "conds" "clob")
9001 (set_attr "length" "12")]
9004 (define_insn "*if_arith_not"
9005 [(set (match_operand:SI 0 "s_register_operand" "=r")
9007 (match_operator 5 "arm_comparison_operator"
9008 [(match_operand 4 "cc_register" "") (const_int 0)])
9009 (match_operator:SI 6 "shiftable_operator"
9010 [(match_operand:SI 2 "s_register_operand" "r")
9011 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9012 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9014 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9015 [(set_attr "conds" "use")
9016 (set_attr "length" "8")]
9019 (define_insn "*ifcompare_neg_move"
9020 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9022 (match_operator 5 "arm_comparison_operator"
9023 [(match_operand:SI 3 "s_register_operand" "r,r")
9024 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9025 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9026 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9027 (clobber (reg:CC CC_REGNUM))]
9030 [(set_attr "conds" "clob")
9031 (set_attr "length" "8,12")]
9034 (define_insn "*if_neg_move"
9035 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9037 (match_operator 4 "arm_comparison_operator"
9038 [(match_operand 3 "cc_register" "") (const_int 0)])
9039 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9040 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9044 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9045 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9046 [(set_attr "conds" "use")
9047 (set_attr "length" "4,8,8")]
9050 (define_insn "*ifcompare_move_neg"
9051 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9053 (match_operator 5 "arm_comparison_operator"
9054 [(match_operand:SI 3 "s_register_operand" "r,r")
9055 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9056 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9057 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9058 (clobber (reg:CC CC_REGNUM))]
9061 [(set_attr "conds" "clob")
9062 (set_attr "length" "8,12")]
9065 (define_insn "*if_move_neg"
9066 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9068 (match_operator 4 "arm_comparison_operator"
9069 [(match_operand 3 "cc_register" "") (const_int 0)])
9070 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9071 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9075 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9076 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9077 [(set_attr "conds" "use")
9078 (set_attr "length" "4,8,8")]
9081 (define_insn "*arith_adjacentmem"
9082 [(set (match_operand:SI 0 "s_register_operand" "=r")
9083 (match_operator:SI 1 "shiftable_operator"
9084 [(match_operand:SI 2 "memory_operand" "m")
9085 (match_operand:SI 3 "memory_operand" "m")]))
9086 (clobber (match_scratch:SI 4 "=r"))]
9087 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9092 int val1 = 0, val2 = 0;
9094 if (REGNO (operands[0]) > REGNO (operands[4]))
9096 ldm[1] = operands[4];
9097 ldm[2] = operands[0];
9101 ldm[1] = operands[0];
9102 ldm[2] = operands[4];
9104 if (GET_CODE (XEXP (operands[2], 0)) != REG)
9105 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
9106 if (GET_CODE (XEXP (operands[3], 0)) != REG)
9107 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9108 arith[0] = operands[0];
9109 arith[3] = operands[1];
9123 ldm[0] = ops[0] = operands[4];
9124 ops[1] = XEXP (XEXP (operands[2], 0), 0);
9125 ops[2] = XEXP (XEXP (operands[2], 0), 1);
9126 output_add_immediate (ops);
9128 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9130 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9134 ldm[0] = XEXP (operands[3], 0);
9136 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9138 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9142 ldm[0] = XEXP (operands[2], 0);
9144 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9146 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9148 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9151 [(set_attr "length" "12")
9152 (set_attr "predicable" "yes")
9153 (set_attr "type" "load1")]
9156 ;; the arm can support extended pre-inc instructions
9158 ;; In all these cases, we use operands 0 and 1 for the register being
9159 ;; incremented because those are the operands that local-alloc will
9160 ;; tie and these are the pair most likely to be tieable (and the ones
9161 ;; that will benefit the most).
9163 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9164 ;; elimination will cause too many headaches.
9166 (define_insn "*strqi_preinc"
9167 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9168 (match_operand:SI 2 "index_operand" "rJ")))
9169 (match_operand:QI 3 "s_register_operand" "r"))
9170 (set (match_operand:SI 0 "s_register_operand" "=r")
9171 (plus:SI (match_dup 1) (match_dup 2)))]
9173 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9174 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9175 && (GET_CODE (operands[2]) != REG
9176 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9177 "str%?b\\t%3, [%0, %2]!"
9178 [(set_attr "type" "store1")
9179 (set_attr "predicable" "yes")]
9182 (define_insn "*strqi_predec"
9183 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9184 (match_operand:SI 2 "s_register_operand" "r")))
9185 (match_operand:QI 3 "s_register_operand" "r"))
9186 (set (match_operand:SI 0 "s_register_operand" "=r")
9187 (minus:SI (match_dup 1) (match_dup 2)))]
9189 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9190 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9191 && (GET_CODE (operands[2]) != REG
9192 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9193 "str%?b\\t%3, [%0, -%2]!"
9194 [(set_attr "type" "store1")
9195 (set_attr "predicable" "yes")]
9198 (define_insn "*loadqi_preinc"
9199 [(set (match_operand:QI 3 "s_register_operand" "=r")
9200 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9201 (match_operand:SI 2 "index_operand" "rJ"))))
9202 (set (match_operand:SI 0 "s_register_operand" "=r")
9203 (plus:SI (match_dup 1) (match_dup 2)))]
9205 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9206 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9207 && (GET_CODE (operands[2]) != REG
9208 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9209 "ldr%?b\\t%3, [%0, %2]!"
9210 [(set_attr "type" "load_byte")
9211 (set_attr "predicable" "yes")]
9214 (define_insn "*loadqi_predec"
9215 [(set (match_operand:QI 3 "s_register_operand" "=r")
9216 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9217 (match_operand:SI 2 "s_register_operand" "r"))))
9218 (set (match_operand:SI 0 "s_register_operand" "=r")
9219 (minus:SI (match_dup 1) (match_dup 2)))]
9221 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9222 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9223 && (GET_CODE (operands[2]) != REG
9224 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9225 "ldr%?b\\t%3, [%0, -%2]!"
9226 [(set_attr "type" "load_byte")
9227 (set_attr "predicable" "yes")]
9230 (define_insn "*loadqisi_preinc"
9231 [(set (match_operand:SI 3 "s_register_operand" "=r")
9233 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9234 (match_operand:SI 2 "index_operand" "rJ")))))
9235 (set (match_operand:SI 0 "s_register_operand" "=r")
9236 (plus:SI (match_dup 1) (match_dup 2)))]
9238 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9239 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9240 && (GET_CODE (operands[2]) != REG
9241 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9242 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9243 [(set_attr "type" "load_byte")
9244 (set_attr "predicable" "yes")]
9247 (define_insn "*loadqisi_predec"
9248 [(set (match_operand:SI 3 "s_register_operand" "=r")
9250 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9251 (match_operand:SI 2 "s_register_operand" "r")))))
9252 (set (match_operand:SI 0 "s_register_operand" "=r")
9253 (minus:SI (match_dup 1) (match_dup 2)))]
9255 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9256 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9257 && (GET_CODE (operands[2]) != REG
9258 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9259 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9260 [(set_attr "type" "load_byte")
9261 (set_attr "predicable" "yes")]
9264 (define_insn "*strsi_preinc"
9265 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9266 (match_operand:SI 2 "index_operand" "rJ")))
9267 (match_operand:SI 3 "s_register_operand" "r"))
9268 (set (match_operand:SI 0 "s_register_operand" "=r")
9269 (plus:SI (match_dup 1) (match_dup 2)))]
9271 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9272 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9273 && (GET_CODE (operands[2]) != REG
9274 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9275 "str%?\\t%3, [%0, %2]!"
9276 [(set_attr "type" "store1")
9277 (set_attr "predicable" "yes")]
9280 (define_insn "*strsi_predec"
9281 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9282 (match_operand:SI 2 "s_register_operand" "r")))
9283 (match_operand:SI 3 "s_register_operand" "r"))
9284 (set (match_operand:SI 0 "s_register_operand" "=r")
9285 (minus:SI (match_dup 1) (match_dup 2)))]
9287 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9288 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9289 && (GET_CODE (operands[2]) != REG
9290 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9291 "str%?\\t%3, [%0, -%2]!"
9292 [(set_attr "type" "store1")
9293 (set_attr "predicable" "yes")]
9296 (define_insn "*loadsi_preinc"
9297 [(set (match_operand:SI 3 "s_register_operand" "=r")
9298 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9299 (match_operand:SI 2 "index_operand" "rJ"))))
9300 (set (match_operand:SI 0 "s_register_operand" "=r")
9301 (plus:SI (match_dup 1) (match_dup 2)))]
9303 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9304 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9305 && (GET_CODE (operands[2]) != REG
9306 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9307 "ldr%?\\t%3, [%0, %2]!"
9308 [(set_attr "type" "load1")
9309 (set_attr "predicable" "yes")]
9312 (define_insn "*loadsi_predec"
9313 [(set (match_operand:SI 3 "s_register_operand" "=r")
9314 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9315 (match_operand:SI 2 "s_register_operand" "r"))))
9316 (set (match_operand:SI 0 "s_register_operand" "=r")
9317 (minus:SI (match_dup 1) (match_dup 2)))]
9319 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9320 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9321 && (GET_CODE (operands[2]) != REG
9322 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9323 "ldr%?\\t%3, [%0, -%2]!"
9324 [(set_attr "type" "load1")
9325 (set_attr "predicable" "yes")]
9328 (define_insn "*loadhi_preinc"
9329 [(set (match_operand:HI 3 "s_register_operand" "=r")
9330 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9331 (match_operand:SI 2 "index_operand" "rJ"))))
9332 (set (match_operand:SI 0 "s_register_operand" "=r")
9333 (plus:SI (match_dup 1) (match_dup 2)))]
9335 && !BYTES_BIG_ENDIAN
9336 && !TARGET_MMU_TRAPS
9338 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9339 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9340 && (GET_CODE (operands[2]) != REG
9341 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9342 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
9343 [(set_attr "type" "load_byte")
9344 (set_attr "predicable" "yes")]
9347 (define_insn "*loadhi_predec"
9348 [(set (match_operand:HI 3 "s_register_operand" "=r")
9349 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9350 (match_operand:SI 2 "s_register_operand" "r"))))
9351 (set (match_operand:SI 0 "s_register_operand" "=r")
9352 (minus:SI (match_dup 1) (match_dup 2)))]
9354 && !BYTES_BIG_ENDIAN
9355 && !TARGET_MMU_TRAPS
9357 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9358 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9359 && (GET_CODE (operands[2]) != REG
9360 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9361 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
9362 [(set_attr "type" "load_byte")
9363 (set_attr "predicable" "yes")]
9366 (define_insn "*strqi_shiftpreinc"
9367 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9368 [(match_operand:SI 3 "s_register_operand" "r")
9369 (match_operand:SI 4 "const_shift_operand" "n")])
9370 (match_operand:SI 1 "s_register_operand" "0")))
9371 (match_operand:QI 5 "s_register_operand" "r"))
9372 (set (match_operand:SI 0 "s_register_operand" "=r")
9373 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9376 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9377 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9378 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9379 "str%?b\\t%5, [%0, %3%S2]!"
9380 [(set_attr "type" "store1")
9381 (set_attr "predicable" "yes")]
9384 (define_insn "*strqi_shiftpredec"
9385 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9386 (match_operator:SI 2 "shift_operator"
9387 [(match_operand:SI 3 "s_register_operand" "r")
9388 (match_operand:SI 4 "const_shift_operand" "n")])))
9389 (match_operand:QI 5 "s_register_operand" "r"))
9390 (set (match_operand:SI 0 "s_register_operand" "=r")
9391 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9394 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9395 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9396 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9397 "str%?b\\t%5, [%0, -%3%S2]!"
9398 [(set_attr "type" "store1")
9399 (set_attr "predicable" "yes")]
9402 (define_insn "*loadqi_shiftpreinc"
9403 [(set (match_operand:QI 5 "s_register_operand" "=r")
9404 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9405 [(match_operand:SI 3 "s_register_operand" "r")
9406 (match_operand:SI 4 "const_shift_operand" "n")])
9407 (match_operand:SI 1 "s_register_operand" "0"))))
9408 (set (match_operand:SI 0 "s_register_operand" "=r")
9409 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9412 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9413 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9414 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9415 "ldr%?b\\t%5, [%0, %3%S2]!"
9416 [(set_attr "type" "load_byte")
9417 (set_attr "predicable" "yes")]
9420 (define_insn "*loadqi_shiftpredec"
9421 [(set (match_operand:QI 5 "s_register_operand" "=r")
9422 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9423 (match_operator:SI 2 "shift_operator"
9424 [(match_operand:SI 3 "s_register_operand" "r")
9425 (match_operand:SI 4 "const_shift_operand" "n")]))))
9426 (set (match_operand:SI 0 "s_register_operand" "=r")
9427 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9430 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9431 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9432 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9433 "ldr%?b\\t%5, [%0, -%3%S2]!"
9434 [(set_attr "type" "load_byte")
9435 (set_attr "predicable" "yes")]
9438 (define_insn "*strsi_shiftpreinc"
9439 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9440 [(match_operand:SI 3 "s_register_operand" "r")
9441 (match_operand:SI 4 "const_shift_operand" "n")])
9442 (match_operand:SI 1 "s_register_operand" "0")))
9443 (match_operand:SI 5 "s_register_operand" "r"))
9444 (set (match_operand:SI 0 "s_register_operand" "=r")
9445 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9448 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9449 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9450 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9451 "str%?\\t%5, [%0, %3%S2]!"
9452 [(set_attr "type" "store1")
9453 (set_attr "predicable" "yes")]
9456 (define_insn "*strsi_shiftpredec"
9457 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9458 (match_operator:SI 2 "shift_operator"
9459 [(match_operand:SI 3 "s_register_operand" "r")
9460 (match_operand:SI 4 "const_shift_operand" "n")])))
9461 (match_operand:SI 5 "s_register_operand" "r"))
9462 (set (match_operand:SI 0 "s_register_operand" "=r")
9463 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9466 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9467 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9468 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9469 "str%?\\t%5, [%0, -%3%S2]!"
9470 [(set_attr "type" "store1")
9471 (set_attr "predicable" "yes")]
9474 (define_insn "*loadsi_shiftpreinc"
9475 [(set (match_operand:SI 5 "s_register_operand" "=r")
9476 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9477 [(match_operand:SI 3 "s_register_operand" "r")
9478 (match_operand:SI 4 "const_shift_operand" "n")])
9479 (match_operand:SI 1 "s_register_operand" "0"))))
9480 (set (match_operand:SI 0 "s_register_operand" "=r")
9481 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9484 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9485 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9486 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9487 "ldr%?\\t%5, [%0, %3%S2]!"
9488 [(set_attr "type" "load1")
9489 (set_attr "predicable" "yes")]
9492 (define_insn "*loadsi_shiftpredec"
9493 [(set (match_operand:SI 5 "s_register_operand" "=r")
9494 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9495 (match_operator:SI 2 "shift_operator"
9496 [(match_operand:SI 3 "s_register_operand" "r")
9497 (match_operand:SI 4 "const_shift_operand" "n")]))))
9498 (set (match_operand:SI 0 "s_register_operand" "=r")
9499 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9502 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9503 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9504 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9505 "ldr%?\\t%5, [%0, -%3%S2]!"
9506 [(set_attr "type" "load1")
9507 (set_attr "predicable" "yes")])
9509 (define_insn "*loadhi_shiftpreinc"
9510 [(set (match_operand:HI 5 "s_register_operand" "=r")
9511 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
9512 [(match_operand:SI 3 "s_register_operand" "r")
9513 (match_operand:SI 4 "const_shift_operand" "n")])
9514 (match_operand:SI 1 "s_register_operand" "0"))))
9515 (set (match_operand:SI 0 "s_register_operand" "=r")
9516 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9519 && !BYTES_BIG_ENDIAN
9520 && !TARGET_MMU_TRAPS
9522 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9523 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9524 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9525 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
9526 [(set_attr "type" "load_byte")
9527 (set_attr "predicable" "yes")]
9530 (define_insn "*loadhi_shiftpredec"
9531 [(set (match_operand:HI 5 "s_register_operand" "=r")
9532 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9533 (match_operator:SI 2 "shift_operator"
9534 [(match_operand:SI 3 "s_register_operand" "r")
9535 (match_operand:SI 4 "const_shift_operand" "n")]))))
9536 (set (match_operand:SI 0 "s_register_operand" "=r")
9537 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9540 && !BYTES_BIG_ENDIAN
9541 && !TARGET_MMU_TRAPS
9543 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9544 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9545 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9546 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
9547 [(set_attr "type" "load_byte")
9548 (set_attr "predicable" "yes")]
9551 ; It can also support extended post-inc expressions, but combine doesn't
9553 ; It doesn't seem worth adding peepholes for anything but the most common
9554 ; cases since, unlike combine, the increment must immediately follow the load
9555 ; for this pattern to match.
9556 ; We must watch to see that the source/destination register isn't also the
9557 ; same as the base address register, and that if the index is a register,
9558 ; that it is not the same as the base address register. In such cases the
9559 ; instruction that we would generate would have UNPREDICTABLE behavior so
9563 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9564 (match_operand:QI 2 "s_register_operand" "r"))
9566 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9568 && (REGNO (operands[2]) != REGNO (operands[0]))
9569 && (GET_CODE (operands[1]) != REG
9570 || (REGNO (operands[1]) != REGNO (operands[0])))"
9571 "str%?b\\t%2, [%0], %1"
9575 [(set (match_operand:QI 0 "s_register_operand" "=r")
9576 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9578 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9580 && REGNO (operands[0]) != REGNO(operands[1])
9581 && (GET_CODE (operands[2]) != REG
9582 || REGNO(operands[0]) != REGNO (operands[2]))"
9583 "ldr%?b\\t%0, [%1], %2"
9587 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9588 (match_operand:SI 2 "s_register_operand" "r"))
9590 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9592 && (REGNO (operands[2]) != REGNO (operands[0]))
9593 && (GET_CODE (operands[1]) != REG
9594 || (REGNO (operands[1]) != REGNO (operands[0])))"
9595 "str%?\\t%2, [%0], %1"
9599 [(set (match_operand:HI 0 "s_register_operand" "=r")
9600 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
9602 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9604 && !BYTES_BIG_ENDIAN
9605 && !TARGET_MMU_TRAPS
9607 && REGNO (operands[0]) != REGNO(operands[1])
9608 && (GET_CODE (operands[2]) != REG
9609 || REGNO(operands[0]) != REGNO (operands[2]))"
9610 "ldr%?\\t%0, [%1], %2\\t%@ loadhi"
9614 [(set (match_operand:SI 0 "s_register_operand" "=r")
9615 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9617 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9619 && REGNO (operands[0]) != REGNO(operands[1])
9620 && (GET_CODE (operands[2]) != REG
9621 || REGNO(operands[0]) != REGNO (operands[2]))"
9622 "ldr%?\\t%0, [%1], %2"
9626 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9627 (match_operand:SI 1 "index_operand" "rJ")))
9628 (match_operand:QI 2 "s_register_operand" "r"))
9629 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9631 && (REGNO (operands[2]) != REGNO (operands[0]))
9632 && (GET_CODE (operands[1]) != REG
9633 || (REGNO (operands[1]) != REGNO (operands[0])))"
9634 "str%?b\\t%2, [%0, %1]!"
9638 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9639 [(match_operand:SI 0 "s_register_operand" "r")
9640 (match_operand:SI 1 "const_int_operand" "n")])
9641 (match_operand:SI 2 "s_register_operand" "+r")))
9642 (match_operand:QI 3 "s_register_operand" "r"))
9643 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9646 && (REGNO (operands[3]) != REGNO (operands[2]))
9647 && (REGNO (operands[0]) != REGNO (operands[2]))"
9648 "str%?b\\t%3, [%2, %0%S4]!"
9651 ; This pattern is never tried by combine, so do it as a peephole
9654 [(set (match_operand:SI 0 "s_register_operand" "")
9655 (match_operand:SI 1 "s_register_operand" ""))
9656 (set (reg:CC CC_REGNUM)
9657 (compare:CC (match_dup 1) (const_int 0)))]
9659 && (!(TARGET_HARD_FLOAT && TARGET_MAVERICK)
9660 || (!cirrus_fp_register (operands[0], SImode)
9661 && !cirrus_fp_register (operands[1], SImode)))
9663 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9664 (set (match_dup 0) (match_dup 1))])]
9668 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9669 ; reversed, check that the memory references aren't volatile.
9672 [(set (match_operand:SI 0 "s_register_operand" "=r")
9673 (match_operand:SI 4 "memory_operand" "m"))
9674 (set (match_operand:SI 1 "s_register_operand" "=r")
9675 (match_operand:SI 5 "memory_operand" "m"))
9676 (set (match_operand:SI 2 "s_register_operand" "=r")
9677 (match_operand:SI 6 "memory_operand" "m"))
9678 (set (match_operand:SI 3 "s_register_operand" "=r")
9679 (match_operand:SI 7 "memory_operand" "m"))]
9680 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9682 return emit_ldm_seq (operands, 4);
9687 [(set (match_operand:SI 0 "s_register_operand" "=r")
9688 (match_operand:SI 3 "memory_operand" "m"))
9689 (set (match_operand:SI 1 "s_register_operand" "=r")
9690 (match_operand:SI 4 "memory_operand" "m"))
9691 (set (match_operand:SI 2 "s_register_operand" "=r")
9692 (match_operand:SI 5 "memory_operand" "m"))]
9693 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9695 return emit_ldm_seq (operands, 3);
9700 [(set (match_operand:SI 0 "s_register_operand" "=r")
9701 (match_operand:SI 2 "memory_operand" "m"))
9702 (set (match_operand:SI 1 "s_register_operand" "=r")
9703 (match_operand:SI 3 "memory_operand" "m"))]
9704 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9706 return emit_ldm_seq (operands, 2);
9711 [(set (match_operand:SI 4 "memory_operand" "=m")
9712 (match_operand:SI 0 "s_register_operand" "r"))
9713 (set (match_operand:SI 5 "memory_operand" "=m")
9714 (match_operand:SI 1 "s_register_operand" "r"))
9715 (set (match_operand:SI 6 "memory_operand" "=m")
9716 (match_operand:SI 2 "s_register_operand" "r"))
9717 (set (match_operand:SI 7 "memory_operand" "=m")
9718 (match_operand:SI 3 "s_register_operand" "r"))]
9719 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9721 return emit_stm_seq (operands, 4);
9726 [(set (match_operand:SI 3 "memory_operand" "=m")
9727 (match_operand:SI 0 "s_register_operand" "r"))
9728 (set (match_operand:SI 4 "memory_operand" "=m")
9729 (match_operand:SI 1 "s_register_operand" "r"))
9730 (set (match_operand:SI 5 "memory_operand" "=m")
9731 (match_operand:SI 2 "s_register_operand" "r"))]
9732 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9734 return emit_stm_seq (operands, 3);
9739 [(set (match_operand:SI 2 "memory_operand" "=m")
9740 (match_operand:SI 0 "s_register_operand" "r"))
9741 (set (match_operand:SI 3 "memory_operand" "=m")
9742 (match_operand:SI 1 "s_register_operand" "r"))]
9743 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9745 return emit_stm_seq (operands, 2);
9750 [(set (match_operand:SI 0 "s_register_operand" "")
9751 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9753 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9754 [(match_operand:SI 3 "s_register_operand" "")
9755 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9756 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9758 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9759 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9764 ;; This split can be used because CC_Z mode implies that the following
9765 ;; branch will be an equality, or an unsigned inequality, so the sign
9766 ;; extension is not needed.
9769 [(set (reg:CC_Z CC_REGNUM)
9771 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9773 (match_operand 1 "const_int_operand" "")))
9774 (clobber (match_scratch:SI 2 ""))]
9776 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9777 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9778 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9779 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9781 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9785 (define_expand "prologue"
9786 [(clobber (const_int 0))]
9789 arm_expand_prologue ();
9791 thumb_expand_prologue ();
9796 (define_expand "epilogue"
9797 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9801 thumb_expand_epilogue ();
9802 else if (USE_RETURN_INSN (FALSE))
9804 emit_jump_insn (gen_return ());
9807 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9809 gen_rtx_RETURN (VOIDmode)),
9815 ;; Note - although unspec_volatile's USE all hard registers,
9816 ;; USEs are ignored after relaod has completed. Thus we need
9817 ;; to add an unspec of the link register to ensure that flow
9818 ;; does not think that it is unused by the sibcall branch that
9819 ;; will replace the standard function epilogue.
9820 (define_insn "sibcall_epilogue"
9821 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9822 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9825 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9826 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9827 return arm_output_epilogue (next_nonnote_insn (insn));
9829 ;; Length is absolute worst case
9830 [(set_attr "length" "44")
9831 (set_attr "type" "block")
9832 ;; We don't clobber the conditions, but the potential length of this
9833 ;; operation is sufficient to make conditionalizing the sequence
9834 ;; unlikely to be profitable.
9835 (set_attr "conds" "clob")]
9838 (define_insn "*epilogue_insns"
9839 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9843 return arm_output_epilogue (NULL);
9844 else /* TARGET_THUMB */
9845 return thumb_unexpanded_epilogue ();
9847 ; Length is absolute worst case
9848 [(set_attr "length" "44")
9849 (set_attr "type" "block")
9850 ;; We don't clobber the conditions, but the potential length of this
9851 ;; operation is sufficient to make conditionalizing the sequence
9852 ;; unlikely to be profitable.
9853 (set_attr "conds" "clob")]
9856 (define_expand "eh_epilogue"
9857 [(use (match_operand:SI 0 "register_operand" ""))
9858 (use (match_operand:SI 1 "register_operand" ""))
9859 (use (match_operand:SI 2 "register_operand" ""))]
9863 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9864 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9866 rtx ra = gen_rtx_REG (Pmode, 2);
9868 emit_move_insn (ra, operands[2]);
9871 /* This is a hack -- we may have crystalized the function type too
9873 cfun->machine->func_type = 0;
9877 ;; This split is only used during output to reduce the number of patterns
9878 ;; that need assembler instructions adding to them. We allowed the setting
9879 ;; of the conditions to be implicit during rtl generation so that
9880 ;; the conditional compare patterns would work. However this conflicts to
9881 ;; some extent with the conditional data operations, so we have to split them
9885 [(set (match_operand:SI 0 "s_register_operand" "")
9886 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9887 [(match_operand 2 "" "") (match_operand 3 "" "")])
9889 (match_operand 4 "" "")))
9890 (clobber (reg:CC CC_REGNUM))]
9891 "TARGET_ARM && reload_completed"
9892 [(set (match_dup 5) (match_dup 6))
9893 (cond_exec (match_dup 7)
9894 (set (match_dup 0) (match_dup 4)))]
9897 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9898 operands[2], operands[3]);
9899 enum rtx_code rc = GET_CODE (operands[1]);
9901 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9902 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9903 if (mode == CCFPmode || mode == CCFPEmode)
9904 rc = reverse_condition_maybe_unordered (rc);
9906 rc = reverse_condition (rc);
9908 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
9913 [(set (match_operand:SI 0 "s_register_operand" "")
9914 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9915 [(match_operand 2 "" "") (match_operand 3 "" "")])
9916 (match_operand 4 "" "")
9918 (clobber (reg:CC CC_REGNUM))]
9919 "TARGET_ARM && reload_completed"
9920 [(set (match_dup 5) (match_dup 6))
9921 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
9922 (set (match_dup 0) (match_dup 4)))]
9925 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9926 operands[2], operands[3]);
9928 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9929 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9934 [(set (match_operand:SI 0 "s_register_operand" "")
9935 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9936 [(match_operand 2 "" "") (match_operand 3 "" "")])
9937 (match_operand 4 "" "")
9938 (match_operand 5 "" "")))
9939 (clobber (reg:CC CC_REGNUM))]
9940 "TARGET_ARM && reload_completed"
9941 [(set (match_dup 6) (match_dup 7))
9942 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9943 (set (match_dup 0) (match_dup 4)))
9944 (cond_exec (match_dup 8)
9945 (set (match_dup 0) (match_dup 5)))]
9948 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9949 operands[2], operands[3]);
9950 enum rtx_code rc = GET_CODE (operands[1]);
9952 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9953 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9954 if (mode == CCFPmode || mode == CCFPEmode)
9955 rc = reverse_condition_maybe_unordered (rc);
9957 rc = reverse_condition (rc);
9959 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9964 [(set (match_operand:SI 0 "s_register_operand" "")
9965 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9966 [(match_operand:SI 2 "s_register_operand" "")
9967 (match_operand:SI 3 "arm_add_operand" "")])
9968 (match_operand:SI 4 "arm_rhs_operand" "")
9970 (match_operand:SI 5 "s_register_operand" ""))))
9971 (clobber (reg:CC CC_REGNUM))]
9972 "TARGET_ARM && reload_completed"
9973 [(set (match_dup 6) (match_dup 7))
9974 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9975 (set (match_dup 0) (match_dup 4)))
9976 (cond_exec (match_dup 8)
9977 (set (match_dup 0) (not:SI (match_dup 5))))]
9980 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9981 operands[2], operands[3]);
9982 enum rtx_code rc = GET_CODE (operands[1]);
9984 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9985 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9986 if (mode == CCFPmode || mode == CCFPEmode)
9987 rc = reverse_condition_maybe_unordered (rc);
9989 rc = reverse_condition (rc);
9991 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9995 (define_insn "*cond_move_not"
9996 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9997 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9998 [(match_operand 3 "cc_register" "") (const_int 0)])
9999 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10001 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10005 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10006 [(set_attr "conds" "use")
10007 (set_attr "length" "4,8")]
10010 ;; The next two patterns occur when an AND operation is followed by a
10011 ;; scc insn sequence
10013 (define_insn "*sign_extract_onebit"
10014 [(set (match_operand:SI 0 "s_register_operand" "=r")
10015 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10017 (match_operand:SI 2 "const_int_operand" "n")))
10018 (clobber (reg:CC CC_REGNUM))]
10021 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10022 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10023 return \"mvnne\\t%0, #0\";
10025 [(set_attr "conds" "clob")
10026 (set_attr "length" "8")]
10029 (define_insn "*not_signextract_onebit"
10030 [(set (match_operand:SI 0 "s_register_operand" "=r")
10032 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10034 (match_operand:SI 2 "const_int_operand" "n"))))
10035 (clobber (reg:CC CC_REGNUM))]
10038 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10039 output_asm_insn (\"tst\\t%1, %2\", operands);
10040 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10041 return \"movne\\t%0, #0\";
10043 [(set_attr "conds" "clob")
10044 (set_attr "length" "12")]
10047 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10048 ;; expressions. For simplicity, the first register is also in the unspec
10050 (define_insn "*push_multi"
10051 [(match_parallel 2 "multi_register_push"
10052 [(set (match_operand:BLK 0 "memory_operand" "=m")
10053 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10054 UNSPEC_PUSH_MULT))])]
10058 int num_saves = XVECLEN (operands[2], 0);
10060 /* For the StrongARM at least it is faster to
10061 use STR to store only a single register. */
10062 if (num_saves == 1)
10063 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10069 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10071 for (i = 1; i < num_saves; i++)
10073 strcat (pattern, \", %|\");
10075 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10078 strcat (pattern, \"}\");
10079 output_asm_insn (pattern, operands);
10084 [(set_attr "type" "store4")]
10087 (define_insn "stack_tie"
10088 [(set (mem:BLK (scratch))
10089 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10090 (match_operand:SI 1 "s_register_operand" "r")]
10094 [(set_attr "length" "0")]
10097 ;; Similarly for the floating point registers
10098 (define_insn "*push_fp_multi"
10099 [(match_parallel 2 "multi_register_push"
10100 [(set (match_operand:BLK 0 "memory_operand" "=m")
10101 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10102 UNSPEC_PUSH_MULT))])]
10103 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10108 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10109 output_asm_insn (pattern, operands);
10112 [(set_attr "type" "f_store")]
10115 ;; Special patterns for dealing with the constant pool
10117 (define_insn "align_4"
10118 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10121 assemble_align (32);
10126 (define_insn "align_8"
10127 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10130 assemble_align (64);
10135 (define_insn "consttable_end"
10136 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10139 making_const_table = FALSE;
10144 (define_insn "consttable_1"
10145 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10148 making_const_table = TRUE;
10149 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10150 assemble_zeros (3);
10153 [(set_attr "length" "4")]
10156 (define_insn "consttable_2"
10157 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10160 making_const_table = TRUE;
10161 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10162 assemble_zeros (2);
10165 [(set_attr "length" "4")]
10168 (define_insn "consttable_4"
10169 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10173 making_const_table = TRUE;
10174 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10179 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10180 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10184 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10189 [(set_attr "length" "4")]
10192 (define_insn "consttable_8"
10193 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10197 making_const_table = TRUE;
10198 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10203 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10204 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10208 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10213 [(set_attr "length" "8")]
10216 ;; Miscellaneous Thumb patterns
10218 (define_expand "tablejump"
10219 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10220 (use (label_ref (match_operand 1 "" "")))])]
10225 /* Hopefully, CSE will eliminate this copy. */
10226 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10227 rtx reg2 = gen_reg_rtx (SImode);
10229 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10230 operands[0] = reg2;
10235 (define_insn "*thumb_tablejump"
10236 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10237 (use (label_ref (match_operand 1 "" "")))]
10240 [(set_attr "length" "2")]
10243 ;; V5 Instructions,
10245 (define_insn "clzsi2"
10246 [(set (match_operand:SI 0 "s_register_operand" "=r")
10247 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10248 "TARGET_ARM && arm_arch5"
10250 [(set_attr "predicable" "yes")])
10252 (define_expand "ffssi2"
10253 [(set (match_operand:SI 0 "s_register_operand" "")
10254 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10255 "TARGET_ARM && arm_arch5"
10260 t1 = gen_reg_rtx (SImode);
10261 t2 = gen_reg_rtx (SImode);
10262 t3 = gen_reg_rtx (SImode);
10264 emit_insn (gen_negsi2 (t1, operands[1]));
10265 emit_insn (gen_andsi3 (t2, operands[1], t1));
10266 emit_insn (gen_clzsi2 (t3, t2));
10267 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10272 (define_expand "ctzsi2"
10273 [(set (match_operand:SI 0 "s_register_operand" "")
10274 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10275 "TARGET_ARM && arm_arch5"
10280 t1 = gen_reg_rtx (SImode);
10281 t2 = gen_reg_rtx (SImode);
10282 t3 = gen_reg_rtx (SImode);
10284 emit_insn (gen_negsi2 (t1, operands[1]));
10285 emit_insn (gen_andsi3 (t2, operands[1], t1));
10286 emit_insn (gen_clzsi2 (t3, t2));
10287 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10292 ;; V5E instructions.
10294 (define_insn "prefetch"
10295 [(prefetch (match_operand:SI 0 "address_operand" "p")
10296 (match_operand:SI 1 "" "")
10297 (match_operand:SI 2 "" ""))]
10298 "TARGET_ARM && arm_arch5e"
10301 ;; General predication pattern
10304 [(match_operator 0 "arm_comparison_operator"
10305 [(match_operand 1 "cc_register" "")
10311 (define_insn "prologue_use"
10312 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10314 "%@ %0 needed for prologue"
10317 ;; Load the FPA co-processor patterns
10319 ;; Load the Maverick co-processor patterns
10320 (include "cirrus.md")
10321 ;; Load the Intel Wireless Multimedia Extension patterns
10322 (include "iwmmxt.md")
10323 ;; Load the VFP co-processor patterns